Home Home > GIT Browse > SLE12-SP3
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-01-10 16:23:55 +0100
committerTakashi Iwai <tiwai@suse.de>2019-01-10 16:23:55 +0100
commit4595c2b981df354dcc89cc23f668e38b5064e679 (patch)
treea3e91e55762e2a523fe9e7b9d74beabd72ed615c
parent61ee315e30da381c78b293190e7b1b06d11e5008 (diff)
parent1dfe28fcc5c15002e739bdfce8a4435cb4ab7944 (diff)
Merge branch 'users/jslaby/SLE12-SP3/for-next' into SLE12-SP3
Pull stable 4.4.168 update from Jiri Slaby
-rw-r--r--patches.arch/0001-kvm-x86-remove-magic-number-with-enum-cpuid_leafs27
-rw-r--r--patches.arch/0002-kvm-add-struct-kvm_vcpu-pointer-parameter-to-get_enable_apicv18
-rw-r--r--patches.arch/0002-kvm-x86-misc-lapic-changes-to-expose-helper-functions68
-rw-r--r--patches.arch/0003-kvm-x86-introducing-kvm_x86_ops-vm-init-destroy-hooks12
-rw-r--r--patches.arch/0004-x86-kvm-Move-l1tf-setup-function.patch12
-rw-r--r--patches.arch/0005-kvm-x86-svm-call-x86_spec_ctrl_set_guest-host-with-interrupts-disabled13
-rw-r--r--patches.arch/0007-kvm-pkeys-expose-cpuid-cr4-to-guest44
-rw-r--r--patches.arch/0007-x86-kvm-Allow-runtime-control-of-L1D-flush.patch8
-rw-r--r--patches.arch/0012-svm-manage-vcpu-load-unload-when-enable-avic22
-rw-r--r--patches.arch/0018-mm-gup-introduce-get_user_pages_remote125
-rw-r--r--patches.arch/0019-mm-core-do-not-enforce-pkey-permissions-on-remote-mm-access59
-rw-r--r--patches.arch/02-x86-KVM-VMX-Add-module-argument-for-L1TF-mitigation.patch48
-rw-r--r--patches.arch/05-x86-KVM-VMX-Add-L1D-flush-logic.patch25
-rw-r--r--patches.arch/47-kvm-svm-implement-virt_spec_ctrl-support-for-ssbd.patch192
-rw-r--r--patches.arch/arm64-bsc1031492-0023-kvm-make-KVM_CAP_COALESCED_MMIO-architecture-agnosti.patch35
-rw-r--r--patches.arch/kvm-nVMX-fix-nested-tsc-scaling.patch18
-rw-r--r--patches.arch/kvm-svm-add-support-for-rdtscp.patch23
-rw-r--r--patches.arch/kvm-vmx-enable-guest-access-to-lmce-related-msrs.patch41
-rw-r--r--patches.arch/kvm-vmx-optimize-apic-id-read-with-apicv.patch28
-rw-r--r--patches.arch/kvm-x86-add-avx512_4vnniw-and-avx512_4fmaps-support.patch51
-rw-r--r--patches.arch/kvm-x86-per-vcpu-apicv-deactivation-support76
-rw-r--r--patches.drivers/0012-svm-implements-update_pi_irte-hook-to-setup-posted-interrupt18
-rw-r--r--patches.drivers/drm-i915-userptr-Hold-mmref-whilst-calling-get-user4
-rw-r--r--patches.drivers/rtnetlink-fdb-dump-optimize-by-saving-last-interface.patch17
-rw-r--r--patches.drivers/staging-rdma-0002-Fix-changed-get_user_pages-arguments.patch15
-rw-r--r--patches.drivers/staging-rdma-hfi1-convert-to-use-get_user_pages_fast.patch8
-rw-r--r--patches.kabi/kabi-KVM-x86-kABI-workaround-for-PKRU-fixes.patch25
-rw-r--r--patches.kabi/kabi-protect-get_vaddr_frames.patch101
-rw-r--r--patches.kabi/kabi-protect-xen-ops-include-in-xlate_mmu.patch29
-rw-r--r--patches.kabi/posix-timers-overrun-change-kABI-fix.patch94
-rw-r--r--patches.kabi/x86-cpufeature-preserve-numbers.patch42
-rw-r--r--patches.kernel.org/4.4.168-001-ipv6-Check-available-headroom-in-ip6_xmit-eve.patch144
-rw-r--r--patches.kernel.org/4.4.168-002-net-8139cp-fix-a-BUG-triggered-by-changing-mt.patch150
-rw-r--r--patches.kernel.org/4.4.168-003-net-phy-don-t-allow-__set_phy_supported-to-ad.patch63
-rw-r--r--patches.kernel.org/4.4.168-004-net-Prevent-invalid-access-to-skb-prev-in-__q.patch104
-rw-r--r--patches.kernel.org/4.4.168-005-rtnetlink-ndo_dflt_fdb_dump-only-work-for-ARP.patch159
-rw-r--r--patches.kernel.org/4.4.168-006-tcp-fix-NULL-ref-in-tail-loss-probe.patch58
-rw-r--r--patches.kernel.org/4.4.168-007-tun-forbid-iface-creation-with-rtnl-ops.patch52
-rw-r--r--patches.kernel.org/4.4.168-008-neighbour-Avoid-writing-before-skb-head-in-ne.patch94
-rw-r--r--patches.kernel.org/4.4.168-009-ARM-OMAP2-prm44xx-Fix-section-annotation-on-o.patch48
-rw-r--r--patches.kernel.org/4.4.168-010-ARM-OMAP1-ams-delta-Fix-possible-use-of-unini.patch44
-rw-r--r--patches.kernel.org/4.4.168-011-sysv-return-err-instead-of-0-in-__sysv_write_.patch42
-rw-r--r--patches.kernel.org/4.4.168-012-s390-cpum_cf-Reject-request-for-sampling-in-e.patch117
-rw-r--r--patches.kernel.org/4.4.168-013-hwmon-ina2xx-Fix-current-value-calculation.patch42
-rw-r--r--patches.kernel.org/4.4.168-014-ASoC-dapm-Recalculate-audio-map-forcely-when-.patch61
-rw-r--r--patches.kernel.org/4.4.168-015-hwmon-w83795-temp4_type-has-writable-permissi.patch38
-rw-r--r--patches.kernel.org/4.4.168-016-Btrfs-send-fix-infinite-loop-due-to-directory.patch204
-rw-r--r--patches.kernel.org/4.4.168-017-ASoC-omap-mcpdm-Add-pm_qos-handling-to-avoid-.patch130
-rw-r--r--patches.kernel.org/4.4.168-018-ASoC-omap-dmic-Add-pm_qos-handling-to-avoid-o.patch67
-rw-r--r--patches.kernel.org/4.4.168-019-exportfs-do-not-read-dentry-after-free.patch43
-rw-r--r--patches.kernel.org/4.4.168-020-bpf-fix-check-of-allowed-specifiers-in-bpf_tr.patch47
-rw-r--r--patches.kernel.org/4.4.168-021-USB-omap_udc-use-devm_request_irq.patch105
-rw-r--r--patches.kernel.org/4.4.168-022-USB-omap_udc-fix-crashes-on-probe-error-and-m.patch117
-rw-r--r--patches.kernel.org/4.4.168-023-USB-omap_udc-fix-omap_udc_start-on-15xx-machi.patch44
-rw-r--r--patches.kernel.org/4.4.168-024-USB-omap_udc-fix-USB-gadget-functionality-on-.patch36
-rw-r--r--patches.kernel.org/4.4.168-025-KVM-x86-fix-empty-body-warnings.patch46
-rw-r--r--patches.kernel.org/4.4.168-026-net-thunderx-fix-NULL-pointer-dereference-in-.patch85
-rw-r--r--patches.kernel.org/4.4.168-027-ixgbe-recognize-1000BaseLX-SFP-modules-as-1Gb.patch46
-rw-r--r--patches.kernel.org/4.4.168-028-net-hisilicon-remove-unexpected-free_netdev.patch40
-rw-r--r--patches.kernel.org/4.4.168-029-drm-ast-fixed-reading-monitor-EDID-not-stable.patch97
-rw-r--r--patches.kernel.org/4.4.168-030-xen-xlate_mmu-add-missing-header-to-fix-W-1-w.patch40
-rw-r--r--patches.kernel.org/4.4.168-031-fscache-fix-race-between-enablement-and-dropp.patch (renamed from patches.fixes/fscache-fix-race-between-enablement-and-dropping-of-.patch)21
-rw-r--r--patches.kernel.org/4.4.168-032-fscache-cachefiles-remove-redundant-variable-.patch42
-rw-r--r--patches.kernel.org/4.4.168-033-ocfs2-fix-deadlock-caused-by-ocfs2_defrag_ext.patch150
-rw-r--r--patches.kernel.org/4.4.168-034-hfs-do-not-free-node-before-using.patch52
-rw-r--r--patches.kernel.org/4.4.168-035-hfsplus-do-not-free-node-before-using.patch52
-rw-r--r--patches.kernel.org/4.4.168-036-debugobjects-avoid-recursive-calls-with-kmeml.patch61
-rw-r--r--patches.kernel.org/4.4.168-037-ocfs2-fix-potential-use-after-free.patch50
-rw-r--r--patches.kernel.org/4.4.168-038-pstore-Convert-console-write-to-use-write_buf.patch45
-rw-r--r--patches.kernel.org/4.4.168-039-ALSA-pcm-remove-SNDRV_PCM_IOCTL1_INFO-interna.patch81
-rw-r--r--patches.kernel.org/4.4.168-040-KVM-nVMX-fix-msr-bitmaps-to-prevent-L2-from-a.patch (renamed from patches.fixes/kvm-nvmx-fix-msr-bitmaps-to-prevent-l2-from-accessing-l0-x2apic)53
-rw-r--r--patches.kernel.org/4.4.168-041-KVM-nVMX-mark-vmcs12-pages-dirty-on-L2-exit.patch122
-rw-r--r--patches.kernel.org/4.4.168-042-KVM-nVMX-Eliminate-vmcs02-pool.patch302
-rw-r--r--patches.kernel.org/4.4.168-043-KVM-VMX-introduce-alloc_loaded_vmcs.patch108
-rw-r--r--patches.kernel.org/4.4.168-044-KVM-VMX-make-MSR-bitmaps-per-VCPU.patch518
-rw-r--r--patches.kernel.org/4.4.168-045-KVM-x86-Add-IBPB-support.patch358
-rw-r--r--patches.kernel.org/4.4.168-046-KVM-VMX-Emulate-MSR_IA32_ARCH_CAPABILITIES.patch163
-rw-r--r--patches.kernel.org/4.4.168-047-KVM-VMX-Allow-direct-access-to-MSR_IA32_SPEC_.patch310
-rw-r--r--patches.kernel.org/4.4.168-048-KVM-SVM-Allow-direct-access-to-MSR_IA32_SPEC_.patch197
-rw-r--r--patches.kernel.org/4.4.168-049-KVM-x86-Remove-indirect-MSR-op-calls-from-SPE.patch111
-rw-r--r--patches.kernel.org/4.4.168-050-x86-reorganize-SMAP-handling-in-user-space-ac.patch (renamed from patches.suse/x86-reorganize-SMAP-handling-in-user-space-accesses.patch)53
-rw-r--r--patches.kernel.org/4.4.168-051-x86-fix-SMAP-in-32-bit-environments.patch (renamed from patches.suse/0001-x86-fix-SMAP-in-32-bit-environments.patch)17
-rw-r--r--patches.kernel.org/4.4.168-052-x86-Introduce-__uaccess_begin_nospec-and-uacc.patch (renamed from patches.suse/0005-x86-Introduce-__uaccess_begin_nospec-and-uaccess_try.patch)21
-rw-r--r--patches.kernel.org/4.4.168-053-x86-usercopy-Replace-open-coded-stac-clac-wit.patch (renamed from patches.suse/0006-x86-usercopy-Replace-open-coded-stac-clac-with-__uac.patch)31
-rw-r--r--patches.kernel.org/4.4.168-054-x86-uaccess-Use-__uaccess_begin_nospec-and-ua.patch (renamed from patches.suse/0007-x86-uaccess-Use-__uaccess_begin_nospec-and-uaccess_t.patch)102
-rw-r--r--patches.kernel.org/4.4.168-055-x86-bugs-KVM-Support-the-combination-of-guest.patch89
-rw-r--r--patches.kernel.org/4.4.168-056-x86-KVM-VMX-Expose-SPEC_CTRL-Bit-2-to-the-gue.patch126
-rw-r--r--patches.kernel.org/4.4.168-057-KVM-SVM-Move-spec-control-call-after-restore-.patch75
-rw-r--r--patches.kernel.org/4.4.168-058-x86-bugs-KVM-Extend-speculation-control-for-V.patch (renamed from patches.arch/39-x86-bugs-kvm-extend-speculation-control-for-virt_spec_ctrl.patch)75
-rw-r--r--patches.kernel.org/4.4.168-059-x86-speculation-Use-synthetic-bits-for-IBRS-I.patch92
-rw-r--r--patches.kernel.org/4.4.168-060-KVM-SVM-Implement-VIRT_SPEC_CTRL-support-for-.patch246
-rw-r--r--patches.kernel.org/4.4.168-061-bpf-support-8-byte-metafield-access.patch57
-rw-r--r--patches.kernel.org/4.4.168-062-bpf-verifier-Add-spi-variable-to-check_stack_.patch53
-rw-r--r--patches.kernel.org/4.4.168-063-bpf-verifier-Pass-instruction-index-to-check_.patch97
-rw-r--r--patches.kernel.org/4.4.168-064-bpf-Prevent-memory-disambiguation-attack.patch (renamed from patches.suse/bpf-prevent-memory-disambiguation-attack.patch)127
-rw-r--r--patches.kernel.org/4.4.168-065-wil6210-missing-length-check-in-wmi_set_ie.patch (renamed from patches.drivers/wil6210-missing-length-check-in-wmi_set_ie)21
-rw-r--r--patches.kernel.org/4.4.168-066-posix-timers-Sanitize-overrun-handling.patch (renamed from patches.fixes/posix-timers-Sanitize-overrun-handling.patch)82
-rw-r--r--patches.kernel.org/4.4.168-067-mm-hugetlb.c-don-t-call-region_abort-if-regio.patch (renamed from patches.fixes/mm-hugetlb.c-don-t-call-region_abort-if-region_chg-f.patch)18
-rw-r--r--patches.kernel.org/4.4.168-068-hugetlbfs-fix-offset-overflow-in-hugetlbfs-mm.patch (renamed from patches.fixes/hugetlbfs-fix-offset-overflow-in-hugetlbfs-mmap.patch)28
-rw-r--r--patches.kernel.org/4.4.168-069-hugetlbfs-check-for-pgoff-value-overflow.patch (renamed from patches.fixes/hugetlbfs-check-for-pgoff-value-overflow.patch)42
-rw-r--r--patches.kernel.org/4.4.168-070-hugetlbfs-fix-bug-in-pgoff-overflow-checking.patch62
-rw-r--r--patches.kernel.org/4.4.168-071-swiotlb-clean-up-reporting.patch94
-rw-r--r--patches.kernel.org/4.4.168-072-sr-pass-down-correctly-sized-SCSI-sense-buffe.patch90
-rw-r--r--patches.kernel.org/4.4.168-073-mm-remove-write-force-parameters-from-__get_u.patch (renamed from patches.suse/0005-mm-remove-write-force-parameters-from-_get_user_pages_locked)68
-rw-r--r--patches.kernel.org/4.4.168-074-mm-remove-write-force-parameters-from-__get_u.patch (renamed from patches.suse/0006-mm-remove-write-force-parameters-from-_get_user_pages_unlocked)117
-rw-r--r--patches.kernel.org/4.4.168-075-mm-nommu.c-Switch-__get_user_pages_unlocked-t.patch37
-rw-r--r--patches.kernel.org/4.4.168-076-mm-replace-get_user_pages_unlocked-write-forc.patch318
-rw-r--r--patches.kernel.org/4.4.168-077-mm-replace-get_user_pages_locked-write-force-.patch121
-rw-r--r--patches.kernel.org/4.4.168-078-mm-replace-get_vaddr_frames-write-force-param.patch138
-rw-r--r--patches.kernel.org/4.4.168-079-mm-replace-get_user_pages-write-force-paramet.patch596
-rw-r--r--patches.kernel.org/4.4.168-080-mm-replace-__access_remote_vm-write-parameter.patch131
-rw-r--r--patches.kernel.org/4.4.168-081-mm-replace-access_remote_vm-write-parameter-w.patch174
-rw-r--r--patches.kernel.org/4.4.168-082-proc-don-t-use-FOLL_FORCE-for-reading-cmdline.patch106
-rw-r--r--patches.kernel.org/4.4.168-083-proc-do-not-access-cmdline-nor-environ-from-f.patch124
-rw-r--r--patches.kernel.org/4.4.168-084-media-dvb-frontends-fix-i2c-access-helpers-fo.patch218
-rw-r--r--patches.kernel.org/4.4.168-085-matroxfb-fix-size-of-memcpy.patch37
-rw-r--r--patches.kernel.org/4.4.168-086-staging-speakup-Replace-strncpy-with-memcpy.patch61
-rw-r--r--patches.kernel.org/4.4.168-087-rocker-fix-rocker_tlv_put_-functions-for-KASA.patch93
-rw-r--r--patches.kernel.org/4.4.168-088-selftests-Move-networking-timestamping-from-D.patch2578
-rw-r--r--patches.kernel.org/4.4.168-089-Linux-4.4.168.patch27
-rw-r--r--patches.suse/0001-KVM-x86-Sync-back-MSR_IA32_SPEC_CTRL-to-VCPU-data-st.patch54
-rw-r--r--patches.suse/0002-mm-gup-overload-get_user_pages-functions105
-rw-r--r--patches.suse/0003-mm-gup-switch-all-callers-of-get_user_pages-to-not-pass-tsk-mm218
-rw-r--r--patches.suse/0004-mm-gup-remove-the-macro-overload-api-migration-helpers-from-the-get_user-apis83
-rw-r--r--patches.suse/0007-mm-replace-get_user_pages_unlocked-write-force-parameters-with-gup_flags238
-rw-r--r--patches.suse/0008-mm-replace-get_user_pages_locked-write-force-parameters-with-gup_flags104
-rw-r--r--patches.suse/0009-mm-replace-get_user_pages-write-force-parameters-with-gup_flags373
-rw-r--r--patches.suse/0010-mm-replace-get_user_pages_remote-write-force-parameters-with-gup_flags92
-rw-r--r--patches.suse/0011-mm-unexport-_get_user_pages18
-rw-r--r--patches.suse/0013-mm-add-locked-parameter-to-get_user_pages_remote42
-rw-r--r--patches.suse/05-x86-bugs-kvm-support-the-combination-of-guest-and-host-ibrs.patch87
-rw-r--r--patches.suse/12-x86-kvm-vmx-expose-spec_ctrl-bit2-to-the-guest.patch44
-rw-r--r--patches.suse/14-x86-kvm-add-msr_ia32_spec_ctrl-and-msr_ia32_pred_cmd-to-kvm.patch119
-rw-r--r--patches.suse/15-x86-kvm-flush-ibp-when-switching-vms.patch27
-rw-r--r--patches.suse/16-x86-kvm-toggle-ibrs-on-vm-entry-and-exit.patch33
-rw-r--r--patches.suse/24-kvm-svm-do-not-intercept-new-speculative-control-msrs.patch35
-rw-r--r--patches.suse/25-x86-svm-set-ibrs-value-on-vm-entry-and-exit.patch71
-rw-r--r--patches.suse/26-x86-svm-set-ibpb-when-running-a-different-vcpu.patch60
-rw-r--r--patches.suse/27-kvm-x86-add-speculative-control-cpuid-support-for-guests.patch54
-rw-r--r--patches.suse/29-kvm-svm-move-spec-control-call-after-restore-of-gs.patch41
-rw-r--r--series.conf123
141 files changed, 12331 insertions, 2789 deletions
diff --git a/patches.arch/0001-kvm-x86-remove-magic-number-with-enum-cpuid_leafs b/patches.arch/0001-kvm-x86-remove-magic-number-with-enum-cpuid_leafs
index 57eadd1faf..e48f7f3be3 100644
--- a/patches.arch/0001-kvm-x86-remove-magic-number-with-enum-cpuid_leafs
+++ b/patches.arch/0001-kvm-x86-remove-magic-number-with-enum-cpuid_leafs
@@ -11,12 +11,12 @@ Signed-off-by: Huaitong Han <huaitong.han@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- arch/x86/kvm/cpuid.c | 40 ++++++++++++++++++++--------------------
+ arch/x86/kvm/cpuid.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
-@@ -299,7 +299,7 @@ static inline int __do_cpuid_ent(struct
+@@ -306,7 +306,7 @@ static inline int __do_cpuid_ent(struct
unsigned f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
/* cpuid 1.edx */
@@ -25,7 +25,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
F(FPU) | F(VME) | F(DE) | F(PSE) |
F(TSC) | F(MSR) | F(PAE) | F(MCE) |
F(CX8) | F(APIC) | 0 /* Reserved */ | F(SEP) |
-@@ -309,7 +309,7 @@ static inline int __do_cpuid_ent(struct
+@@ -316,7 +316,7 @@ static inline int __do_cpuid_ent(struct
F(FXSR) | F(XMM) | F(XMM2) | F(SELFSNOOP) |
0 /* HTT, TM, Reserved, PBE */;
/* cpuid 0x80000001.edx */
@@ -34,7 +34,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
F(FPU) | F(VME) | F(DE) | F(PSE) |
F(TSC) | F(MSR) | F(PAE) | F(MCE) |
F(CX8) | F(APIC) | 0 /* Reserved */ | F(SYSCALL) |
-@@ -319,7 +319,7 @@ static inline int __do_cpuid_ent(struct
+@@ -326,7 +326,7 @@ static inline int __do_cpuid_ent(struct
F(FXSR) | F(FXSR_OPT) | f_gbpages | f_rdtscp |
0 /* Reserved */ | f_lm | F(3DNOWEXT) | F(3DNOW);
/* cpuid 1.ecx */
@@ -43,7 +43,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
/* NOTE: MONITOR (and MWAIT) are emulated as NOP,
* but *not* advertised to guests via CPUID ! */
F(XMM3) | F(PCLMULQDQ) | 0 /* DTES64, MONITOR */ |
-@@ -331,27 +331,27 @@ static inline int __do_cpuid_ent(struct
+@@ -338,7 +338,7 @@ static inline int __do_cpuid_ent(struct
0 /* Reserved*/ | F(AES) | F(XSAVE) | 0 /* OSXSAVE */ | F(AVX) |
F(F16C) | F(RDRAND);
/* cpuid 0x80000001.ecx */
@@ -52,7 +52,8 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
F(LAHF_LM) | F(CMP_LEGACY) | 0 /*SVM*/ | 0 /* ExtApicSpace */ |
F(CR8_LEGACY) | F(ABM) | F(SSE4A) | F(MISALIGNSSE) |
F(3DNOWPREFETCH) | F(OSVW) | 0 /* IBS */ | F(XOP) |
- 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM);
+@@ -349,20 +349,20 @@ static inline int __do_cpuid_ent(struct
+ F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD);
/* cpuid 0xC0000001.edx */
- const u32 kvm_supported_word5_x86_features =
@@ -74,8 +75,8 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ const u32 kvm_cpuid_D_1_eax_x86_features =
F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves;
- /* all calls to cpuid_count() should be made on the same cpu */
-@@ -370,10 +370,10 @@ static inline int __do_cpuid_ent(struct
+ /* cpuid 7.0.edx*/
+@@ -385,10 +385,10 @@ static inline int __do_cpuid_ent(struct
entry->eax = min(entry->eax, (u32)0xd);
break;
case 1:
@@ -90,7 +91,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
/* we support x2apic emulation even if host does not support
* it since we emulate x2apic in software */
entry->ecx |= F(X2APIC);
-@@ -427,8 +427,8 @@ static inline int __do_cpuid_ent(struct
+@@ -442,8 +442,8 @@ static inline int __do_cpuid_ent(struct
entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
/* Mask ebx against host capability word 9 */
if (index == 0) {
@@ -100,8 +101,8 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ cpuid_mask(&entry->ebx, CPUID_7_0_EBX);
// TSC_ADJUST is emulated
entry->ebx |= F(TSC_ADJUST);
- } else
-@@ -508,7 +508,7 @@ static inline int __do_cpuid_ent(struct
+ entry->edx &= kvm_cpuid_7_0_edx_x86_features;
+@@ -526,7 +526,7 @@ static inline int __do_cpuid_ent(struct
do_cpuid_1_ent(&entry[i], function, idx);
if (idx == 1) {
@@ -110,7 +111,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
cpuid_mask(&entry[i].eax, 10);
entry[i].ebx = 0;
if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
-@@ -559,10 +559,10 @@ static inline int __do_cpuid_ent(struct
+@@ -577,10 +577,10 @@ static inline int __do_cpuid_ent(struct
entry->eax = min(entry->eax, 0x8000001a);
break;
case 0x80000001:
@@ -125,7 +126,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
break;
case 0x80000007: /* Advanced power management */
/* invariant TSC is CPUID.80000007H:EDX[8] */
-@@ -595,8 +595,8 @@ static inline int __do_cpuid_ent(struct
+@@ -627,8 +627,8 @@ static inline int __do_cpuid_ent(struct
entry->eax = min(entry->eax, 0xC0000004);
break;
case 0xC0000001:
diff --git a/patches.arch/0002-kvm-add-struct-kvm_vcpu-pointer-parameter-to-get_enable_apicv b/patches.arch/0002-kvm-add-struct-kvm_vcpu-pointer-parameter-to-get_enable_apicv
index 3d7886d172..b1eaf04df4 100644
--- a/patches.arch/0002-kvm-add-struct-kvm_vcpu-pointer-parameter-to-get_enable_apicv
+++ b/patches.arch/0002-kvm-add-struct-kvm_vcpu-pointer-parameter-to-get_enable_apicv
@@ -15,15 +15,15 @@ Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- arch/x86/include/asm/kvm_host.h | 2 +-
- arch/x86/kvm/svm.c | 2 +-
- arch/x86/kvm/vmx.c | 2 +-
- arch/x86/kvm/x86.c | 2 +-
+ arch/x86/include/asm/kvm_host.h | 2 +-
+ arch/x86/kvm/svm.c | 2 +-
+ arch/x86/kvm/vmx.c | 2 +-
+ arch/x86/kvm/x86.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
-@@ -882,7 +882,7 @@ struct kvm_x86_ops {
+@@ -877,7 +877,7 @@ struct kvm_x86_ops {
void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
void (*enable_irq_window)(struct kvm_vcpu *vcpu);
void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
@@ -34,7 +34,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
void (*hwapic_isr_update)(struct kvm *kvm, int isr);
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
-@@ -4344,7 +4344,7 @@ static void svm_set_virtual_x2apic_mode(
+@@ -4427,7 +4427,7 @@ static void svm_set_virtual_x2apic_mode(
return;
}
@@ -45,8 +45,8 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -4552,7 +4552,7 @@ static void vmx_disable_intercept_msr_wr
- msr, MSR_TYPE_W);
+@@ -4684,7 +4684,7 @@ static void vmx_update_msr_bitmap(struct
+ vmx->msr_bitmap_mode = mode;
}
-static bool vmx_get_enable_apicv(void)
@@ -56,7 +56,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -7685,7 +7685,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
+@@ -7689,7 +7689,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
BUG_ON(vcpu->kvm == NULL);
kvm = vcpu->kvm;
diff --git a/patches.arch/0002-kvm-x86-misc-lapic-changes-to-expose-helper-functions b/patches.arch/0002-kvm-x86-misc-lapic-changes-to-expose-helper-functions
index cdb43fd621..485185742d 100644
--- a/patches.arch/0002-kvm-x86-misc-lapic-changes-to-expose-helper-functions
+++ b/patches.arch/0002-kvm-x86-misc-lapic-changes-to-expose-helper-functions
@@ -21,9 +21,9 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
-@@ -58,9 +58,8 @@
+@@ -59,9 +59,8 @@
/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
- #define apic_debug(fmt, arg...)
+ #define apic_debug(fmt, arg...) do {} while (0)
-#define APIC_LVT_NUM 6
/* 14 is the version for Xeon and Pentium 8.4.8*/
@@ -32,7 +32,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
#define LAPIC_MMIO_LENGTH (1 << 12)
/* followed define is not in apicdef.h */
#define APIC_SHORT_MASK 0xc0000
-@@ -72,14 +71,6 @@
+@@ -73,14 +72,6 @@
#define APIC_BROADCAST 0xFF
#define X2APIC_BROADCAST 0xFFFFFFFFul
@@ -47,7 +47,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static inline int apic_test_vector(int vec, void *bitmap)
{
return test_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
-@@ -93,11 +84,6 @@ bool kvm_apic_pending_eoi(struct kvm_vcp
+@@ -94,11 +85,6 @@ bool kvm_apic_pending_eoi(struct kvm_vcp
apic_test_vector(vector, apic->regs + APIC_IRR);
}
@@ -59,7 +59,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static inline void apic_clear_vector(int vec, void *bitmap)
{
clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
-@@ -216,7 +202,7 @@ static inline void apic_set_spiv(struct
+@@ -212,7 +198,7 @@ static inline void apic_set_spiv(struct
{
bool enabled = val & APIC_SPIV_APIC_ENABLED;
@@ -68,7 +68,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (enabled != apic->sw_enabled) {
apic->sw_enabled = enabled;
-@@ -230,13 +216,13 @@ static inline void apic_set_spiv(struct
+@@ -226,13 +212,13 @@ static inline void apic_set_spiv(struct
static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id)
{
@@ -84,7 +84,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
recalculate_apic_map(apic->vcpu->kvm);
}
-@@ -244,8 +230,8 @@ static inline void kvm_apic_set_x2apic_i
+@@ -240,8 +226,8 @@ static inline void kvm_apic_set_x2apic_i
{
u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf));
@@ -95,7 +95,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
recalculate_apic_map(apic->vcpu->kvm);
}
-@@ -299,10 +285,10 @@ void kvm_apic_set_version(struct kvm_vcp
+@@ -295,10 +281,10 @@ void kvm_apic_set_version(struct kvm_vcp
if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))) &&
!ioapic_in_kernel(vcpu->kvm))
v |= APIC_LVR_DIRECTED_EOI;
@@ -108,7 +108,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
LVT_MASK , /* part LVTT mask, timer mode mask added at runtime */
LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */
LVT_MASK | APIC_MODE_MASK, /* LVTPC */
-@@ -361,16 +347,6 @@ void kvm_apic_update_irr(struct kvm_vcpu
+@@ -357,16 +343,6 @@ void kvm_apic_update_irr(struct kvm_vcpu
}
EXPORT_SYMBOL_GPL(kvm_apic_update_irr);
@@ -125,7 +125,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static inline int apic_search_irr(struct kvm_lapic *apic)
{
return find_highest_vector(apic->regs + APIC_IRR);
-@@ -581,7 +557,7 @@ static void apic_update_ppr(struct kvm_l
+@@ -577,7 +553,7 @@ static void apic_update_ppr(struct kvm_l
apic, ppr, isr, isrv);
if (old_ppr != ppr) {
@@ -134,7 +134,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (ppr < old_ppr)
kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
}
-@@ -589,7 +565,7 @@ static void apic_update_ppr(struct kvm_l
+@@ -585,7 +561,7 @@ static void apic_update_ppr(struct kvm_l
static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr)
{
@@ -143,7 +143,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
apic_update_ppr(apic);
}
-@@ -686,6 +662,7 @@ bool kvm_apic_match_dest(struct kvm_vcpu
+@@ -682,6 +658,7 @@ bool kvm_apic_match_dest(struct kvm_vcpu
return false;
}
}
@@ -151,7 +151,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
int kvm_vector_to_index(u32 vector, u32 dest_vcpus,
const unsigned long *bitmap, u32 bitmap_size)
-@@ -858,7 +835,7 @@ static int __apic_accept_irq(struct kvm_
+@@ -935,7 +912,7 @@ static int __apic_accept_irq(struct kvm_
if (apic_test_vector(vector, apic->regs + APIC_TMR) != !!trig_mode) {
if (trig_mode)
@@ -160,7 +160,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
else
apic_clear_vector(vector, apic->regs + APIC_TMR);
}
-@@ -866,7 +843,7 @@ static int __apic_accept_irq(struct kvm_
+@@ -943,7 +920,7 @@ static int __apic_accept_irq(struct kvm_
if (vcpu->arch.apicv_active)
kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
else {
@@ -169,7 +169,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_make_request(KVM_REQ_EVENT, vcpu);
kvm_vcpu_kick(vcpu);
-@@ -1120,7 +1097,7 @@ static inline struct kvm_lapic *to_lapic
+@@ -1200,7 +1177,7 @@ static inline struct kvm_lapic *to_lapic
return container_of(dev, struct kvm_lapic, dev);
}
@@ -178,7 +178,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
void *data)
{
unsigned char alignment = offset & 0xf;
-@@ -1157,6 +1134,7 @@ static int apic_reg_read(struct kvm_lapi
+@@ -1237,6 +1214,7 @@ static int apic_reg_read(struct kvm_lapi
}
return 0;
}
@@ -186,7 +186,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr)
{
-@@ -1174,7 +1152,7 @@ static int apic_mmio_read(struct kvm_vcp
+@@ -1254,7 +1232,7 @@ static int apic_mmio_read(struct kvm_vcp
if (!apic_mmio_in_range(apic, address))
return -EOPNOTSUPP;
@@ -195,7 +195,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return 0;
}
-@@ -1359,7 +1337,7 @@ static void apic_manage_nmi_watchdog(str
+@@ -1439,7 +1417,7 @@ static void apic_manage_nmi_watchdog(str
}
}
@@ -204,7 +204,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
{
int ret = 0;
-@@ -1391,7 +1369,7 @@ static int apic_reg_write(struct kvm_lap
+@@ -1471,7 +1449,7 @@ static int apic_reg_write(struct kvm_lap
case APIC_DFR:
if (!apic_x2apic_mode(apic)) {
@@ -213,7 +213,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
recalculate_apic_map(apic->vcpu->kvm);
} else
ret = 1;
-@@ -1406,10 +1384,10 @@ static int apic_reg_write(struct kvm_lap
+@@ -1486,10 +1464,10 @@ static int apic_reg_write(struct kvm_lap
int i;
u32 lvt_val;
@@ -226,7 +226,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
lvt_val | APIC_LVT_MASKED);
}
apic_update_lvtt(apic);
-@@ -1420,14 +1398,14 @@ static int apic_reg_write(struct kvm_lap
+@@ -1500,14 +1478,14 @@ static int apic_reg_write(struct kvm_lap
}
case APIC_ICR:
/* No delay here, so we always clear the pending bit */
@@ -243,7 +243,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
break;
case APIC_LVT0:
-@@ -1441,7 +1419,7 @@ static int apic_reg_write(struct kvm_lap
+@@ -1521,7 +1499,7 @@ static int apic_reg_write(struct kvm_lap
val |= APIC_LVT_MASKED;
val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4];
@@ -252,7 +252,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
break;
-@@ -1449,7 +1427,7 @@ static int apic_reg_write(struct kvm_lap
+@@ -1529,7 +1507,7 @@ static int apic_reg_write(struct kvm_lap
if (!kvm_apic_sw_enabled(apic))
val |= APIC_LVT_MASKED;
val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask);
@@ -261,7 +261,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
apic_update_lvtt(apic);
break;
-@@ -1458,14 +1436,14 @@ static int apic_reg_write(struct kvm_lap
+@@ -1538,14 +1516,14 @@ static int apic_reg_write(struct kvm_lap
break;
hrtimer_cancel(&apic->lapic_timer.timer);
@@ -278,7 +278,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
update_divide_count(apic);
break;
-@@ -1478,7 +1456,7 @@ static int apic_reg_write(struct kvm_lap
+@@ -1558,7 +1536,7 @@ static int apic_reg_write(struct kvm_lap
case APIC_SELF_IPI:
if (apic_x2apic_mode(apic)) {
@@ -287,7 +287,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
} else
ret = 1;
break;
-@@ -1490,6 +1468,7 @@ static int apic_reg_write(struct kvm_lap
+@@ -1570,6 +1548,7 @@ static int apic_reg_write(struct kvm_lap
apic_debug("Local APIC Write to read-only register %x\n", reg);
return ret;
}
@@ -295,7 +295,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this,
gpa_t address, int len, const void *data)
-@@ -1519,7 +1498,7 @@ static int apic_mmio_write(struct kvm_vc
+@@ -1599,7 +1578,7 @@ static int apic_mmio_write(struct kvm_vc
apic_debug("%s: offset 0x%x with length 0x%x, and value is "
"0x%x\n", __func__, offset, len, val);
@@ -304,7 +304,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return 0;
}
-@@ -1527,7 +1506,7 @@ static int apic_mmio_write(struct kvm_vc
+@@ -1607,7 +1586,7 @@ static int apic_mmio_write(struct kvm_vc
void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu)
{
if (kvm_vcpu_has_lapic(vcpu))
@@ -313,7 +313,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi);
-@@ -1539,10 +1518,10 @@ void kvm_apic_write_nodecode(struct kvm_
+@@ -1619,10 +1598,10 @@ void kvm_apic_write_nodecode(struct kvm_
/* hw has done the conditional check and inst decode */
offset &= 0xff0;
@@ -326,7 +326,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
EXPORT_SYMBOL_GPL(kvm_apic_write_nodecode);
-@@ -1681,28 +1660,28 @@ void kvm_lapic_reset(struct kvm_vcpu *vc
+@@ -1761,28 +1740,28 @@ void kvm_lapic_reset(struct kvm_vcpu *vc
kvm_apic_set_id(apic, vcpu->vcpu_id);
kvm_apic_set_version(apic->vcpu);
@@ -368,7 +368,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
apic->irr_pending = vcpu->arch.apicv_active;
apic->isr_count = vcpu->arch.apicv_active ? 1 : 0;
-@@ -2078,8 +2057,8 @@ int kvm_x2apic_msr_write(struct kvm_vcpu
+@@ -2164,8 +2143,8 @@ int kvm_x2apic_msr_write(struct kvm_vcpu
/* if this is ICR write vector before command */
if (reg == APIC_ICR)
@@ -379,7 +379,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data)
-@@ -2096,10 +2075,10 @@ int kvm_x2apic_msr_read(struct kvm_vcpu
+@@ -2182,10 +2161,10 @@ int kvm_x2apic_msr_read(struct kvm_vcpu
return 1;
}
@@ -392,7 +392,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
*data = (((u64)high) << 32) | low;
-@@ -2115,8 +2094,8 @@ int kvm_hv_vapic_msr_write(struct kvm_vc
+@@ -2201,8 +2180,8 @@ int kvm_hv_vapic_msr_write(struct kvm_vc
/* if this is ICR write vector before command */
if (reg == APIC_ICR)
@@ -403,7 +403,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data)
-@@ -2127,10 +2106,10 @@ int kvm_hv_vapic_msr_read(struct kvm_vcp
+@@ -2213,10 +2192,10 @@ int kvm_hv_vapic_msr_read(struct kvm_vcp
if (!kvm_vcpu_has_lapic(vcpu))
return 1;
diff --git a/patches.arch/0003-kvm-x86-introducing-kvm_x86_ops-vm-init-destroy-hooks b/patches.arch/0003-kvm-x86-introducing-kvm_x86_ops-vm-init-destroy-hooks
index a250dceff9..f134ede9cc 100644
--- a/patches.arch/0003-kvm-x86-introducing-kvm_x86_ops-vm-init-destroy-hooks
+++ b/patches.arch/0003-kvm-x86-introducing-kvm_x86_ops-vm-init-destroy-hooks
@@ -12,14 +12,14 @@ Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- arch/x86/include/asm/kvm_host.h | 3 +++
- arch/x86/kvm/x86.c | 5 +++++
+ arch/x86/include/asm/kvm_host.h | 3 +++
+ arch/x86/kvm/x86.c | 5 +++++
2 files changed, 8 insertions(+)
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
-@@ -770,6 +770,9 @@ struct kvm_x86_ops {
- bool (*cpu_has_high_real_mode_segbase)(void);
+@@ -794,6 +794,9 @@ struct kvm_x86_ops {
+ bool (*has_emulated_msr)(int index);
void (*cpuid_update)(struct kvm_vcpu *vcpu);
+ int (*vm_init)(struct kvm *kvm);
@@ -30,7 +30,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
void (*vcpu_free)(struct kvm_vcpu *vcpu);
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -7757,6 +7757,9 @@ int __x86_set_memory_region(struct kvm *
+@@ -7868,6 +7868,9 @@ int __x86_set_memory_region(struct kvm *
WARN_ON(r < 0);
}
@@ -40,7 +40,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return 0;
}
EXPORT_SYMBOL_GPL(__x86_set_memory_region);
-@@ -7785,6 +7788,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm
+@@ -7896,6 +7899,8 @@ void kvm_arch_destroy_vm(struct kvm *kvm
x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT, 0, 0);
x86_set_memory_region(kvm, TSS_PRIVATE_MEMSLOT, 0, 0);
}
diff --git a/patches.arch/0004-x86-kvm-Move-l1tf-setup-function.patch b/patches.arch/0004-x86-kvm-Move-l1tf-setup-function.patch
index 21cc10d494..606e4cb1c8 100644
--- a/patches.arch/0004-x86-kvm-Move-l1tf-setup-function.patch
+++ b/patches.arch/0004-x86-kvm-Move-l1tf-setup-function.patch
@@ -31,7 +31,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -178,7 +178,8 @@ extern const ulong vmx_return;
+@@ -186,7 +186,8 @@ extern const ulong vmx_return;
static DEFINE_STATIC_KEY_FALSE(vmx_l1d_should_flush);
@@ -41,7 +41,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
static const struct {
const char *option;
-@@ -190,33 +191,85 @@ static const struct {
+@@ -198,33 +199,85 @@ static const struct {
{"always", VMENTER_L1D_FLUSH_ALWAYS},
};
@@ -137,8 +137,8 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, NULL, S_IRUGO);
#define NR_AUTOLOAD_MSRS 8
- #define VMCS02_POOL_SIZE 1
-@@ -8305,7 +8358,7 @@ static void vmx_l1d_flush(struct kvm_vcp
+
+@@ -8321,7 +8374,7 @@ static void vmx_l1d_flush(struct kvm_vcp
* it. The flush bit gets set again either from vcpu_run() or from
* one of the unsafe VMEXIT handlers.
*/
@@ -147,7 +147,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
vcpu->arch.l1tf_flush_l1d = always;
vcpu->stat.l1d_flush++;
-@@ -11177,34 +11230,6 @@ static struct kvm_x86_ops vmx_x86_ops =
+@@ -11270,34 +11323,6 @@ static struct kvm_x86_ops vmx_x86_ops =
.setup_mce = vmx_setup_mce,
};
@@ -182,7 +182,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
static void vmx_cleanup_l1d_flush(void)
{
if (vmx_l1d_flush_pages) {
-@@ -11239,12 +11264,18 @@ static int __init vmx_init(void)
+@@ -11332,12 +11357,18 @@ static int __init vmx_init(void)
return r;
/*
diff --git a/patches.arch/0005-kvm-x86-svm-call-x86_spec_ctrl_set_guest-host-with-interrupts-disabled b/patches.arch/0005-kvm-x86-svm-call-x86_spec_ctrl_set_guest-host-with-interrupts-disabled
index c92e83998a..1d688e84b4 100644
--- a/patches.arch/0005-kvm-x86-svm-call-x86_spec_ctrl_set_guest-host-with-interrupts-disabled
+++ b/patches.arch/0005-kvm-x86-svm-call-x86_spec_ctrl_set_guest-host-with-interrupts-disabled
@@ -68,17 +68,22 @@ Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- arch/x86/kvm/svm.c | 8 ++++----
+ arch/x86/kvm/svm.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
-@@ -4864,10 +4864,10 @@ static void svm_vcpu_run(struct kvm_vcpu
+@@ -4906,8 +4906,6 @@ static void svm_vcpu_run(struct kvm_vcpu
clgi();
- local_irq_enable();
-
+ /*
+ * If this vCPU has touched SPEC_CTRL, restore the guest's value if
+ * it's non-zero. Since vmentry is serialising on affected CPUs, there
+@@ -4916,6 +4914,8 @@ static void svm_vcpu_run(struct kvm_vcpu
+ */
x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl);
+ local_irq_enable();
@@ -86,8 +91,8 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
asm volatile (
"push %%" _ASM_BP "; \n\t"
"mov %c[rbx](%[svm]), %%" _ASM_BX " \n\t"
-@@ -4975,12 +4975,12 @@ static void svm_vcpu_run(struct kvm_vcpu
- if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
+@@ -5038,12 +5038,12 @@ static void svm_vcpu_run(struct kvm_vcpu
+ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
- x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl);
diff --git a/patches.arch/0007-kvm-pkeys-expose-cpuid-cr4-to-guest b/patches.arch/0007-kvm-pkeys-expose-cpuid-cr4-to-guest
index 48617037e7..0a2df2c38f 100644
--- a/patches.arch/0007-kvm-pkeys-expose-cpuid-cr4-to-guest
+++ b/patches.arch/0007-kvm-pkeys-expose-cpuid-cr4-to-guest
@@ -18,15 +18,15 @@ Reviewed-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- arch/x86/include/asm/kvm_host.h | 3 ++-
- arch/x86/kvm/cpuid.c | 23 +++++++++++++++++++++--
- arch/x86/kvm/cpuid.h | 8 ++++++++
- arch/x86/kvm/x86.c | 9 ++++++---
- 4 files changed, 37 insertions(+), 6 deletions(-)
+ arch/x86/include/asm/kvm_host.h | 3 ++-
+ arch/x86/kvm/cpuid.c | 20 +++++++++++++++++++-
+ arch/x86/kvm/cpuid.h | 8 ++++++++
+ arch/x86/kvm/x86.c | 9 ++++++---
+ 4 files changed, 35 insertions(+), 5 deletions(-)
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
-@@ -57,7 +57,8 @@
+@@ -58,7 +58,8 @@
| X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE \
| X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \
| X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \
@@ -38,7 +38,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
-@@ -81,6 +81,16 @@ int kvm_update_cpuid(struct kvm_vcpu *vc
+@@ -94,6 +94,16 @@ int kvm_update_cpuid(struct kvm_vcpu *vc
apic->lapic_timer.timer_mode_mask = 1 << 17;
}
@@ -55,38 +55,40 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
best = kvm_find_cpuid_entry(vcpu, 0xD, 0);
if (!best) {
vcpu->arch.guest_supported_xcr0 = 0;
-@@ -354,6 +364,9 @@ static inline int __do_cpuid_ent(struct
+@@ -371,6 +381,9 @@ static inline int __do_cpuid_ent(struct
const u32 kvm_cpuid_D_1_eax_x86_features =
F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves;
+ /* cpuid 7.0.ecx*/
+ const u32 kvm_cpuid_7_0_ecx_x86_features = F(PKU) | 0 /*OSPKE*/;
+
- /* all calls to cpuid_count() should be made on the same cpu */
- get_cpu();
-
-@@ -431,10 +444,16 @@ static inline int __do_cpuid_ent(struct
+ /* cpuid 7.0.edx*/
+ const u32 kvm_cpuid_7_0_edx_x86_features =
+ KF(SPEC_CTRL) | KF(SPEC_CTRL_SSBD) | KF(ARCH_CAPABILITIES);
+@@ -452,14 +465,19 @@ static inline int __do_cpuid_ent(struct
cpuid_mask(&entry->ebx, CPUID_7_0_EBX);
// TSC_ADJUST is emulated
entry->ebx |= F(TSC_ADJUST);
-- } else
+ entry->ecx &= kvm_cpuid_7_0_ecx_x86_features;
+ cpuid_mask(&entry->ecx, CPUID_7_ECX);
+ /* PKU is not yet implemented for shadow paging. */
+ if (!tdp_enabled)
+ entry->ecx &= ~F(PKU);
-+ } else {
+ entry->edx &= kvm_cpuid_7_0_edx_x86_features;
+ entry->edx &= get_scattered_cpuid_leaf(7, 0, CPUID_EDX);
+ } else {
entry->ebx = 0;
+ entry->ecx = 0;
-+ }
+ entry->edx = 0;
+ }
entry->eax = 0;
- entry->ecx = 0;
- entry->edx = 0;
break;
}
+ case 9:
--- a/arch/x86/kvm/cpuid.h
+++ b/arch/x86/kvm/cpuid.h
-@@ -78,6 +78,14 @@ static inline bool guest_cpuid_has_fsgsb
+@@ -79,6 +79,14 @@ static inline bool guest_cpuid_has_fsgsb
return best && (best->ebx & bit(X86_FEATURE_FSGSBASE));
}
@@ -103,7 +105,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
struct kvm_cpuid_entry2 *best;
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -728,7 +728,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, u
+@@ -731,7 +731,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, u
{
unsigned long old_cr4 = kvm_read_cr4(vcpu);
unsigned long pdptr_bits = X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE |
@@ -112,7 +114,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (cr4 & CR4_RESERVED_BITS)
return 1;
-@@ -745,6 +745,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, u
+@@ -748,6 +748,9 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, u
if (!guest_cpuid_has_fsgsbase(vcpu) && (cr4 & X86_CR4_FSGSBASE))
return 1;
@@ -122,7 +124,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (is_long_mode(vcpu)) {
if (!(cr4 & X86_CR4_PAE))
return 1;
-@@ -770,7 +773,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, u
+@@ -774,7 +777,7 @@ int kvm_set_cr4(struct kvm_vcpu *vcpu, u
(!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
kvm_mmu_reset_context(vcpu);
@@ -131,7 +133,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_update_cpuid(vcpu);
return 0;
-@@ -7058,7 +7061,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
+@@ -7159,7 +7162,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct
mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4;
kvm_x86_ops->set_cr4(vcpu, sregs->cr4);
diff --git a/patches.arch/0007-x86-kvm-Allow-runtime-control-of-L1D-flush.patch b/patches.arch/0007-x86-kvm-Allow-runtime-control-of-L1D-flush.patch
index fde818631b..ceee1e1395 100644
--- a/patches.arch/0007-x86-kvm-Allow-runtime-control-of-L1D-flush.patch
+++ b/patches.arch/0007-x86-kvm-Allow-runtime-control-of-L1D-flush.patch
@@ -40,7 +40,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -219,12 +219,15 @@ static int vmx_setup_l1d_flush(enum vmx_
+@@ -227,12 +227,15 @@ static int vmx_setup_l1d_flush(enum vmx_
l1tf_vmx_mitigation = l1tf;
@@ -59,7 +59,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
return 0;
}
-@@ -234,7 +237,7 @@ static int vmentry_l1d_flush_parse(const
+@@ -242,7 +245,7 @@ static int vmentry_l1d_flush_parse(const
if (s) {
for (i = 0; i < ARRAY_SIZE(vmentry_l1d_param); i++) {
@@ -68,7 +68,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
return vmentry_l1d_param[i].cmd;
}
}
-@@ -278,7 +281,7 @@ static const struct kernel_param_ops vme
+@@ -286,7 +289,7 @@ static const struct kernel_param_ops vme
.set = vmentry_l1d_flush_set,
.get = vmentry_l1d_flush_get,
};
@@ -76,4 +76,4 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, NULL, 0644);
#define NR_AUTOLOAD_MSRS 8
- #define VMCS02_POOL_SIZE 1
+
diff --git a/patches.arch/0012-svm-manage-vcpu-load-unload-when-enable-avic b/patches.arch/0012-svm-manage-vcpu-load-unload-when-enable-avic
index 1893962635..4027fe58a1 100644
--- a/patches.arch/0012-svm-manage-vcpu-load-unload-when-enable-avic
+++ b/patches.arch/0012-svm-manage-vcpu-load-unload-when-enable-avic
@@ -24,7 +24,7 @@ Reviewed-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- arch/x86/kvm/svm.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ arch/x86/kvm/svm.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
--- a/arch/x86/kvm/svm.c
@@ -37,7 +37,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
#include <asm/perf_event.h>
#include <asm/tlbflush.h>
#include <asm/desc.h>
-@@ -181,6 +182,7 @@ struct vcpu_svm {
+@@ -193,6 +194,7 @@ struct vcpu_svm {
u32 ldr_reg;
struct page *avic_backing_page;
u64 *avic_physical_id_cache;
@@ -45,7 +45,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
};
#define AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK (0xFF)
-@@ -1313,6 +1315,72 @@ free_avic:
+@@ -1348,6 +1350,72 @@ free_avic:
return err;
}
@@ -118,7 +118,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
{
struct vcpu_svm *svm = to_svm(vcpu);
-@@ -1376,6 +1444,11 @@ static struct kvm_vcpu *svm_create_vcpu(
+@@ -1414,6 +1482,11 @@ static struct kvm_vcpu *svm_create_vcpu(
goto free_page4;
}
@@ -130,16 +130,16 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
svm->nested.hsave = page_address(hsave_page);
svm->msrpm = page_address(msrpm_pages);
-@@ -1449,6 +1522,8 @@ static void svm_vcpu_load(struct kvm_vcp
- /* This assumes that the kernel never uses MSR_TSC_AUX */
- if (static_cpu_has(X86_FEATURE_RDTSCP))
- wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
+@@ -1500,6 +1573,8 @@ static void svm_vcpu_load(struct kvm_vcp
+ sd->current_vmcb = svm->vmcb;
+ indirect_branch_prediction_barrier();
+ }
+
+ avic_vcpu_load(vcpu, cpu);
}
static void svm_vcpu_put(struct kvm_vcpu *vcpu)
-@@ -1456,6 +1531,8 @@ static void svm_vcpu_put(struct kvm_vcpu
+@@ -1507,6 +1582,8 @@ static void svm_vcpu_put(struct kvm_vcpu
struct vcpu_svm *svm = to_svm(vcpu);
int i;
@@ -148,7 +148,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
++vcpu->stat.host_state_reload;
kvm_load_ldt(svm->host.ldt);
#ifdef CONFIG_X86_64
-@@ -1471,6 +1548,16 @@ static void svm_vcpu_put(struct kvm_vcpu
+@@ -1522,6 +1599,16 @@ static void svm_vcpu_put(struct kvm_vcpu
wrmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
}
@@ -165,7 +165,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static unsigned long svm_get_rflags(struct kvm_vcpu *vcpu)
{
return to_svm(vcpu)->vmcb->save.rflags;
-@@ -4833,6 +4920,8 @@ static struct kvm_x86_ops svm_x86_ops =
+@@ -5037,6 +5124,8 @@ static struct kvm_x86_ops svm_x86_ops =
.prepare_guest_switch = svm_prepare_guest_switch,
.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
diff --git a/patches.arch/0018-mm-gup-introduce-get_user_pages_remote b/patches.arch/0018-mm-gup-introduce-get_user_pages_remote
index 09c872b9fe..9ff93c6e8a 100644
--- a/patches.arch/0018-mm-gup-introduce-get_user_pages_remote
+++ b/patches.arch/0018-mm-gup-introduce-get_user_pages_remote
@@ -52,29 +52,28 @@ Link: http://lkml.kernel.org/r/20160212210154.3F0E51EA@viggo.jf.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- drivers/gpu/drm/etnaviv/etnaviv_gem.c | 6 +++---
- drivers/gpu/drm/i915/i915_gem_userptr.c | 10 +++++-----
- drivers/infiniband/core/umem_odp.c | 8 ++++----
- fs/exec.c | 8 ++++++--
- include/linux/mm.h | 5 +++++
- kernel/events/uprobes.c | 10 ++++++++--
- mm/gup.c | 27 ++++++++++++++++++++++-----
- mm/memory.c | 2 +-
- mm/process_vm_access.c | 11 ++++++++---
- security/tomoyo/domain.c | 9 ++++++++-
- virt/kvm/async_pf.c | 8 +++++++-
- 11 files changed, 77 insertions(+), 27 deletions(-)
+ drivers/gpu/drm/i915/i915_gem_userptr.c | 10 +++++-----
+ drivers/infiniband/core/umem_odp.c | 7 ++++---
+ fs/exec.c | 8 ++++++--
+ include/linux/mm.h | 5 +++++
+ kernel/events/uprobes.c | 10 ++++++++--
+ mm/gup.c | 24 +++++++++++++++++++++++-
+ mm/memory.c | 4 ++--
+ mm/process_vm_access.c | 12 ++++++++----
+ security/tomoyo/domain.c | 10 ++++++++--
+ virt/kvm/async_pf.c | 9 ++++++++-
+ 10 files changed, 77 insertions(+), 22 deletions(-)
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
-@@ -584,11 +584,11 @@ __i915_gem_userptr_get_pages_worker(stru
+@@ -588,11 +588,11 @@ __i915_gem_userptr_get_pages_worker(stru
down_read(&mm->mmap_sem);
while (pinned < npages) {
- ret = get_user_pages(work->task, mm,
- obj->userptr.ptr + pinned * PAGE_SIZE,
- npages - pinned,
-- !obj->userptr.read_only, 0,
+- flags,
- pvec + pinned, NULL);
+ ret = get_user_pages_remote(work->task, mm,
+ obj->userptr.ptr + pinned * PAGE_SIZE,
@@ -86,14 +85,13 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
--- a/drivers/infiniband/core/umem_odp.c
+++ b/drivers/infiniband/core/umem_odp.c
-@@ -572,10 +572,10 @@ int ib_umem_odp_map_dma_pages(struct ib_
+@@ -576,9 +576,10 @@ int ib_umem_odp_map_dma_pages(struct ib_
* complex (and doesn't gain us much performance in most use
* cases).
*/
- npages = get_user_pages(owning_process, owning_mm, user_virt,
- gup_num_pages,
-- access_mask & ODP_WRITE_ALLOWED_BIT, 0,
-- local_page_list, NULL);
+- flags, local_page_list, NULL);
+ npages = get_user_pages_remote(owning_process, owning_mm,
+ user_virt, gup_num_pages,
+ access_mask & ODP_WRITE_ALLOWED_BIT,
@@ -103,12 +101,12 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (npages < 0)
--- a/fs/exec.c
+++ b/fs/exec.c
-@@ -198,8 +198,12 @@ static struct page *get_arg_page(struct
- return NULL;
- }
- #endif
-- ret = get_user_pages(current, bprm->mm, pos,
-- 1, write, 1, &page, NULL);
+@@ -204,8 +204,12 @@ static struct page *get_arg_page(struct
+ if (write)
+ gup_flags |= FOLL_WRITE;
+
+- ret = get_user_pages(current, bprm->mm, pos, 1, gup_flags,
+- &page, NULL);
+ /*
+ * We are doing an exec(). 'current' is the process
+ * doing the exec and bprm->mm is the new process's mm.
@@ -120,7 +118,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
-@@ -1213,6 +1213,10 @@ long __get_user_pages(struct task_struct
+@@ -1230,6 +1230,10 @@ long __get_user_pages(struct task_struct
unsigned long start, unsigned long nr_pages,
unsigned int foll_flags, struct page **pages,
struct vm_area_struct **vmas, int *nonblocking);
@@ -130,22 +128,22 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ struct vm_area_struct **vmas);
long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
- int write, int force, struct page **pages,
-@@ -2132,6 +2136,7 @@ static inline struct page *follow_page(s
+ unsigned int gup_flags, struct page **pages,
+@@ -2177,6 +2181,7 @@ static inline struct page *follow_page(s
#define FOLL_MIGRATION 0x400 /* wait for page to replace migration entry */
#define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */
#define FOLL_MLOCK 0x1000 /* lock present pages */
+#define FOLL_REMOTE 0x2000 /* we are working on non-current tsk/mm */
#define FOLL_COW 0x4000 /* internal GUP flag */
+ #define FOLL_ANON 0x8000 /* don't do file mappings */
- typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
--- a/kernel/events/uprobes.c
+++ b/kernel/events/uprobes.c
@@ -299,7 +299,7 @@ int uprobe_write_opcode(struct mm_struct
retry:
/* Read the page with vaddr into memory */
-- ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
+- ret = get_user_pages(NULL, mm, vaddr, 1, FOLL_FORCE, &old_page, &vma);
+ ret = get_user_pages_remote(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
if (ret <= 0)
return ret;
@@ -154,7 +152,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (likely(result == 0))
goto out;
-- result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
+- result = get_user_pages(NULL, mm, vaddr, 1, FOLL_FORCE, &page, NULL);
+ /*
+ * The NULL 'tsk' here ensures that any faults that occur here
+ * will not be accounted to the task. 'mm' *is* current->mm,
@@ -167,7 +165,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
--- a/mm/gup.c
+++ b/mm/gup.c
-@@ -827,7 +827,7 @@ long get_user_pages_unlocked(struct task
+@@ -826,7 +826,7 @@ long get_user_pages_unlocked(struct task
EXPORT_SYMBOL(get_user_pages_unlocked);
/*
@@ -176,22 +174,25 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
* @tsk: the task_struct to use for page fault accounting, or
* NULL if faults are not to be recorded.
* @mm: mm_struct of target mm
-@@ -881,12 +881,29 @@ EXPORT_SYMBOL(get_user_pages_unlocked);
+@@ -880,6 +880,28 @@ EXPORT_SYMBOL(get_user_pages_unlocked);
* should use get_user_pages because it cannot pass
* FAULT_FLAG_ALLOW_RETRY to handle_mm_fault.
*/
--long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
-- unsigned long start, unsigned long nr_pages, int write,
-- int force, struct page **pages, struct vm_area_struct **vmas)
+long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+ int write, int force, struct page **pages,
+ struct vm_area_struct **vmas)
- {
- return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force,
-- pages, vmas, NULL, false, FOLL_TOUCH);
++{
++ unsigned int flags = FOLL_TOUCH | FOLL_REMOTE;
++
++ if (write)
++ flags |= FOLL_WRITE;
++ if (force)
++ flags |= FOLL_FORCE;
++
++ return __get_user_pages_locked(tsk, mm, start, nr_pages,
+ pages, vmas, NULL, false,
-+ FOLL_TOUCH | FOLL_REMOTE);
++ flags);
+}
+EXPORT_SYMBOL(get_user_pages_remote);
+
@@ -199,55 +200,58 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ * This is the same as get_user_pages_remote() for the time
+ * being.
+ */
-+long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
-+ unsigned long start, unsigned long nr_pages,
-+ int write, int force, struct page **pages,
-+ struct vm_area_struct **vmas)
-+{
-+ return __get_user_pages_locked(tsk, mm, start, nr_pages,
-+ write, force, pages, vmas, NULL, false,
-+ FOLL_TOUCH);
- }
- EXPORT_SYMBOL(get_user_pages);
-
+ long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+ unsigned int gup_flags, struct page **pages,
--- a/mm/memory.c
+++ b/mm/memory.c
-@@ -3730,7 +3730,7 @@ static int __access_remote_vm(struct tas
+@@ -3713,8 +3713,8 @@ static int __access_remote_vm(struct tas
void *maddr;
struct page *page = NULL;
- ret = get_user_pages(tsk, mm, addr, 1,
+- gup_flags, &page, &vma);
+ ret = get_user_pages_remote(tsk, mm, addr, 1,
- write, 1, &page, &vma);
++ write, 1, &page, &vma);
if (ret <= 0) {
#ifndef CONFIG_HAVE_IOREMAP_PROT
+ break;
--- a/mm/process_vm_access.c
+++ b/mm/process_vm_access.c
-@@ -98,9 +98,14 @@ static int process_vm_rw_single_vec(unsi
+@@ -88,7 +88,7 @@ static int process_vm_rw_single_vec(unsi
+ ssize_t rc = 0;
+ unsigned long max_pages_per_loop = PVM_MAX_KMALLOC_PAGES
+ / sizeof(struct pages *);
+- unsigned int flags = 0;
++ unsigned int flags = FOLL_REMOTE;
+
+ /* Work out address and page range required */
+ if (len == 0)
+@@ -102,9 +102,13 @@ static int process_vm_rw_single_vec(unsi
int pages = min(nr_pages, max_pages_per_loop);
size_t bytes;
- /* Get the pages we're interested in */
- pages = get_user_pages_unlocked(task, mm, pa, pages,
-- vm_write, 0, process_pages);
+- process_pages, flags);
+ /*
+ * Get the pages we're interested in. We must
+ * add FOLL_REMOTE because task/mm might not
+ * current/current->mm
+ */
+ pages = __get_user_pages_unlocked(task, mm, pa, pages,
-+ vm_write, 0, process_pages,
-+ FOLL_REMOTE);
++ process_pages, flags);
if (pages <= 0)
return -EFAULT;
--- a/security/tomoyo/domain.c
+++ b/security/tomoyo/domain.c
-@@ -874,7 +874,14 @@ bool tomoyo_dump_page(struct linux_binpr
+@@ -874,8 +874,14 @@ bool tomoyo_dump_page(struct linux_binpr
}
/* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
#ifdef CONFIG_MMU
-- if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
+- if (get_user_pages(current, bprm->mm, pos, 1,
+- FOLL_FORCE, &page, NULL) <= 0)
+ /*
+ * This is called at execve() time in order to dig around
+ * in the argv/environment of the new proceess
@@ -261,17 +265,18 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
page = bprm->page[pos / PAGE_SIZE];
--- a/virt/kvm/async_pf.c
+++ b/virt/kvm/async_pf.c
-@@ -80,7 +80,13 @@ static void async_pf_execute(struct work
+@@ -80,7 +80,14 @@ static void async_pf_execute(struct work
might_sleep();
-- get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL);
+- get_user_pages_unlocked(NULL, mm, addr, 1, NULL, FOLL_WRITE);
+ /*
+ * This work is run asynchromously to the task which owns
+ * mm and might be done in another context, so we must
+ * use FOLL_REMOTE.
+ */
-+ __get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL, FOLL_REMOTE);
++ __get_user_pages_unlocked(NULL, mm, addr, 1, NULL,
++ FOLL_WRITE | FOLL_REMOTE);
+
kvm_async_page_present_sync(vcpu, apf);
diff --git a/patches.arch/0019-mm-core-do-not-enforce-pkey-permissions-on-remote-mm-access b/patches.arch/0019-mm-core-do-not-enforce-pkey-permissions-on-remote-mm-access
index fbfcd39eed..bfd1c7b7ca 100644
--- a/patches.arch/0019-mm-core-do-not-enforce-pkey-permissions-on-remote-mm-access
+++ b/patches.arch/0019-mm-core-do-not-enforce-pkey-permissions-on-remote-mm-access
@@ -89,16 +89,16 @@ Cc: linuxppc-dev@lists.ozlabs.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Joerg Roedel <jroedel@suse.de>
---
- arch/powerpc/include/asm/mmu_context.h | 3 ++-
- arch/s390/include/asm/mmu_context.h | 3 ++-
- arch/unicore32/include/asm/mmu_context.h | 3 ++-
- arch/x86/include/asm/mmu_context.h | 5 +++--
- drivers/iommu/amd_iommu_v2.c | 1 +
- include/asm-generic/mm_hooks.h | 3 ++-
- include/linux/mm.h | 1 +
- mm/gup.c | 15 ++++++++++-----
- mm/ksm.c | 10 ++++++++--
- mm/memory.c | 3 ++-
+ arch/powerpc/include/asm/mmu_context.h | 3 ++-
+ arch/s390/include/asm/mmu_context.h | 3 ++-
+ arch/unicore32/include/asm/mmu_context.h | 3 ++-
+ arch/x86/include/asm/mmu_context.h | 5 +++--
+ drivers/iommu/amd_iommu_v2.c | 1 +
+ include/asm-generic/mm_hooks.h | 3 ++-
+ include/linux/mm.h | 1 +
+ mm/gup.c | 15 ++++++++++-----
+ mm/ksm.c | 10 ++++++++--
+ mm/memory.c | 3 ++-
10 files changed, 33 insertions(+), 14 deletions(-)
--- a/arch/powerpc/include/asm/mmu_context.h
@@ -139,7 +139,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return true;
--- a/arch/x86/include/asm/mmu_context.h
+++ b/arch/x86/include/asm/mmu_context.h
-@@ -322,10 +322,11 @@ static inline bool vma_is_foreign(struct
+@@ -243,10 +243,11 @@ static inline bool vma_is_foreign(struct
return false;
}
@@ -153,6 +153,16 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return true;
return __pkru_allows_pkey(vma_pkey(vma), write);
}
+--- a/drivers/iommu/amd_iommu_v2.c
++++ b/drivers/iommu/amd_iommu_v2.c
+@@ -526,6 +526,7 @@ static void do_fault(struct work_struct
+ flags |= FAULT_FLAG_USER;
+ if (fault->flags & PPR_FAULT_WRITE)
+ flags |= FAULT_FLAG_WRITE;
++ flags |= FAULT_FLAG_REMOTE;
+
+ down_read(&mm->mmap_sem);
+ vma = find_extend_vma(mm, address);
--- a/include/asm-generic/mm_hooks.h
+++ b/include/asm-generic/mm_hooks.h
@@ -26,7 +26,8 @@ static inline void arch_bprm_mm_init(str
@@ -167,7 +177,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return true;
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
-@@ -237,6 +237,7 @@ extern pgprot_t protection_map[16];
+@@ -239,6 +239,7 @@ extern pgprot_t protection_map[16];
#define FAULT_FLAG_KILLABLE 0x10 /* The fault task is in SIGKILL killable region */
#define FAULT_FLAG_TRIED 0x20 /* Second try */
#define FAULT_FLAG_USER 0x40 /* The fault originated in userspace */
@@ -177,7 +187,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
* vm_fault is filled by the the pagefault handler and passed to the vma's
--- a/mm/gup.c
+++ b/mm/gup.c
-@@ -320,6 +320,8 @@ static int faultin_page(struct task_stru
+@@ -342,6 +342,8 @@ static int faultin_page(struct task_stru
return -ENOENT;
if (*flags & FOLL_WRITE)
fault_flags |= FAULT_FLAG_WRITE;
@@ -186,7 +196,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (nonblocking)
fault_flags |= FAULT_FLAG_ALLOW_RETRY;
if (*flags & FOLL_NOWAIT)
-@@ -370,11 +372,13 @@ static int faultin_page(struct task_stru
+@@ -392,6 +394,8 @@ static int faultin_page(struct task_stru
static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
{
vm_flags_t vm_flags = vma->vm_flags;
@@ -195,13 +205,16 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (vm_flags & (VM_IO | VM_PFNMAP))
return -EFAULT;
+@@ -399,7 +403,7 @@ static int check_vma_flags(struct vm_are
+ if (gup_flags & FOLL_ANON && !vma_is_anonymous(vma))
+ return -EFAULT;
- if (gup_flags & FOLL_WRITE) {
+ if (write) {
if (!(vm_flags & VM_WRITE)) {
if (!(gup_flags & FOLL_FORCE))
return -EFAULT;
-@@ -402,7 +406,7 @@ static int check_vma_flags(struct vm_are
+@@ -425,7 +429,7 @@ static int check_vma_flags(struct vm_are
if (!(vm_flags & VM_MAYREAD))
return -EFAULT;
}
@@ -210,7 +223,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return -EFAULT;
return 0;
}
-@@ -572,7 +576,8 @@ EXPORT_SYMBOL(__get_user_pages);
+@@ -595,7 +599,8 @@ EXPORT_SYMBOL(__get_user_pages);
bool vma_permits_fault(struct vm_area_struct *vma, unsigned int fault_flags)
{
@@ -220,7 +233,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
vm_flags_t vm_flags = write ? VM_WRITE : VM_READ;
if (!(vm_flags & vma->vm_flags))
-@@ -580,9 +585,9 @@ bool vma_permits_fault(struct vm_area_st
+@@ -603,9 +608,9 @@ bool vma_permits_fault(struct vm_area_st
/*
* The architecture might have a hardware protection
@@ -264,7 +277,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
put_page(page);
--- a/mm/memory.c
+++ b/mm/memory.c
-@@ -3402,7 +3402,8 @@ static int __handle_mm_fault(struct mm_s
+@@ -3385,7 +3385,8 @@ static int __handle_mm_fault(struct mm_s
pmd_t *pmd;
pte_t *pte;
@@ -274,13 +287,3 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return VM_FAULT_SIGSEGV;
if (unlikely(is_vm_hugetlb_page(vma)))
---- a/drivers/iommu/amd_iommu_v2.c
-+++ b/drivers/iommu/amd_iommu_v2.c
-@@ -526,6 +526,7 @@ static void do_fault(struct work_struct
- flags |= FAULT_FLAG_USER;
- if (fault->flags & PPR_FAULT_WRITE)
- flags |= FAULT_FLAG_WRITE;
-+ flags |= FAULT_FLAG_REMOTE;
-
- down_read(&mm->mmap_sem);
- vma = find_extend_vma(mm, address);
diff --git a/patches.arch/02-x86-KVM-VMX-Add-module-argument-for-L1TF-mitigation.patch b/patches.arch/02-x86-KVM-VMX-Add-module-argument-for-L1TF-mitigation.patch
index a9231d5bd9..aedccaef1a 100644
--- a/patches.arch/02-x86-KVM-VMX-Add-module-argument-for-L1TF-mitigation.patch
+++ b/patches.arch/02-x86-KVM-VMX-Add-module-argument-for-L1TF-mitigation.patch
@@ -27,9 +27,30 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
arch/x86/kvm/vmx.c | 65 ++++++++++++++++++++++++++++++++++--
2 files changed, 75 insertions(+), 2 deletions(-)
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1887,6 +1887,18 @@ bytes respectively. Such letter suffixes
+ (virtualized real and unpaged mode) on capable
+ Intel chips. Default is 1 (enabled)
+
++ kvm-intel.vmentry_l1d_flush=[KVM,Intel] Mitigation for L1 Terminal Fault
++ CVE-2018-3620.
++
++ Valid arguments: never, cond, always
++
++ always: L1D cache flush on every VMENTER.
++ cond: Flush L1D on VMENTER only when the code between
++ VMEXIT and VMENTER can leak host memory.
++ never: Disables the mitigation
++
++ Default is cond (do L1 cache flush in specific instances)
++
+ kvm-intel.vpid= [KVM,Intel] Disable Virtual Processor Identification
+ feature (tagged TLBs) on capable Intel chips.
+ Default is 1 (enabled)
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -176,6 +176,54 @@ module_param(ple_window_max, int, S_IRUG
+@@ -184,6 +184,54 @@ module_param(ple_window_max, int, S_IRUG
extern const ulong vmx_return;
@@ -82,9 +103,9 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+module_param_cb(vmentry_l1d_flush, &vmentry_l1d_flush_ops, &vmentry_l1d_flush, S_IRUGO);
+
#define NR_AUTOLOAD_MSRS 8
- #define VMCS02_POOL_SIZE 1
-@@ -11042,10 +11090,23 @@ static struct kvm_x86_ops vmx_x86_ops =
+ struct vmcs {
+@@ -11116,10 +11164,23 @@ static struct kvm_x86_ops vmx_x86_ops =
.setup_mce = vmx_setup_mce,
};
@@ -110,24 +131,3 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
if (r)
return r;
---- a/Documentation/kernel-parameters.txt
-+++ b/Documentation/kernel-parameters.txt
-@@ -1889,6 +1889,18 @@ bytes respectively. Such letter suffixes
- (virtualized real and unpaged mode) on capable
- Intel chips. Default is 1 (enabled)
-
-+ kvm-intel.vmentry_l1d_flush=[KVM,Intel] Mitigation for L1 Terminal Fault
-+ CVE-2018-3620.
-+
-+ Valid arguments: never, cond, always
-+
-+ always: L1D cache flush on every VMENTER.
-+ cond: Flush L1D on VMENTER only when the code between
-+ VMEXIT and VMENTER can leak host memory.
-+ never: Disables the mitigation
-+
-+ Default is cond (do L1 cache flush in specific instances)
-+
- kvm-intel.vpid= [KVM,Intel] Disable Virtual Processor Identification
- feature (tagged TLBs) on capable Intel chips.
- Default is 1 (enabled)
diff --git a/patches.arch/05-x86-KVM-VMX-Add-L1D-flush-logic.patch b/patches.arch/05-x86-KVM-VMX-Add-L1D-flush-logic.patch
index a8741878ee..c670ae94d7 100644
--- a/patches.arch/05-x86-KVM-VMX-Add-L1D-flush-logic.patch
+++ b/patches.arch/05-x86-KVM-VMX-Add-L1D-flush-logic.patch
@@ -42,13 +42,13 @@ Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
---
arch/x86/include/asm/kvm_host.h | 4 ++++
- arch/x86/kvm/vmx.c | 22 +++++++++++++++++++++-
+ arch/x86/kvm/vmx.c | 21 ++++++++++++++++++++-
arch/x86/kvm/x86.c | 7 +++++++
- 3 files changed, 32 insertions(+), 1 deletion(-)
+ 3 files changed, 31 insertions(+), 1 deletion(-)
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
-@@ -614,6 +614,9 @@ struct kvm_vcpu_arch {
+@@ -609,6 +609,9 @@ struct kvm_vcpu_arch {
int pending_ioapic_eoi;
int pending_external_vector;
@@ -58,7 +58,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
};
struct kvm_lpage_info {
-@@ -769,6 +772,7 @@ struct kvm_vcpu_stat {
+@@ -764,6 +767,7 @@ struct kvm_vcpu_stat {
u32 signal_exits;
u32 irq_window_exits;
u32 nmi_window_exits;
@@ -68,7 +68,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
u32 halt_attempted_poll;
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -8273,9 +8273,20 @@ static int vmx_handle_exit(struct kvm_vc
+@@ -8293,9 +8293,20 @@ static int vmx_handle_exit(struct kvm_vc
#define L1D_CACHE_ORDER 4
static void *vmx_l1d_flush_pages;
@@ -90,11 +90,10 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
if (static_cpu_has(X86_FEATURE_FLUSH_L1D)) {
wrmsrl(MSR_IA32_FLUSH_CMD, L1D_FLUSH);
-@@ -8736,6 +8747,12 @@ static void __noclone vmx_vcpu_run(struc
- x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0);
+@@ -8762,6 +8773,11 @@ static void __noclone vmx_vcpu_run(struc
vmx->__launched = vmx->loaded_vmcs->launched;
-+
+
+ if (static_branch_unlikely(&vmx_l1d_should_flush)) {
+ if (vcpu->arch.l1tf_flush_l1d)
+ vmx_l1d_flush(vcpu);
@@ -103,7 +102,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
asm(
/* Store host registers */
"push %%" _ASM_DX "; push %%" _ASM_BP ";"
-@@ -10150,6 +10167,9 @@ static int nested_vmx_run(struct kvm_vcp
+@@ -10227,6 +10243,9 @@ static int nested_vmx_run(struct kvm_vcp
}
}
@@ -115,7 +114,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
* the nested entry.
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -4351,6 +4351,9 @@ static int kvm_write_guest_virt_helper(g
+@@ -4349,6 +4349,9 @@ static int kvm_write_guest_virt_helper(g
void *data = val;
int r = X86EMUL_CONTINUE;
@@ -125,7 +124,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
while (bytes) {
gpa_t gpa = vcpu->arch.walk_mmu->gva_to_gpa(vcpu, addr,
access,
-@@ -5483,6 +5486,8 @@ int x86_emulate_instruction(struct kvm_v
+@@ -5477,6 +5480,8 @@ int x86_emulate_instruction(struct kvm_v
bool writeback = true;
bool write_fault_to_spt = vcpu->arch.write_fault_to_shadow_pgtable;
@@ -134,7 +133,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
/*
* Clear write_fault_to_shadow_pgtable here to ensure it is
* never reused.
-@@ -6828,6 +6833,7 @@ static int vcpu_run(struct kvm_vcpu *vcp
+@@ -6833,6 +6838,7 @@ static int vcpu_run(struct kvm_vcpu *vcp
struct kvm *kvm = vcpu->kvm;
vcpu->srcu_idx = srcu_read_lock(&kvm->srcu);
@@ -142,7 +141,7 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
for (;;) {
if (kvm_vcpu_running(vcpu)) {
-@@ -7790,6 +7796,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcp
+@@ -7795,6 +7801,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcp
void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu)
{
diff --git a/patches.arch/47-kvm-svm-implement-virt_spec_ctrl-support-for-ssbd.patch b/patches.arch/47-kvm-svm-implement-virt_spec_ctrl-support-for-ssbd.patch
deleted file mode 100644
index 1017d3242a..0000000000
--- a/patches.arch/47-kvm-svm-implement-virt_spec_ctrl-support-for-ssbd.patch
+++ /dev/null
@@ -1,192 +0,0 @@
-From: Tom Lendacky <thomas.lendacky@amd.com>
-Date: Thu, 10 May 2018 22:06:39 +0200
-Subject: KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD
-Git-commit: bc226f07dcd3c9ef0b7f6236fe356ea4a9cb4769
-Patch-mainline: v4.17-rc7
-References: bsc#1087082 CVE-2018-3639
-
-Expose the new virtualized architectural mechanism, VIRT_SSBD, for using
-speculative store bypass disable (SSBD) under SVM. This will allow guests
-to use SSBD on hardware that uses non-architectural mechanisms for enabling
-SSBD.
-
-[ tglx: Folded the migration fixup from Paolo Bonzini ]
-
-Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Acked-by: Borislav Petkov <bp@suse.de>
----
- arch/x86/include/asm/kvm_host.h | 2 +-
- arch/x86/kernel/cpu/common.c | 3 ++-
- arch/x86/kvm/cpuid.c | 2 +-
- arch/x86/kvm/svm.c | 31 +++++++++++++++++++++++++++++--
- arch/x86/kvm/vmx.c | 18 +++++++++++++++---
- arch/x86/kvm/x86.c | 13 ++++---------
- 6 files changed, 52 insertions(+), 17 deletions(-)
-
---- a/arch/x86/include/asm/kvm_host.h
-+++ b/arch/x86/include/asm/kvm_host.h
-@@ -813,7 +813,7 @@ struct kvm_x86_ops {
- int (*hardware_setup)(void); /* __init */
- void (*hardware_unsetup)(void); /* __exit */
- bool (*cpu_has_accelerated_tpr)(void);
-- bool (*cpu_has_high_real_mode_segbase)(void);
-+ bool (*has_emulated_msr)(int index);
- void (*cpuid_update)(struct kvm_vcpu *vcpu);
-
- int (*vm_init)(struct kvm *kvm);
---- a/arch/x86/kernel/cpu/common.c
-+++ b/arch/x86/kernel/cpu/common.c
-@@ -746,7 +746,8 @@ static void init_speculation_control(str
- if (cpu_has(c, X86_FEATURE_INTEL_STIBP))
- set_cpu_cap(c, X86_FEATURE_STIBP);
-
-- if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD))
-+ if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD) ||
-+ cpu_has(c, X86_FEATURE_VIRT_SSBD))
- set_cpu_cap(c, X86_FEATURE_SSBD);
-
- if (cpu_has(c, X86_FEATURE_AMD_IBRS)) {
---- a/arch/x86/kvm/cpuid.c
-+++ b/arch/x86/kvm/cpuid.c
-@@ -386,7 +386,7 @@ static inline int __do_cpuid_ent(struct
-
- /* cpuid 0x80000008.0.ebx */
- const u32 kvm_cpuid_80000008_0_ebx_x86_features =
-- F(IBPB);
-+ F(IBPB) | F(AMD_IBRS) | F(VIRT_SSBD);
-
- /* all calls to cpuid_count() should be made on the same cpu */
- get_cpu();
---- a/arch/x86/kvm/svm.c
-+++ b/arch/x86/kvm/svm.c
-@@ -3529,6 +3529,18 @@ static int svm_get_msr(struct kvm_vcpu *
- case MSR_IA32_SPEC_CTRL:
- msr_info->data = svm->spec_ctrl;
- break;
-+ case MSR_AMD64_VIRT_SPEC_CTRL:
-+ if (!msr_info->host_initiated)
-+ /*
-+ * !guest_cpuid_has(vcpu, X86_FEATURE_VIRT_SSBD))
-+ *
-+ * this would need backporting the whole
-+ * guest_cpuid_has() fun.
-+ */
-+ return 1;
-+
-+ msr_info->data = svm->virt_spec_ctrl;
-+ break;
- case MSR_IA32_UCODE_REV:
- msr_info->data = 0x01000065;
- break;
-@@ -3603,6 +3615,21 @@ static int svm_set_msr(struct kvm_vcpu *
- case MSR_IA32_TSC:
- kvm_write_tsc(vcpu, msr);
- break;
-+ case MSR_AMD64_VIRT_SPEC_CTRL:
-+ if (!msr->host_initiated)
-+ /*
-+ * !guest_cpuid_has(vcpu, X86_FEATURE_VIRT_SSBD))
-+ *
-+ * this would need backporting the whole
-+ * guest_cpuid_has() fun.
-+ */
-+ return 1;
-+
-+ if (data & ~SPEC_CTRL_SSBD)
-+ return 1;
-+
-+ svm->virt_spec_ctrl = data;
-+ break;
- case MSR_STAR:
- svm->vmcb->save.star = data;
- break;
-@@ -5040,7 +5067,7 @@ static bool svm_cpu_has_accelerated_tpr(
- return false;
- }
-
--static bool svm_has_high_real_mode_segbase(void)
-+static bool svm_has_emulated_msr(int index)
- {
- return true;
- }
-@@ -5338,7 +5365,7 @@ static struct kvm_x86_ops svm_x86_ops =
- .hardware_enable = svm_hardware_enable,
- .hardware_disable = svm_hardware_disable,
- .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr,
-- .cpu_has_high_real_mode_segbase = svm_has_high_real_mode_segbase,
-+ .has_emulated_msr = svm_has_emulated_msr,
-
- .vcpu_create = svm_create_vcpu,
- .vcpu_free = svm_free_vcpu,
---- a/arch/x86/kvm/vmx.c
-+++ b/arch/x86/kvm/vmx.c
-@@ -8425,9 +8425,21 @@ static void vmx_handle_external_intr(str
- local_irq_enable();
- }
-
--static bool vmx_has_high_real_mode_segbase(void)
-+static bool vmx_has_emulated_msr(int index)
- {
-- return enable_unrestricted_guest || emulate_invalid_guest_state;
-+ switch (index) {
-+ case MSR_IA32_SMBASE:
-+ /*
-+ * We cannot do SMM unless we can run the guest in big
-+ * real mode.
-+ */
-+ return enable_unrestricted_guest || emulate_invalid_guest_state;
-+ case MSR_AMD64_VIRT_SPEC_CTRL:
-+ /* This is AMD only. */
-+ return false;
-+ default:
-+ return true;
-+ }
- }
-
- static bool vmx_mpx_supported(void)
-@@ -10891,7 +10903,7 @@ static struct kvm_x86_ops vmx_x86_ops =
- .hardware_enable = hardware_enable,
- .hardware_disable = hardware_disable,
- .cpu_has_accelerated_tpr = report_flexpriority,
-- .cpu_has_high_real_mode_segbase = vmx_has_high_real_mode_segbase,
-+ .has_emulated_msr = vmx_has_emulated_msr,
-
- .vcpu_create = vmx_create_vcpu,
- .vcpu_free = vmx_free_vcpu,
---- a/arch/x86/kvm/x86.c
-+++ b/arch/x86/kvm/x86.c
-@@ -997,6 +997,7 @@ static u32 emulated_msrs[] = {
- MSR_IA32_MCG_CTL,
- MSR_IA32_MCG_EXT_CTL,
- MSR_IA32_SMBASE,
-+ MSR_AMD64_VIRT_SPEC_CTRL,
- };
-
- static unsigned num_emulated_msrs;
-@@ -2600,7 +2601,7 @@ int kvm_vm_ioctl_check_extension(struct
- * fringe case that is not enabled except via specific settings
- * of the module parameters.
- */
-- r = kvm_x86_ops->cpu_has_high_real_mode_segbase();
-+ r = kvm_x86_ops->has_emulated_msr(MSR_IA32_SMBASE);
- break;
- case KVM_CAP_VAPIC:
- r = !kvm_x86_ops->cpu_has_accelerated_tpr();
-@@ -4143,14 +4144,8 @@ static void kvm_init_msr_list(void)
- num_msrs_to_save = j;
-
- for (i = j = 0; i < ARRAY_SIZE(emulated_msrs); i++) {
-- switch (emulated_msrs[i]) {
-- case MSR_IA32_SMBASE:
-- if (!kvm_x86_ops->cpu_has_high_real_mode_segbase())
-- continue;
-- break;
-- default:
-- break;
-- }
-+ if (!kvm_x86_ops->has_emulated_msr(emulated_msrs[i]))
-+ continue;
-
- if (j < i)
- emulated_msrs[j] = emulated_msrs[i];
diff --git a/patches.arch/arm64-bsc1031492-0023-kvm-make-KVM_CAP_COALESCED_MMIO-architecture-agnosti.patch b/patches.arch/arm64-bsc1031492-0023-kvm-make-KVM_CAP_COALESCED_MMIO-architecture-agnosti.patch
index 371eb1f268..9ff0c7b8aa 100644
--- a/patches.arch/arm64-bsc1031492-0023-kvm-make-KVM_CAP_COALESCED_MMIO-architecture-agnosti.patch
+++ b/patches.arch/arm64-bsc1031492-0023-kvm-make-KVM_CAP_COALESCED_MMIO-architecture-agnosti.patch
@@ -23,18 +23,16 @@ Signed-off-by: Alexander Graf <agraf@suse.de>
Conflicts: arch/mips/kvm/mips.c
---
- arch/arm/kvm/arm.c | 3 ---
- arch/mips/kvm/mips.c | 3 ---
- arch/powerpc/kvm/powerpc.c | 5 -----
- arch/x86/kvm/x86.c | 3 ---
- virt/kvm/kvm_main.c | 4 ++++
+ arch/arm/kvm/arm.c | 3 ---
+ arch/mips/kvm/mips.c | 3 ---
+ arch/powerpc/kvm/powerpc.c | 5 -----
+ arch/x86/kvm/x86.c | 3 ---
+ virt/kvm/kvm_main.c | 4 ++++
5 files changed, 4 insertions(+), 14 deletions(-)
-diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
-index 83e7263..e20a5f7 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
-@@ -208,9 +208,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+@@ -208,9 +208,6 @@ int kvm_vm_ioctl_check_extension(struct
case KVM_CAP_MP_STATE:
r = 1;
break;
@@ -44,11 +42,9 @@ index 83e7263..e20a5f7 100644
case KVM_CAP_ARM_SET_DEVICE_ADDR:
r = 1;
break;
-diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
-index c51c837..8bb89f5 100644
--- a/arch/mips/kvm/mips.c
+++ b/arch/mips/kvm/mips.c
-@@ -1094,9 +1094,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+@@ -1094,9 +1094,6 @@ int kvm_vm_ioctl_check_extension(struct
case KVM_CAP_ENABLE_CAP:
r = 1;
break;
@@ -58,11 +54,9 @@ index c51c837..8bb89f5 100644
case KVM_CAP_MIPS_FPU:
r = !!cpu_has_fpu;
break;
-diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c
-index 652daa5..6a29fce 100644
--- a/arch/powerpc/kvm/powerpc.c
+++ b/arch/powerpc/kvm/powerpc.c
-@@ -506,11 +506,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+@@ -506,11 +506,6 @@ int kvm_vm_ioctl_check_extension(struct
/* We support this only for PR */
r = !hv_enabled;
break;
@@ -74,13 +68,11 @@ index 652daa5..6a29fce 100644
#ifdef CONFIG_KVM_MPIC
case KVM_CAP_IRQ_MPIC:
r = 1;
-diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index 58f86b9..c08b2ac 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -2597,9 +2597,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+@@ -2601,9 +2601,6 @@ int kvm_vm_ioctl_check_extension(struct
*/
- r = kvm_x86_ops->cpu_has_high_real_mode_segbase();
+ r = kvm_x86_ops->has_emulated_msr(MSR_IA32_SMBASE);
break;
- case KVM_CAP_COALESCED_MMIO:
- r = KVM_COALESCED_MMIO_PAGE_OFFSET;
@@ -88,11 +80,9 @@ index 58f86b9..c08b2ac 100644
case KVM_CAP_VAPIC:
r = !kvm_x86_ops->cpu_has_accelerated_tpr();
break;
-diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
-index d6c6e02..420b33d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
-@@ -2813,6 +2813,10 @@ static long kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg)
+@@ -2812,6 +2812,10 @@ static long kvm_vm_ioctl_check_extension
case KVM_CAP_IOEVENTFD_ANY_LENGTH:
case KVM_CAP_CHECK_EXTENSION_VM:
return 1;
@@ -103,6 +93,3 @@ index d6c6e02..420b33d 100644
#ifdef CONFIG_HAVE_KVM_IRQ_ROUTING
case KVM_CAP_IRQ_ROUTING:
return KVM_MAX_IRQ_ROUTES;
---
-1.8.5.6
-
diff --git a/patches.arch/kvm-nVMX-fix-nested-tsc-scaling.patch b/patches.arch/kvm-nVMX-fix-nested-tsc-scaling.patch
index 5749831fc4..0c34aaebd6 100644
--- a/patches.arch/kvm-nVMX-fix-nested-tsc-scaling.patch
+++ b/patches.arch/kvm-nVMX-fix-nested-tsc-scaling.patch
@@ -15,14 +15,12 @@ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Lin Ma <lma@suse.com>
---
- arch/x86/kvm/vmx.c | 16 ++++++++++++----
+ arch/x86/kvm/vmx.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
-diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
-index ae111a07acc4..5cede40e2552 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -2065,6 +2065,12 @@
+@@ -2120,6 +2120,12 @@ static void vmx_vcpu_pi_load(struct kvm_
new.control) != old.control);
}
@@ -35,7 +33,7 @@ index ae111a07acc4..5cede40e2552 100644
/*
* Switches to specified vcpu, until a matching vcpu_put(), but assumes
* vcpu mutex is already taken.
-@@ -2121,10 +2127,8 @@
+@@ -2175,10 +2181,8 @@ static void vmx_vcpu_load(struct kvm_vcp
/* Setup TSC multiplier */
if (kvm_has_tsc_control &&
@@ -48,16 +46,16 @@ index ae111a07acc4..5cede40e2552 100644
vmx_vcpu_pi_load(vcpu, cpu);
vmx->host_pkru = read_pkru();
-@@ -9846,6 +9850,8 @@
+@@ -9945,6 +9949,8 @@ static void prepare_vmcs02(struct kvm_vc
vmx->nested.vmcs01_tsc_offset + vmcs12->tsc_offset);
else
vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
+ if (kvm_has_tsc_control)
+ decache_tsc_multiplier(vmx);
- if (enable_vpid) {
- /*
-@@ -10611,6 +10617,8 @@
+ if (cpu_has_vmx_msr_bitmap())
+ vmcs_write64(MSR_BITMAP, __pa(vmx->nested.vmcs02.msr_bitmap));
+@@ -10704,6 +10710,8 @@ static void nested_vmx_vmexit(struct kvm
/* Update TSC_OFFSET if TSC was changed while L2 ran */
vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
@@ -66,5 +64,3 @@ index ae111a07acc4..5cede40e2552 100644
if (vmx->nested.change_vmcs01_virtual_x2apic_mode) {
vmx->nested.change_vmcs01_virtual_x2apic_mode = false;
---
-2.16.2
diff --git a/patches.arch/kvm-svm-add-support-for-rdtscp.patch b/patches.arch/kvm-svm-add-support-for-rdtscp.patch
index 86553524bc..8665298f08 100644
--- a/patches.arch/kvm-svm-add-support-for-rdtscp.patch
+++ b/patches.arch/kvm-svm-add-support-for-rdtscp.patch
@@ -14,14 +14,12 @@ Cc: Joerg Roedel <joro@8bytes.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
- arch/x86/kvm/svm.c | 24 +++++++++++++++++++++++-
+ arch/x86/kvm/svm.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
-diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
-index 59f8113e8808..430a22021493 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
-@@ -120,6 +120,7 @@ static const u32 host_save_user_msrs[] = {
+@@ -88,6 +88,7 @@ static const u32 host_save_user_msrs[] =
MSR_FS_BASE,
#endif
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
@@ -29,7 +27,7 @@ index 59f8113e8808..430a22021493 100644
};
#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
-@@ -169,6 +170,7 @@ struct vcpu_svm {
+@@ -137,6 +138,7 @@ struct vcpu_svm {
uint64_t asid_generation;
uint64_t sysenter_esp;
uint64_t sysenter_eip;
@@ -37,17 +35,17 @@ index 59f8113e8808..430a22021493 100644
u64 next_rip;
-@@ -1689,6 +1691,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+@@ -1279,6 +1281,9 @@ static void svm_vcpu_load(struct kvm_vcp
wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
}
}
+ /* This assumes that the kernel never uses MSR_TSC_AUX */
+ if (static_cpu_has(X86_FEATURE_RDTSCP))
+ wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
- }
-
- static void svm_vcpu_put(struct kvm_vcpu *vcpu)
-@@ -3495,6 +3500,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ if (sd->current_vmcb != svm->vmcb) {
+ sd->current_vmcb = svm->vmcb;
+ indirect_branch_prediction_barrier();
+@@ -3069,6 +3074,11 @@ static int svm_get_msr(struct kvm_vcpu *
case MSR_IA32_SYSENTER_ESP:
msr_info->data = svm->sysenter_esp;
break;
@@ -59,7 +57,7 @@ index 59f8113e8808..430a22021493 100644
/*
* Nobody will change the following 5 values in the VMCB so we can
* safely return them on rdmsr. They will always be 0 until LBRV is
-@@ -3616,6 +3626,18 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
+@@ -3264,6 +3274,18 @@ static int svm_set_msr(struct kvm_vcpu *
svm->sysenter_esp = data;
svm->vmcb->save.sysenter_esp = data;
break;
@@ -78,7 +76,7 @@ index 59f8113e8808..430a22021493 100644
case MSR_IA32_DEBUGCTLMSR:
if (!boot_cpu_has(X86_FEATURE_LBRV)) {
vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
-@@ -5049,7 +5071,7 @@ static int svm_get_lpage_level(void)
+@@ -4210,7 +4232,7 @@ static int svm_get_lpage_level(void)
static bool svm_rdtscp_supported(void)
{
@@ -87,4 +85,3 @@ index 59f8113e8808..430a22021493 100644
}
static bool svm_invpcid_supported(void)
-
diff --git a/patches.arch/kvm-vmx-enable-guest-access-to-lmce-related-msrs.patch b/patches.arch/kvm-vmx-enable-guest-access-to-lmce-related-msrs.patch
index ed88551f6e..a30c838999 100644
--- a/patches.arch/kvm-vmx-enable-guest-access-to-lmce-related-msrs.patch
+++ b/patches.arch/kvm-vmx-enable-guest-access-to-lmce-related-msrs.patch
@@ -17,16 +17,14 @@ Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
- arch/x86/include/asm/kvm_host.h | 5 +++++
- arch/x86/kvm/vmx.c | 29 +++++++++++++++++++++++++++++
- arch/x86/kvm/x86.c | 15 +++++++++------
+ arch/x86/include/asm/kvm_host.h | 5 +++++
+ arch/x86/kvm/vmx.c | 29 +++++++++++++++++++++++++++++
+ arch/x86/kvm/x86.c | 15 +++++++++------
3 files changed, 43 insertions(+), 6 deletions(-)
-diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
-index d877754deee3..5a6e6fe27b75 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
-@@ -538,6 +538,7 @@ struct kvm_vcpu_arch {
+@@ -549,6 +549,7 @@ struct kvm_vcpu_arch {
u64 mcg_cap;
u64 mcg_status;
u64 mcg_ctl;
@@ -34,7 +32,7 @@ index d877754deee3..5a6e6fe27b75 100644
u64 *mce_banks;
/* Cache MMIO info */
-@@ -941,6 +942,8 @@ struct kvm_x86_ops {
+@@ -952,6 +953,8 @@ struct kvm_x86_ops {
int (*update_pi_irte)(struct kvm *kvm, unsigned int host_irq,
uint32_t guest_irq, bool set);
void (*apicv_post_state_restore)(struct kvm_vcpu *vcpu);
@@ -43,7 +41,7 @@ index d877754deee3..5a6e6fe27b75 100644
};
struct kvm_arch_async_pf {
-@@ -1011,6 +1014,8 @@ extern u8 kvm_tsc_scaling_ratio_frac_bits;
+@@ -1022,6 +1025,8 @@ extern u8 kvm_tsc_scaling_ratio_frac_b
/* maximum allowed value of TSC scaling ratio */
extern u64 kvm_max_tsc_scaling_ratio;
@@ -52,11 +50,9 @@ index d877754deee3..5a6e6fe27b75 100644
enum emulation_result {
EMULATE_DONE, /* no further processing */
EMULATE_USER_EXIT, /* kvm_run ready for userspace exit */
-diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
-index 6d14769a4179..a1a81e5b6ae9 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -2844,6 +2844,13 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+@@ -2914,6 +2914,13 @@ static int vmx_get_msr(struct kvm_vcpu *
return 1;
msr_info->data = vmcs_read64(GUEST_BNDCFGS);
break;
@@ -70,7 +66,7 @@ index 6d14769a4179..a1a81e5b6ae9 100644
case MSR_IA32_FEATURE_CONTROL:
msr_info->data = to_vmx(vcpu)->msr_ia32_feature_control;
break;
-@@ -2935,6 +2942,14 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+@@ -3071,6 +3078,14 @@ static int vmx_set_msr(struct kvm_vcpu *
case MSR_IA32_TSC_ADJUST:
ret = kvm_set_msr_common(vcpu, msr_info);
break;
@@ -85,7 +81,7 @@ index 6d14769a4179..a1a81e5b6ae9 100644
case MSR_IA32_FEATURE_CONTROL:
if (!vmx_feature_control_msr_valid(vcpu, data) ||
(to_vmx(vcpu)->msr_ia32_feature_control &
-@@ -6330,6 +6345,8 @@ static __init int hardware_setup(void)
+@@ -6499,6 +6514,8 @@ static __init int hardware_setup(void)
kvm_set_posted_intr_wakeup_handler(wakeup_handler);
@@ -93,8 +89,8 @@ index 6d14769a4179..a1a81e5b6ae9 100644
+
return alloc_kvm_area();
- out8:
-@@ -10848,6 +10865,16 @@ out:
+ out3:
+@@ -11005,6 +11022,16 @@ out:
return ret;
}
@@ -111,7 +107,7 @@ index 6d14769a4179..a1a81e5b6ae9 100644
static struct kvm_x86_ops vmx_x86_ops = {
.cpu_has_kvm_support = cpu_has_kvm_support,
.disabled_by_bios = vmx_disabled_by_bios,
-@@ -10972,6 +10999,8 @@ static struct kvm_x86_ops vmx_x86_ops = {
+@@ -11129,6 +11156,8 @@ static struct kvm_x86_ops vmx_x86_ops =
.pmu_ops = &intel_pmu_ops,
.update_pi_irte = vmx_update_pi_irte,
@@ -120,8 +116,6 @@ index 6d14769a4179..a1a81e5b6ae9 100644
};
static int __init vmx_init(void)
-diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index acaa462034fb..5f1d9fe99a37 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -70,7 +70,8 @@
@@ -134,15 +128,15 @@ index acaa462034fb..5f1d9fe99a37 100644
#define emul_to_vcpu(ctxt) \
container_of(ctxt, struct kvm_vcpu, arch.emulate_ctxt)
-@@ -985,6 +986,7 @@ static u32 emulated_msrs[] = {
+@@ -992,6 +993,7 @@ static u32 emulated_msrs[] = {
MSR_IA32_MISC_ENABLE,
MSR_IA32_MCG_STATUS,
MSR_IA32_MCG_CTL,
+ MSR_IA32_MCG_EXT_CTL,
MSR_IA32_SMBASE,
+ MSR_AMD64_VIRT_SPEC_CTRL,
};
-
-@@ -2678,11 +2680,9 @@ long kvm_arch_dev_ioctl(struct file *filp,
+@@ -2690,11 +2692,9 @@ long kvm_arch_dev_ioctl(struct file *fil
break;
}
case KVM_X86_GET_MCE_CAP_SUPPORTED: {
@@ -156,7 +150,7 @@ index acaa462034fb..5f1d9fe99a37 100644
goto out;
r = 0;
break;
-@@ -2855,7 +2855,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
+@@ -2873,7 +2873,7 @@ static int kvm_vcpu_ioctl_x86_setup_mce(
r = -EINVAL;
if (!bank_num || bank_num >= KVM_MAX_MCE_BANKS)
goto out;
@@ -165,7 +159,7 @@ index acaa462034fb..5f1d9fe99a37 100644
goto out;
r = 0;
vcpu->arch.mcg_cap = mcg_cap;
-@@ -2865,6 +2865,9 @@ static int kvm_vcpu_ioctl_x86_setup_mce(struct kvm_vcpu *vcpu,
+@@ -2883,6 +2883,9 @@ static int kvm_vcpu_ioctl_x86_setup_mce(
/* Init IA32_MCi_CTL to all 1s */
for (bank = 0; bank < bank_num; bank++)
vcpu->arch.mce_banks[bank*4] = ~(u64)0;
@@ -175,4 +169,3 @@ index acaa462034fb..5f1d9fe99a37 100644
out:
return r;
}
-
diff --git a/patches.arch/kvm-vmx-optimize-apic-id-read-with-apicv.patch b/patches.arch/kvm-vmx-optimize-apic-id-read-with-apicv.patch
index 7b2abf3925..7265cbefa3 100644
--- a/patches.arch/kvm-vmx-optimize-apic-id-read-with-apicv.patch
+++ b/patches.arch/kvm-vmx-optimize-apic-id-read-with-apicv.patch
@@ -16,24 +16,16 @@ Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Bruce Rogers <brogers@suse.com>
---
- arch/x86/kvm/vmx.c | 4 ----
- 1 file changed, 4 deletions(-)
+ arch/x86/kvm/vmx.c | 1 -
+ 1 file changed, 1 deletion(-)
-diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
-index 437beface2bd..37aff43d0cbf 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -6303,10 +6303,6 @@ static __init int hardware_setup(void)
- for (msr = 0x800; msr <= 0x8ff; msr++)
- vmx_disable_intercept_msr_read_x2apic(msr);
-
-- /* According SDM, in x2apic mode, the whole id reg is used.
-- * But in KVM, it only use the highest eight bits. Need to
-- * intercept it */
-- vmx_enable_intercept_msr_read_x2apic(0x802);
- /* TMCCT */
- vmx_enable_intercept_msr_read_x2apic(0x839);
- /* TPR */
---
-2.12.2
-
+@@ -4704,7 +4704,6 @@ static void vmx_update_msr_bitmap_x2apic
+ */
+ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TASKPRI), MSR_TYPE_RW);
+ if (mode & MSR_BITMAP_MODE_X2APIC_APICV) {
+- vmx_enable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_ID), MSR_TYPE_R);
+ vmx_enable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TMCCT), MSR_TYPE_R);
+ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_EOI), MSR_TYPE_W);
+ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_SELF_IPI), MSR_TYPE_W);
diff --git a/patches.arch/kvm-x86-add-avx512_4vnniw-and-avx512_4fmaps-support.patch b/patches.arch/kvm-x86-add-avx512_4vnniw-and-avx512_4fmaps-support.patch
index cd9f60e404..836d5fe7e5 100644
--- a/patches.arch/kvm-x86-add-avx512_4vnniw-and-avx512_4fmaps-support.patch
+++ b/patches.arch/kvm-x86-add-avx512_4vnniw-and-avx512_4fmaps-support.patch
@@ -23,11 +23,9 @@ Signed-off-by: Luwei Kang <luwei.kang@intel.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
- arch/x86/kvm/cpuid.c | 14 +++++++++++++-
- 1 file changed, 13 insertions(+), 1 deletion(-)
+ arch/x86/kvm/cpuid.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
-diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
-index 33d924ccd165..668b9c26198e 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -16,6 +16,7 @@
@@ -38,43 +36,22 @@ index 33d924ccd165..668b9c26198e 100644
#include <asm/fpu/internal.h> /* For use_eager_fpu. Ugh! */
#include <asm/user.h>
#include <asm/fpu/xstate.h>
-@@ -58,6 +59,11 @@ u64 kvm_supported_xcr0(void)
-
+@@ -66,6 +67,8 @@ u64 kvm_supported_xcr0(void)
#define F(x) bit(X86_FEATURE_##x)
-+/* These are scattered features in cpufeatures.h. */
+ /* These are scattered features in cpufeatures.h. */
+#define KVM_CPUID_BIT_AVX512_4VNNIW 2
+#define KVM_CPUID_BIT_AVX512_4FMAPS 3
-+#define KF(x) bit(KVM_CPUID_BIT_##x)
-+
- int kvm_update_cpuid(struct kvm_vcpu *vcpu)
- {
- struct kvm_cpuid_entry2 *best;
-@@ -368,6 +374,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
- /* cpuid 7.0.ecx*/
- const u32 kvm_cpuid_7_0_ecx_x86_features = F(PKU) | 0 /*OSPKE*/;
+ #define KVM_CPUID_BIT_SPEC_CTRL 26
+ #define KVM_CPUID_BIT_ARCH_CAPABILITIES 29
+ #define KVM_CPUID_BIT_SPEC_CTRL_SSBD 31
+@@ -387,7 +390,8 @@ static inline int __do_cpuid_ent(struct
+
+ /* cpuid 7.0.edx*/
+ const u32 kvm_cpuid_7_0_edx_x86_features =
+- KF(SPEC_CTRL) | KF(SPEC_CTRL_SSBD) | KF(ARCH_CAPABILITIES);
++ KF(AVX512_4VNNIW) | KF(AVX512_4FMAPS) | KF(SPEC_CTRL) |
++ KF(SPEC_CTRL_SSBD) | KF(ARCH_CAPABILITIES);
-+ /* cpuid 7.0.edx*/
-+ const u32 kvm_cpuid_7_0_edx_x86_features =
-+ KF(AVX512_4VNNIW) | KF(AVX512_4FMAPS);
-+
/* all calls to cpuid_count() should be made on the same cpu */
get_cpu();
-
-@@ -450,12 +460,14 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
- /* PKU is not yet implemented for shadow paging. */
- if (!tdp_enabled)
- entry->ecx &= ~F(PKU);
-+ entry->edx &= kvm_cpuid_7_0_edx_x86_features;
-+ entry->edx &= get_scattered_cpuid_leaf(7, 0, CPUID_EDX);
- } else {
- entry->ebx = 0;
- entry->ecx = 0;
-+ entry->edx = 0;
- }
- entry->eax = 0;
-- entry->edx = 0;
- break;
- }
- case 9:
-
diff --git a/patches.arch/kvm-x86-per-vcpu-apicv-deactivation-support b/patches.arch/kvm-x86-per-vcpu-apicv-deactivation-support
index 5421ec0d9c..10906b63de 100644
--- a/patches.arch/kvm-x86-per-vcpu-apicv-deactivation-support
+++ b/patches.arch/kvm-x86-per-vcpu-apicv-deactivation-support
@@ -42,7 +42,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
-@@ -413,6 +413,7 @@ struct kvm_vcpu_arch {
+@@ -400,6 +400,7 @@ struct kvm_vcpu_arch {
u64 efer;
u64 apic_base;
struct kvm_lapic *apic; /* kernel irqchip context */
@@ -50,7 +50,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
DECLARE_BITMAP(ioapic_handled_vectors, 256);
unsigned long apic_attention;
int32_t apic_arb_prio;
-@@ -845,7 +846,8 @@ struct kvm_x86_ops {
+@@ -831,7 +832,8 @@ struct kvm_x86_ops {
void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
void (*enable_irq_window)(struct kvm_vcpu *vcpu);
void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
@@ -60,7 +60,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
void (*hwapic_isr_update)(struct kvm *kvm, int isr);
void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap);
-@@ -1101,6 +1103,8 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kv
+@@ -1087,6 +1089,8 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kv
gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
struct x86_exception *exception);
@@ -82,7 +82,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return kvm_apic_has_interrupt(v) != -1; /* LAPIC */
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
-@@ -379,7 +379,8 @@ static inline int apic_find_highest_irr(
+@@ -387,7 +387,8 @@ static inline int apic_find_highest_irr(
if (!apic->irr_pending)
return -1;
@@ -92,7 +92,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
result = apic_search_irr(apic);
ASSERT(result == -1 || result >= 16);
-@@ -392,7 +393,7 @@ static inline void apic_clear_irr(int ve
+@@ -400,7 +401,7 @@ static inline void apic_clear_irr(int ve
vcpu = apic->vcpu;
@@ -101,7 +101,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
/* try to update RVI */
apic_clear_vector(vec, apic->regs + APIC_IRR);
kvm_make_request(KVM_REQ_EVENT, vcpu);
-@@ -418,7 +419,7 @@ static inline void apic_set_isr(int vec,
+@@ -426,7 +427,7 @@ static inline void apic_set_isr(int vec,
* because the processor can modify ISR under the hood. Instead
* just set SVI.
*/
@@ -110,7 +110,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_x86_ops->hwapic_isr_update(vcpu->kvm, vec);
else {
++apic->isr_count;
-@@ -466,7 +467,7 @@ static inline void apic_clear_isr(int ve
+@@ -474,7 +475,7 @@ static inline void apic_clear_isr(int ve
* on the other hand isr_count and highest_isr_cache are unused
* and must be left alone.
*/
@@ -119,7 +119,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_x86_ops->hwapic_isr_update(vcpu->kvm,
apic_find_highest_isr(apic));
else {
-@@ -854,7 +855,7 @@ static int __apic_accept_irq(struct kvm_
+@@ -860,7 +861,7 @@ static int __apic_accept_irq(struct kvm_
apic_clear_vector(vector, apic->regs + APIC_TMR);
}
@@ -128,7 +128,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_x86_ops->deliver_posted_interrupt(vcpu, vector);
else {
apic_set_irr(vector, apic);
-@@ -1227,7 +1228,7 @@ static bool lapic_timer_int_injected(str
+@@ -1233,7 +1234,7 @@ static bool lapic_timer_int_injected(str
int vec = reg & APIC_VECTOR_MASK;
void *bitmap = apic->regs + APIC_ISR;
@@ -137,7 +137,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
bitmap = apic->regs + APIC_IRR;
if (apic_test_vector(vec, bitmap))
-@@ -1695,8 +1696,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vc
+@@ -1701,8 +1702,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vc
apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
}
@@ -148,7 +148,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
apic->highest_isr_cache = -1;
update_divide_count(apic);
atomic_set(&apic->lapic_timer.pending, 0);
-@@ -1908,15 +1909,15 @@ void kvm_apic_post_state_restore(struct
+@@ -1914,15 +1915,15 @@ void kvm_apic_post_state_restore(struct
update_divide_count(apic);
start_apic_timer(apic);
apic->irr_pending = true;
@@ -169,7 +169,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_rtc_eoi_tracking_restore_one(vcpu);
--- a/arch/x86/kvm/lapic.h
+++ b/arch/x86/kvm/lapic.h
-@@ -147,9 +147,9 @@ static inline int apic_x2apic_mode(struc
+@@ -144,9 +144,9 @@ static inline int apic_x2apic_mode(struc
return apic->vcpu->arch.apic_base & X2APIC_ENABLE;
}
@@ -183,7 +183,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
-@@ -3576,9 +3576,13 @@ static void svm_set_virtual_x2apic_mode(
+@@ -3680,9 +3680,13 @@ static void svm_set_virtual_x2apic_mode(
return;
}
@@ -199,7 +199,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
-@@ -4368,7 +4372,8 @@ static struct kvm_x86_ops svm_x86_ops =
+@@ -4497,7 +4501,8 @@ static struct kvm_x86_ops svm_x86_ops =
.enable_irq_window = enable_irq_window,
.update_cr8_intercept = update_cr8_intercept,
.set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode,
@@ -219,7 +219,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
#include <linux/kvm_host.h>
#include <linux/module.h>
-@@ -881,7 +882,6 @@ static u64 construct_eptp(unsigned long
+@@ -884,7 +885,6 @@ static u64 construct_eptp(unsigned long
static void kvm_cpu_vmxon(u64 addr);
static void kvm_cpu_vmxoff(void);
static bool vmx_xsaves_supported(void);
@@ -227,7 +227,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr);
static void vmx_set_segment(struct kvm_vcpu *vcpu,
struct kvm_segment *var, int seg);
-@@ -889,7 +889,6 @@ static void vmx_get_segment(struct kvm_v
+@@ -892,7 +892,6 @@ static void vmx_get_segment(struct kvm_v
struct kvm_segment *var, int seg);
static bool guest_state_valid(struct kvm_vcpu *vcpu);
static u32 vmx_segment_access_rights(struct kvm_segment *var);
@@ -235,7 +235,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
static int alloc_identity_pagetable(struct kvm *kvm);
-@@ -2548,7 +2547,7 @@ static void nested_vmx_setup_ctls_msrs(s
+@@ -2577,7 +2576,7 @@ static void nested_vmx_setup_ctls_msrs(s
vmx->nested.nested_vmx_pinbased_ctls_high |=
PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR |
PIN_BASED_VMX_PREEMPTION_TIMER;
@@ -244,8 +244,8 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
vmx->nested.nested_vmx_pinbased_ctls_high |=
PIN_BASED_POSTED_INTR;
-@@ -4527,9 +4526,9 @@ static void vmx_disable_intercept_msr_wr
- msr, MSR_TYPE_W);
+@@ -4687,9 +4686,9 @@ static void vmx_update_msr_bitmap(struct
+ vmx->msr_bitmap_mode = mode;
}
-static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu)
@@ -255,8 +255,8 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ return enable_apicv;
}
- static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
-@@ -4656,11 +4655,6 @@ static void vmx_sync_pir_to_irr(struct k
+ static void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu)
+@@ -4837,11 +4836,6 @@ static void vmx_sync_pir_to_irr(struct k
kvm_apic_update_irr(vcpu, vmx->pi_desc.pir);
}
@@ -268,7 +268,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
/*
* Set up the vmcs's constant host-state fields, i.e., host-state fields that
* will not change in the lifetime of the guest.
-@@ -4730,11 +4724,18 @@ static u32 vmx_pin_based_exec_ctrl(struc
+@@ -4911,11 +4905,18 @@ static u32 vmx_pin_based_exec_ctrl(struc
{
u32 pin_based_exec_ctrl = vmcs_config.pin_based_exec_ctrl;
@@ -288,7 +288,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static u32 vmx_exec_control(struct vcpu_vmx *vmx)
{
u32 exec_control = vmcs_config.cpu_based_exec_ctrl;
-@@ -4773,7 +4774,7 @@ static u32 vmx_secondary_exec_control(st
+@@ -4954,7 +4955,7 @@ static u32 vmx_secondary_exec_control(st
exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
if (!ple_gap)
exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
@@ -297,7 +297,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT |
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
-@@ -4837,7 +4838,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
+@@ -5018,7 +5019,7 @@ static int vmx_vcpu_setup(struct vcpu_vm
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
vmx_secondary_exec_control(vmx));
@@ -306,7 +306,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
vmcs_write64(EOI_EXIT_BITMAP0, 0);
vmcs_write64(EOI_EXIT_BITMAP1, 0);
vmcs_write64(EOI_EXIT_BITMAP2, 0);
-@@ -4995,7 +4996,7 @@ static void vmx_vcpu_reset(struct kvm_vc
+@@ -5179,7 +5180,7 @@ static void vmx_vcpu_reset(struct kvm_vc
kvm_make_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu);
@@ -315,7 +315,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
memset(&vmx->pi_desc, 0, sizeof(struct pi_desc));
if (vmx->vpid != 0)
-@@ -6278,15 +6279,6 @@ static __init int hardware_setup(void)
+@@ -6438,15 +6439,6 @@ static __init int hardware_setup(void)
kvm_tsc_scaling_ratio_frac_bits = 48;
}
@@ -328,10 +328,10 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
- kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
- }
-
- vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
- vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
- vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
-@@ -8225,7 +8217,7 @@ static void vmx_set_virtual_x2apic_mode(
+ set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
+
+ if (enable_ept) {
+@@ -8272,7 +8264,7 @@ static void vmx_set_virtual_x2apic_mode(
* apicv
*/
if (!cpu_has_vmx_virtualize_x2apic_mode() ||
@@ -340,7 +340,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return;
if (!cpu_need_tpr_shadow(vcpu))
-@@ -8333,7 +8325,7 @@ static void vmx_hwapic_irr_update(struct
+@@ -8379,7 +8371,7 @@ static void vmx_hwapic_irr_update(struct
static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
{
@@ -349,7 +349,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
return;
vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]);
-@@ -10952,7 +10944,8 @@ static struct kvm_x86_ops vmx_x86_ops =
+@@ -11023,7 +11015,8 @@ static struct kvm_x86_ops vmx_x86_ops =
.update_cr8_intercept = update_cr8_intercept,
.set_virtual_x2apic_mode = vmx_set_virtual_x2apic_mode,
.set_apic_access_page_addr = vmx_set_apic_access_page_addr,
@@ -361,7 +361,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
.hwapic_isr_update = vmx_hwapic_isr_update,
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -2769,7 +2769,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *
+@@ -2768,7 +2768,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *
static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
struct kvm_lapic_state *s)
{
@@ -372,7 +372,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
memcpy(s->regs, vcpu->arch.apic->regs, sizeof *s);
return 0;
-@@ -5934,6 +5936,12 @@ static void kvm_pv_kick_cpu_op(struct kv
+@@ -5939,6 +5941,12 @@ static void kvm_pv_kick_cpu_op(struct kv
kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL);
}
@@ -385,7 +385,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
{
unsigned long nr, a0, a1, a2, a3, ret;
-@@ -6028,6 +6036,9 @@ static void update_cr8_intercept(struct
+@@ -6033,6 +6041,9 @@ static void update_cr8_intercept(struct
if (!vcpu->arch.apic)
return;
@@ -395,7 +395,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (!vcpu->arch.apic->vapic_addr)
max_irr = kvm_lapic_find_highest_irr(vcpu);
else
-@@ -6372,7 +6383,8 @@ static void vcpu_scan_ioapic(struct kvm_
+@@ -6377,7 +6388,8 @@ static void vcpu_scan_ioapic(struct kvm_
if (irqchip_split(vcpu->kvm))
kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors);
else {
@@ -405,7 +405,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors);
}
kvm_x86_ops->load_eoi_exitmap(vcpu,
-@@ -6518,7 +6530,7 @@ static int vcpu_enter_guest(struct kvm_v
+@@ -6524,7 +6536,7 @@ static int vcpu_enter_guest(struct kvm_v
* Update architecture specific hints for APIC
* virtual interrupt delivery.
*/
@@ -414,7 +414,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
kvm_x86_ops->hwapic_irr_update(vcpu,
kvm_lapic_find_highest_irr(vcpu));
}
-@@ -7598,6 +7610,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
+@@ -7604,6 +7616,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *
BUG_ON(vcpu->kvm == NULL);
kvm = vcpu->kvm;
diff --git a/patches.drivers/0012-svm-implements-update_pi_irte-hook-to-setup-posted-interrupt b/patches.drivers/0012-svm-implements-update_pi_irte-hook-to-setup-posted-interrupt
index 44c7a81e7c..b723d766b2 100644
--- a/patches.drivers/0012-svm-implements-update_pi_irte-hook-to-setup-posted-interrupt
+++ b/patches.drivers/0012-svm-implements-update_pi_irte-hook-to-setup-posted-interrupt
@@ -32,15 +32,15 @@ Signed-off-by: Bruce Rogers <brogers@suse.com>
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
-@@ -44,6 +44,7 @@
- #include <asm/debugreg.h>
+@@ -45,6 +45,7 @@
#include <asm/kvm_para.h>
+ #include <asm/microcode.h>
#include <asm/spec-ctrl.h>
+#include <asm/irq_remapping.h>
#include <asm/virtext.h>
#include "trace.h"
-@@ -201,6 +202,23 @@ struct vcpu_svm {
+@@ -210,6 +211,23 @@ struct vcpu_svm {
struct page *avic_backing_page;
u64 *avic_physical_id_cache;
bool avic_is_running;
@@ -64,7 +64,7 @@ Signed-off-by: Bruce Rogers <brogers@suse.com>
};
#define AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK (0xFF)
-@@ -1440,31 +1458,34 @@ free_avic:
+@@ -1472,31 +1490,34 @@ free_avic:
return err;
}
@@ -118,7 +118,7 @@ Signed-off-by: Bruce Rogers <brogers@suse.com>
}
static void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
-@@ -1491,6 +1512,8 @@ static void avic_vcpu_load(struct kvm_vc
+@@ -1523,6 +1544,8 @@ static void avic_vcpu_load(struct kvm_vc
entry |= AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK;
WRITE_ONCE(*(svm->avic_physical_id_cache), entry);
@@ -127,7 +127,7 @@ Signed-off-by: Bruce Rogers <brogers@suse.com>
}
static void avic_vcpu_put(struct kvm_vcpu *vcpu)
-@@ -1502,10 +1525,27 @@ static void avic_vcpu_put(struct kvm_vcp
+@@ -1534,10 +1557,27 @@ static void avic_vcpu_put(struct kvm_vcp
return;
entry = READ_ONCE(*(svm->avic_physical_id_cache));
@@ -155,7 +155,7 @@ Signed-off-by: Bruce Rogers <brogers@suse.com>
static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
{
struct vcpu_svm *svm = to_svm(vcpu);
-@@ -1567,6 +1607,9 @@ static struct kvm_vcpu *svm_create_vcpu(
+@@ -1602,6 +1642,9 @@ static struct kvm_vcpu *svm_create_vcpu(
err = avic_init_backing_page(&svm->vcpu);
if (err)
goto free_page4;
@@ -165,7 +165,7 @@ Signed-off-by: Bruce Rogers <brogers@suse.com>
}
/* We initialize this flag to true to make sure that the is_running
-@@ -4334,6 +4377,209 @@ static void svm_deliver_avic_intr(struct
+@@ -4466,6 +4509,209 @@ static void svm_deliver_avic_intr(struct
kvm_vcpu_wake_up(vcpu);
}
@@ -375,7 +375,7 @@ Signed-off-by: Bruce Rogers <brogers@suse.com>
static int svm_nmi_allowed(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
-@@ -5173,6 +5419,7 @@ static struct kvm_x86_ops svm_x86_ops =
+@@ -5342,6 +5588,7 @@ static struct kvm_x86_ops svm_x86_ops =
.pmu_ops = &amd_pmu_ops,
.deliver_posted_interrupt = svm_deliver_avic_intr,
diff --git a/patches.drivers/drm-i915-userptr-Hold-mmref-whilst-calling-get-user b/patches.drivers/drm-i915-userptr-Hold-mmref-whilst-calling-get-user
index 5f698a480e..f76a6d729b 100644
--- a/patches.drivers/drm-i915-userptr-Hold-mmref-whilst-calling-get-user
+++ b/patches.drivers/drm-i915-userptr-Hold-mmref-whilst-calling-get-user
@@ -34,8 +34,8 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
+++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
@@ -586,19 +586,24 @@ __i915_gem_userptr_get_pages_worker(stru
- if (pvec != NULL) {
- struct mm_struct *mm = obj->userptr.mm->mm;
+ if (!obj->userptr.read_only)
+ flags |= FOLL_WRITE;
- down_read(&mm->mmap_sem);
- while (pinned < npages) {
diff --git a/patches.drivers/rtnetlink-fdb-dump-optimize-by-saving-last-interface.patch b/patches.drivers/rtnetlink-fdb-dump-optimize-by-saving-last-interface.patch
index 90b1170e97..f40c846a9a 100644
--- a/patches.drivers/rtnetlink-fdb-dump-optimize-by-saving-last-interface.patch
+++ b/patches.drivers/rtnetlink-fdb-dump-optimize-by-saving-last-interface.patch
@@ -89,7 +89,7 @@ Acked-by: David Chang <dchang@suse.com>
static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter)
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
-@@ -909,20 +909,20 @@ out:
+@@ -911,20 +911,20 @@ out:
/* Dump forwarding table */
static int vxlan_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
struct net_device *dev,
@@ -113,7 +113,7 @@ Acked-by: David Chang <dchang@suse.com>
goto skip;
err = vxlan_fdb_info(skb, vxlan, f,
-@@ -930,17 +930,15 @@ static int vxlan_fdb_dump(struct sk_buff
+@@ -932,17 +932,15 @@ static int vxlan_fdb_dump(struct sk_buff
cb->nlh->nlmsg_seq,
RTM_NEWNEIGH,
NLM_F_MULTI, rd);
@@ -176,7 +176,7 @@ Acked-by: David Chang <dchang@suse.com>
void switchdev_port_fwd_mark_set(struct net_device *dev,
struct net_device *group_dev,
bool joining);
-@@ -321,7 +321,7 @@ static inline int switchdev_port_fdb_dum
+@@ -323,7 +323,7 @@ static inline int switchdev_port_fdb_dum
struct netlink_callback *cb,
struct net_device *dev,
struct net_device *filter_dev,
@@ -255,7 +255,7 @@ Acked-by: David Chang <dchang@suse.com>
int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p,
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
-@@ -2911,7 +2911,7 @@ static int nlmsg_populate_fdb(struct sk_
+@@ -2936,7 +2936,7 @@ static int nlmsg_populate_fdb(struct sk_
seq = cb->nlh->nlmsg_seq;
list_for_each_entry(ha, &list->list, list) {
@@ -264,7 +264,7 @@ Acked-by: David Chang <dchang@suse.com>
goto skip;
err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, 0,
-@@ -2938,19 +2938,18 @@ int ndo_dflt_fdb_dump(struct sk_buff *sk
+@@ -2963,7 +2963,7 @@ int ndo_dflt_fdb_dump(struct sk_buff *sk
struct netlink_callback *cb,
struct net_device *dev,
struct net_device *filter_dev,
@@ -273,6 +273,9 @@ Acked-by: David Chang <dchang@suse.com>
{
int err;
+@@ -2971,14 +2971,13 @@ int ndo_dflt_fdb_dump(struct sk_buff *sk
+ return -EINVAL;
+
netif_addr_lock_bh(dev);
- err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc);
+ err = nlmsg_populate_fdb(skb, cb, dev, idx, &dev->uc);
@@ -288,7 +291,7 @@ Acked-by: David Chang <dchang@suse.com>
}
EXPORT_SYMBOL(ndo_dflt_fdb_dump);
-@@ -2963,9 +2962,13 @@ static int rtnl_fdb_dump(struct sk_buff
+@@ -2991,9 +2990,13 @@ static int rtnl_fdb_dump(struct sk_buff
const struct net_device_ops *cops = NULL;
struct ifinfomsg *ifm = nlmsg_data(cb->nlh);
struct net *net = sock_net(skb->sk);
@@ -303,7 +306,7 @@ Acked-by: David Chang <dchang@suse.com>
if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
ifla_policy) == 0) {
-@@ -2983,49 +2986,71 @@ static int rtnl_fdb_dump(struct sk_buff
+@@ -3011,49 +3014,71 @@ static int rtnl_fdb_dump(struct sk_buff
ops = br_dev->netdev_ops;
}
diff --git a/patches.drivers/staging-rdma-0002-Fix-changed-get_user_pages-arguments.patch b/patches.drivers/staging-rdma-0002-Fix-changed-get_user_pages-arguments.patch
index 32d710491e..f79b69d735 100644
--- a/patches.drivers/staging-rdma-0002-Fix-changed-get_user_pages-arguments.patch
+++ b/patches.drivers/staging-rdma-0002-Fix-changed-get_user_pages-arguments.patch
@@ -6,25 +6,18 @@ Patch-mainline: Never, fixes build bugs in upstream removed Linux drivers
Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
- drivers/staging/rdma/ipath/ipath_user_pages.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
+ drivers/staging/rdma/ipath/ipath_user_pages.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
-diff --git a/drivers/staging/rdma/ipath/ipath_user_pages.c b/drivers/staging/rdma/ipath/ipath_user_pages.c
-index d29b4daf61f8..401b6bf08ffa 100644
--- a/drivers/staging/rdma/ipath/ipath_user_pages.c
+++ b/drivers/staging/rdma/ipath/ipath_user_pages.c
-@@ -70,9 +70,8 @@ static int __ipath_get_user_pages(unsigned long start_page, size_t num_pages,
+@@ -70,8 +70,7 @@ static int __ipath_get_user_pages(unsign
(unsigned long) num_pages, start_page);
for (got = 0; got < num_pages; got += ret) {
- ret = get_user_pages(current, current->mm,
- start_page + got * PAGE_SIZE,
-- num_pages - got, 1, 1,
+ ret = get_user_pages(start_page + got * PAGE_SIZE,
-+ num_pages - got, FOLL_WRITE | FOLL_FORCE,
+ num_pages - got, FOLL_WRITE | FOLL_FORCE,
p + got, NULL);
if (ret < 0)
- goto bail_release;
---
-1.8.5.6
-
diff --git a/patches.drivers/staging-rdma-hfi1-convert-to-use-get_user_pages_fast.patch b/patches.drivers/staging-rdma-hfi1-convert-to-use-get_user_pages_fast.patch
index 9ee60af4ef..c350fd85fd 100644
--- a/patches.drivers/staging-rdma-hfi1-convert-to-use-get_user_pages_fast.patch
+++ b/patches.drivers/staging-rdma-hfi1-convert-to-use-get_user_pages_fast.patch
@@ -21,7 +21,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
--- a/drivers/staging/rdma/hfi1/file_ops.c
+++ b/drivers/staging/rdma/hfi1/file_ops.c
-@@ -1663,8 +1663,8 @@ static int exp_tid_setup(struct file *fp
+@@ -1669,8 +1669,8 @@ static int exp_tid_setup(struct file *fp
* Now that we know how many free RcvArray entries we have,
* we can pin that many user pages.
*/
@@ -32,7 +32,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
if (ret) {
/*
* We can't continue because the pages array won't be
-@@ -1833,7 +1833,7 @@ static int exp_tid_free(struct file *fp,
+@@ -1839,7 +1839,7 @@ static int exp_tid_free(struct file *fp,
}
}
flush_wc();
@@ -41,7 +41,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
clear_bit(bitidx, &uctxt->tidusemap[idx]);
map &= ~(1ULL<<bitidx);
}
-@@ -1862,7 +1862,7 @@ static void unlock_exp_tids(struct hfi1_
+@@ -1868,7 +1868,7 @@ static void unlock_exp_tids(struct hfi1_
uctxt->physshadow[tid] = 0;
uctxt->tid_pg_list[tid] = NULL;
pci_unmap_page(dd->pcidev, phys, PAGE_SIZE, PCI_DMA_FROMDEVICE);
@@ -106,7 +106,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
- for (got = 0; got < num_pages; got += ret) {
- ret = get_user_pages(current, current->mm,
- start_page + got * PAGE_SIZE,
-- num_pages - got, 1, 1,
+- num_pages - got, FOLL_WRITE | FOLL_FORCE,
- p + got, NULL);
- if (ret < 0)
- goto bail_release;
diff --git a/patches.kabi/kabi-KVM-x86-kABI-workaround-for-PKRU-fixes.patch b/patches.kabi/kabi-KVM-x86-kABI-workaround-for-PKRU-fixes.patch
index c5cddaa7e4..235e45eb78 100644
--- a/patches.kabi/kabi-KVM-x86-kABI-workaround-for-PKRU-fixes.patch
+++ b/patches.kabi/kabi-KVM-x86-kABI-workaround-for-PKRU-fixes.patch
@@ -28,7 +28,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
-@@ -410,7 +410,6 @@ struct kvm_vcpu_arch {
+@@ -420,7 +420,6 @@ struct kvm_vcpu_arch {
unsigned long cr4;
unsigned long cr4_guest_owned_bits;
unsigned long cr8;
@@ -36,7 +36,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
u32 hflags;
u64 efer;
u64 apic_base;
-@@ -945,6 +944,11 @@ struct kvm_x86_ops {
+@@ -969,6 +968,11 @@ struct kvm_x86_ops {
void (*apicv_post_state_restore)(struct kvm_vcpu *vcpu);
void (*setup_mce)(struct kvm_vcpu *vcpu);
@@ -82,7 +82,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
offset = pfec - 1 +
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
-@@ -1584,6 +1584,16 @@ static void svm_set_rflags(struct kvm_vc
+@@ -1799,6 +1799,16 @@ static void svm_set_rflags(struct kvm_vc
to_svm(vcpu)->vmcb->save.rflags = rflags;
}
@@ -99,7 +99,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
{
switch (reg) {
-@@ -4985,6 +4995,9 @@ static struct kvm_x86_ops svm_x86_ops =
+@@ -5495,6 +5505,9 @@ static struct kvm_x86_ops svm_x86_ops =
.get_rflags = svm_get_rflags,
.set_rflags = svm_set_rflags,
@@ -111,7 +111,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
.run = svm_vcpu_run,
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -601,6 +601,7 @@ struct vcpu_vmx {
+@@ -669,6 +669,7 @@ struct vcpu_vmx {
u64 current_tsc_ratio;
@@ -119,7 +119,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
u32 host_pkru;
/*
-@@ -2224,6 +2225,16 @@ static void vmx_set_rflags(struct kvm_vc
+@@ -2325,6 +2326,16 @@ static void vmx_set_rflags(struct kvm_vc
vmcs_writel(GUEST_RFLAGS, rflags);
}
@@ -136,7 +136,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
static u32 vmx_get_interrupt_shadow(struct kvm_vcpu *vcpu)
{
u32 interruptibility = vmcs_read32(GUEST_INTERRUPTIBILITY_INFO);
-@@ -8626,8 +8637,8 @@ static void __noclone vmx_vcpu_run(struc
+@@ -8798,8 +8809,8 @@ static void __noclone vmx_vcpu_run(struc
if (static_cpu_has(X86_FEATURE_PKU) &&
kvm_read_cr4_bits(vcpu, X86_CR4_PKE) &&
@@ -146,8 +146,8 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
+ __write_pkru(vmx->guest_pkru);
atomic_switch_perf_msrs(vmx);
-
-@@ -8775,8 +8786,8 @@ static void __noclone vmx_vcpu_run(struc
+ debugctlmsr = get_debugctlmsr();
+@@ -8996,8 +9007,8 @@ static void __noclone vmx_vcpu_run(struc
*/
if (static_cpu_has(X86_FEATURE_PKU) &&
kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) {
@@ -158,7 +158,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
__write_pkru(vmx->host_pkru);
}
-@@ -10921,6 +10932,9 @@ static struct kvm_x86_ops vmx_x86_ops =
+@@ -11213,6 +11224,9 @@ static struct kvm_x86_ops vmx_x86_ops =
.get_rflags = vmx_get_rflags,
.set_rflags = vmx_set_rflags,
@@ -168,10 +168,9 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
.tlb_flush = vmx_flush_tlb,
.run = vmx_vcpu_run,
-
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
-@@ -3089,12 +3089,12 @@ static void fill_xsave(u8 *dest, struct
+@@ -3114,12 +3114,12 @@ static void fill_xsave(u8 *dest, struct
u32 size, offset, ecx, edx;
cpuid_count(XSTATE_CPUID, index,
&size, &offset, &ecx, &edx);
@@ -189,7 +188,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
}
valid -= feature;
-@@ -3132,11 +3132,14 @@ static void load_xsave(struct kvm_vcpu *
+@@ -3157,11 +3157,14 @@ static void load_xsave(struct kvm_vcpu *
u32 size, offset, ecx, edx;
cpuid_count(XSTATE_CPUID, index,
&size, &offset, &ecx, &edx);
diff --git a/patches.kabi/kabi-protect-get_vaddr_frames.patch b/patches.kabi/kabi-protect-get_vaddr_frames.patch
new file mode 100644
index 0000000000..aa21e2ab7b
--- /dev/null
+++ b/patches.kabi/kabi-protect-get_vaddr_frames.patch
@@ -0,0 +1,101 @@
+From: Jiri Slaby <jslaby@suse.cz>
+Subject: kABI: protect get_vaddr_frames
+Patch-mainline: never, kabi
+References: kabi
+
+In 4.4.168, commit 3ec22a6bce3f06aa3b8a399ea456fb1cb3792584 (mm:
+replace get_vaddr_frames() write/force parameters with gup_flags),
+upstream commit 7f23b3504a0df63b724180262c5f3f117f21bcae changed
+parameters of get_vaddr_frames. It made the kABI checker to complain.
+
+Reintroduce the old function with the old semantics and rename the new
+to get_vaddr_frames4.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 2 +-
+ drivers/media/platform/omap/omap_vout.c | 2 +-
+ drivers/media/v4l2-core/videobuf2-memops.c | 2 +-
+ include/linux/mm.h | 2 ++
+ mm/frame_vector.c | 17 ++++++++++++++++-
+ 5 files changed, 21 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -471,7 +471,7 @@ static dma_addr_t *g2d_userptr_get_dma_a
+ goto err_free;
+ }
+
+- ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE,
++ ret = get_vaddr_frames4(start, npages, FOLL_FORCE | FOLL_WRITE,
+ g2d_userptr->vec);
+ if (ret != npages) {
+ DRM_ERROR("failed to get user pages from userptr.\n");
+--- a/drivers/media/platform/omap/omap_vout.c
++++ b/drivers/media/platform/omap/omap_vout.c
+@@ -214,7 +214,7 @@ static int omap_vout_get_userptr(struct
+ if (!vec)
+ return -ENOMEM;
+
+- ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec);
++ ret = get_vaddr_frames4(virtp, 1, FOLL_WRITE, vec);
+ if (ret != 1) {
+ frame_vector_destroy(vec);
+ return -EINVAL;
+--- a/drivers/media/v4l2-core/videobuf2-memops.c
++++ b/drivers/media/v4l2-core/videobuf2-memops.c
+@@ -53,7 +53,7 @@ struct frame_vector *vb2_create_framevec
+ vec = frame_vector_create(nr);
+ if (!vec)
+ return ERR_PTR(-ENOMEM);
+- ret = get_vaddr_frames(start & PAGE_MASK, nr, flags, vec);
++ ret = get_vaddr_frames4(start & PAGE_MASK, nr, flags, vec);
+ if (ret < 0)
+ goto out_destroy;
+ /* We accept only complete set of PFNs */
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1285,6 +1285,8 @@ struct frame_vector {
+ struct frame_vector *frame_vector_create(unsigned int nr_frames);
+ void frame_vector_destroy(struct frame_vector *vec);
+ int get_vaddr_frames(unsigned long start, unsigned int nr_pfns,
++ bool write, bool force, struct frame_vector *vec);
++int get_vaddr_frames4(unsigned long start, unsigned int nr_pfns,
+ unsigned int gup_flags, struct frame_vector *vec);
+ void put_vaddr_frames(struct frame_vector *vec);
+ int frame_vector_to_pages(struct frame_vector *vec);
+--- a/mm/frame_vector.c
++++ b/mm/frame_vector.c
+@@ -30,7 +30,7 @@
+ *
+ * This function takes care of grabbing mmap_sem as necessary.
+ */
+-int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
++int get_vaddr_frames4(unsigned long start, unsigned int nr_frames,
+ unsigned int gup_flags, struct frame_vector *vec)
+ {
+ struct mm_struct *mm = current->mm;
+@@ -92,8 +92,23 @@ out:
+ vec->nr_frames = ret;
+ return ret;
+ }
++EXPORT_SYMBOL(get_vaddr_frames4);
++
++int get_vaddr_frames(unsigned long start, unsigned int nr_pfns,
++ bool write, bool force, struct frame_vector *vec)
++{
++ unsigned int gup_flags = 0;
++
++ if (write)
++ gup_flags |= FOLL_WRITE;
++ if (force)
++ gup_flags |= FOLL_FORCE;
++
++ return get_vaddr_frames4(start, nr_pfns, gup_flags, vec);
++}
+ EXPORT_SYMBOL(get_vaddr_frames);
+
++
+ /**
+ * put_vaddr_frames() - drop references to pages if get_vaddr_frames() acquired
+ * them
diff --git a/patches.kabi/kabi-protect-xen-ops-include-in-xlate_mmu.patch b/patches.kabi/kabi-protect-xen-ops-include-in-xlate_mmu.patch
new file mode 100644
index 0000000000..610f0f5353
--- /dev/null
+++ b/patches.kabi/kabi-protect-xen-ops-include-in-xlate_mmu.patch
@@ -0,0 +1,29 @@
+From: Jiri Slaby <jslaby@suse.cz>
+Subject: kABI: protect xen/xen-ops.h include in xlate_mmu.c
+Patch-mainline: never, kabi
+References: kabi
+
+In 4.4.168, commit 26e081481506908e75a202ac91d15b484be7b27c (xen:
+xlate_mmu: add missing header to fix 'W=1' warning), upstream commit
+72791ac854fea36034fa7976b748fde585008e78 added xen/xen-ops.h include
+to xlate_mmu.c and it made some of the symbols defined.
+
+Protect the include by __GENKSYMS__ to satisfy the kABI checker.
+
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/xen/xlate_mmu.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/xen/xlate_mmu.c
++++ b/drivers/xen/xlate_mmu.c
+@@ -34,7 +34,9 @@
+ #include <asm/xen/hypervisor.h>
+
+ #include <xen/xen.h>
++#ifndef __GENKSYMS__
+ #include <xen/xen-ops.h>
++#endif
+ #include <xen/page.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/memory.h>
diff --git a/patches.kabi/posix-timers-overrun-change-kABI-fix.patch b/patches.kabi/posix-timers-overrun-change-kABI-fix.patch
index 76ae8b7d06..b0b6be88c0 100644
--- a/patches.kabi/posix-timers-overrun-change-kABI-fix.patch
+++ b/patches.kabi/posix-timers-overrun-change-kABI-fix.patch
@@ -49,6 +49,52 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
};
struct k_clock {
+--- a/kernel/time/alarmtimer.c
++++ b/kernel/time/alarmtimer.c
+@@ -478,6 +478,7 @@ static enum alarmtimer_restart alarm_han
+ ptr->it.alarm.interval);
+ result = ALARMTIMER_RESTART;
+ }
++ ptr->__it_overrun = (unsigned int)ptr->it_overrun;
+ spin_unlock_irqrestore(&ptr->it_lock, flags);
+
+ return result;
+--- a/kernel/time/posix-cpu-timers.c
++++ b/kernel/time/posix-cpu-timers.c
+@@ -104,6 +104,7 @@ static void bump_cpu_timer(struct k_itim
+
+ timer->it.cpu.expires += incr;
+ timer->it_overrun += 1LL << i;
++ timer->__it_overrun = (unsigned int)timer->it_overrun;
+ delta -= incr;
+ }
+ }
+@@ -745,6 +746,8 @@ static int posix_cpu_timer_set(struct k_
+ ~REQUEUE_PENDING;
+ timer->it_overrun_last = 0;
+ timer->it_overrun = -1;
++ timer->__it_overrun_last = 0;
++ timer->__it_overrun = -1;
+
+ if (new_expires != 0 && !(val < new_expires)) {
+ /*
+@@ -1101,6 +1104,8 @@ void posix_cpu_timer_schedule(struct k_i
+ out:
+ timer->it_overrun_last = timer->it_overrun;
+ timer->it_overrun = -1;
++ timer->__it_overrun_last = (unsigned int)timer->it_overrun_last;
++ timer->__it_overrun = -1;
+ ++timer->it_requeue_pending;
+ }
+
+@@ -1306,6 +1311,7 @@ static int do_cpu_nanosleep(const clocki
+ spin_lock_init(&timer.it_lock);
+ timer.it_clock = which_clock;
+ timer.it_overrun = -1;
++ timer.__it_overrun = -1;
+ error = posix_cpu_timer_create(&timer);
+ timer.it_process = current;
+ if (!error) {
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -379,6 +379,8 @@ static void schedule_next_timer(struct k
@@ -63,7 +109,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
@@ -504,6 +506,7 @@ static enum hrtimer_restart posix_timer_
#endif
timr->it_overrun += hrtimer_forward(timer, now,
- timr->it.real.interval);
+ timr->it.real.interval);
+ timr->__it_overrun = (unsigned int)timr->it_overrun;
ret = HRTIMER_RESTART;
++timr->it_requeue_pending;
@@ -96,49 +142,3 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
/* switch off the timer when it_value is zero */
if (!new_setting->it_value.tv_sec && !new_setting->it_value.tv_nsec)
---- a/kernel/time/alarmtimer.c
-+++ b/kernel/time/alarmtimer.c
-@@ -478,6 +478,7 @@ static enum alarmtimer_restart alarm_han
- ptr->it.alarm.interval);
- result = ALARMTIMER_RESTART;
- }
-+ ptr->__it_overrun = (unsigned int)ptr->it_overrun;
- spin_unlock_irqrestore(&ptr->it_lock, flags);
-
- return result;
---- a/kernel/time/posix-cpu-timers.c
-+++ b/kernel/time/posix-cpu-timers.c
-@@ -104,6 +104,7 @@ static void bump_cpu_timer(struct k_itim
-
- timer->it.cpu.expires += incr;
- timer->it_overrun += 1LL << i;
-+ timer->__it_overrun = (unsigned int)timer->it_overrun;
- delta -= incr;
- }
- }
-@@ -745,6 +746,8 @@ static int posix_cpu_timer_set(struct k_
- ~REQUEUE_PENDING;
- timer->it_overrun_last = 0;
- timer->it_overrun = -1LL;
-+ timer->__it_overrun_last = 0;
-+ timer->__it_overrun = -1;
-
- if (new_expires != 0 && !(val < new_expires)) {
- /*
-@@ -1101,6 +1104,8 @@ void posix_cpu_timer_schedule(struct k_i
- out:
- timer->it_overrun_last = timer->it_overrun;
- timer->it_overrun = -1LL;
-+ timer->__it_overrun_last = (unsigned int)timer->it_overrun_last;
-+ timer->__it_overrun = -1;
- ++timer->it_requeue_pending;
- }
-
-@@ -1306,6 +1311,7 @@ static int do_cpu_nanosleep(const clocki
- spin_lock_init(&timer.it_lock);
- timer.it_clock = which_clock;
- timer.it_overrun = -1LL;
-+ timer.__it_overrun = -1;
- error = posix_cpu_timer_create(&timer);
- timer.it_process = current;
- if (!error) {
diff --git a/patches.kabi/x86-cpufeature-preserve-numbers.patch b/patches.kabi/x86-cpufeature-preserve-numbers.patch
index 8e86ab0ea2..0104eca458 100644
--- a/patches.kabi/x86-cpufeature-preserve-numbers.patch
+++ b/patches.kabi/x86-cpufeature-preserve-numbers.patch
@@ -20,7 +20,8 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
arch/x86/include/asm/required-features.h | 3 -
arch/x86/kernel/cpu/common.c | 1
arch/x86/kernel/cpu/scattered.c | 5 +++
- 6 files changed, 36 insertions(+), 32 deletions(-)
+ arch/x86/kvm/cpuid.c | 10 +++++-
+ 7 files changed, 44 insertions(+), 34 deletions(-)
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -84,7 +85,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
/* Other features, Linux-defined mapping, word 3 */
/* This range is used for feature bits which conflict or are synthesized */
#define X86_FEATURE_CXMMX ( 3*32+ 0) /* Cyrix MMX extensions */
-@@ -199,26 +211,29 @@
+@@ -198,26 +210,29 @@
#define X86_FEATURE_HWP_EPP ( 7*32+13) /* Intel HWP_EPP */
#define X86_FEATURE_HWP_PKG_REQ ( 7*32+14) /* Intel HWP_PKG_REQ */
#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
@@ -125,7 +126,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
#define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
/* Virtualization flags: Linux defined, word 8 */
-@@ -294,16 +309,6 @@
+@@ -293,16 +308,6 @@
#define X86_FEATURE_SUCCOR (17*32+1) /* Uncorrectable error containment and recovery */
#define X86_FEATURE_SMCA (17*32+3) /* Scalable MCA */
@@ -166,7 +167,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
#endif /* _ASM_X86_REQUIRED_FEATURES_H */
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
-@@ -733,7 +733,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
+@@ -730,7 +730,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
c->x86_capability[CPUID_7_0_EBX] = ebx;
c->x86_capability[CPUID_7_ECX] = ecx;
@@ -188,3 +189,36 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
{ X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 },
{ X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 },
{ X86_FEATURE_PROC_FEEDBACK, CR_EDX,11, 0x80000007, 0 },
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -64,6 +64,12 @@ u64 kvm_supported_xcr0(void)
+
+ #define F(x) bit(X86_FEATURE_##x)
+
++/* These are scattered features in cpufeatures.h. */
++#define KVM_CPUID_BIT_SPEC_CTRL 26
++#define KVM_CPUID_BIT_ARCH_CAPABILITIES 29
++#define KVM_CPUID_BIT_SPEC_CTRL_SSBD 31
++#define KF(x) bit(KVM_CPUID_BIT_##x)
++
+ int kvm_update_cpuid(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_cpuid_entry2 *best;
+@@ -364,7 +370,7 @@ static inline int __do_cpuid_ent(struct
+
+ /* cpuid 7.0.edx*/
+ const u32 kvm_cpuid_7_0_edx_x86_features =
+- F(SPEC_CTRL) | F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES);
++ KF(SPEC_CTRL) | KF(SPEC_CTRL_SSBD) | KF(ARCH_CAPABILITIES);
+
+ /* all calls to cpuid_count() should be made on the same cpu */
+ get_cpu();
+@@ -444,7 +450,7 @@ static inline int __do_cpuid_ent(struct
+ // TSC_ADJUST is emulated
+ entry->ebx |= F(TSC_ADJUST);
+ entry->edx &= kvm_cpuid_7_0_edx_x86_features;
+- cpuid_mask(&entry->edx, CPUID_7_EDX);
++ entry->edx &= get_scattered_cpuid_leaf(7, 0, CPUID_EDX);
+ } else {
+ entry->ebx = 0;
+ entry->edx = 0;
diff --git a/patches.kernel.org/4.4.168-001-ipv6-Check-available-headroom-in-ip6_xmit-eve.patch b/patches.kernel.org/4.4.168-001-ipv6-Check-available-headroom-in-ip6_xmit-eve.patch
new file mode 100644
index 0000000000..0cb9bb6e4f
--- /dev/null
+++ b/patches.kernel.org/4.4.168-001-ipv6-Check-available-headroom-in-ip6_xmit-eve.patch
@@ -0,0 +1,144 @@
+From: Stefano Brivio <sbrivio@redhat.com>
+Date: Thu, 6 Dec 2018 19:30:36 +0100
+Subject: [PATCH] ipv6: Check available headroom in ip6_xmit() even without
+ options
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 66033f47ca60294a95fc85ec3a3cc909dab7b765
+
+[ Upstream commit 66033f47ca60294a95fc85ec3a3cc909dab7b765 ]
+
+Even if we send an IPv6 packet without options, MAX_HEADER might not be
+enough to account for the additional headroom required by alignment of
+hardware headers.
+
+On a configuration without HYPERV_NET, WLAN, AX25, and with IPV6_TUNNEL,
+sending short SCTP packets over IPv4 over L2TP over IPv6, we start with
+100 bytes of allocated headroom in sctp_packet_transmit(), end up with 54
+bytes after l2tp_xmit_skb(), and 14 bytes in ip6_finish_output2().
+
+Those would be enough to append our 14 bytes header, but we're going to
+align that to 16 bytes, and write 2 bytes out of the allocated slab in
+neigh_hh_output().
+
+KASan says:
+
+[ 264.967848] ==================================================================
+[ 264.967861] BUG: KASAN: slab-out-of-bounds in ip6_finish_output2+0x1aec/0x1c70
+[ 264.967866] Write of size 16 at addr 000000006af1c7fe by task netperf/6201
+[ 264.967870]
+[ 264.967876] CPU: 0 PID: 6201 Comm: netperf Not tainted 4.20.0-rc4+ #1
+[ 264.967881] Hardware name: IBM 2827 H43 400 (z/VM 6.4.0)
+[ 264.967887] Call Trace:
+[ 264.967896] ([<00000000001347d6>] show_stack+0x56/0xa0)
+[ 264.967903] [<00000000017e379c>] dump_stack+0x23c/0x290
+[ 264.967912] [<00000000007bc594>] print_address_description+0xf4/0x290
+[ 264.967919] [<00000000007bc8fc>] kasan_report+0x13c/0x240
+[ 264.967927] [<000000000162f5e4>] ip6_finish_output2+0x1aec/0x1c70
+[ 264.967935] [<000000000163f890>] ip6_finish_output+0x430/0x7f0
+[ 264.967943] [<000000000163fe44>] ip6_output+0x1f4/0x580
+[ 264.967953] [<000000000163882a>] ip6_xmit+0xfea/0x1ce8
+[ 264.967963] [<00000000017396e2>] inet6_csk_xmit+0x282/0x3f8
+[ 264.968033] [<000003ff805fb0ba>] l2tp_xmit_skb+0xe02/0x13e0 [l2tp_core]
+[ 264.968037] [<000003ff80631192>] l2tp_eth_dev_xmit+0xda/0x150 [l2tp_eth]
+[ 264.968041] [<0000000001220020>] dev_hard_start_xmit+0x268/0x928
+[ 264.968069] [<0000000001330e8e>] sch_direct_xmit+0x7ae/0x1350
+[ 264.968071] [<000000000122359c>] __dev_queue_xmit+0x2b7c/0x3478
+[ 264.968075] [<00000000013d2862>] ip_finish_output2+0xce2/0x11a0
+[ 264.968078] [<00000000013d9b14>] ip_finish_output+0x56c/0x8c8
+[ 264.968081] [<00000000013ddd1e>] ip_output+0x226/0x4c0
+[ 264.968083] [<00000000013dbd6c>] __ip_queue_xmit+0x894/0x1938
+[ 264.968100] [<000003ff80bc3a5c>] sctp_packet_transmit+0x29d4/0x3648 [sctp]
+[ 264.968116] [<000003ff80b7bf68>] sctp_outq_flush_ctrl.constprop.5+0x8d0/0xe50 [sctp]
+[ 264.968131] [<000003ff80b7c716>] sctp_outq_flush+0x22e/0x7d8 [sctp]
+[ 264.968146] [<000003ff80b35c68>] sctp_cmd_interpreter.isra.16+0x530/0x6800 [sctp]
+[ 264.968161] [<000003ff80b3410a>] sctp_do_sm+0x222/0x648 [sctp]
+[ 264.968177] [<000003ff80bbddac>] sctp_primitive_ASSOCIATE+0xbc/0xf8 [sctp]
+[ 264.968192] [<000003ff80b93328>] __sctp_connect+0x830/0xc20 [sctp]
+[ 264.968208] [<000003ff80bb11ce>] sctp_inet_connect+0x2e6/0x378 [sctp]
+[ 264.968212] [<0000000001197942>] __sys_connect+0x21a/0x450
+[ 264.968215] [<000000000119aff8>] sys_socketcall+0x3d0/0xb08
+[ 264.968218] [<000000000184ea7a>] system_call+0x2a2/0x2c0
+
+[...]
+
+Just like ip_finish_output2() does for IPv4, check that we have enough
+headroom in ip6_xmit(), and reallocate it if we don't.
+
+This issue is older than git history.
+
+Reported-by: Jianlin Shi <jishi@redhat.com>
+Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ net/ipv6/ip6_output.c | 42 +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 530b62fd6b64..f8cca81d66f2 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -169,37 +169,37 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
+ const struct ipv6_pinfo *np = inet6_sk(sk);
+ struct in6_addr *first_hop = &fl6->daddr;
+ struct dst_entry *dst = skb_dst(skb);
++ unsigned int head_room;
+ struct ipv6hdr *hdr;
+ u8 proto = fl6->flowi6_proto;
+ int seg_len = skb->len;
+ int hlimit = -1;
+ u32 mtu;
+
+- if (opt) {
+- unsigned int head_room;
++ head_room = sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev);
++ if (opt)
++ head_room += opt->opt_nflen + opt->opt_flen;
+
+- /* First: exthdrs may take lots of space (~8K for now)
+- MAX_HEADER is not enough.
+- */
+- head_room = opt->opt_nflen + opt->opt_flen;
+- seg_len += head_room;
+- head_room += sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev);
+-
+- if (skb_headroom(skb) < head_room) {
+- struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
+- if (!skb2) {
+- IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
+- IPSTATS_MIB_OUTDISCARDS);
+- kfree_skb(skb);
+- return -ENOBUFS;
+- }
+- if (skb->sk)
+- skb_set_owner_w(skb2, skb->sk);
+- consume_skb(skb);
+- skb = skb2;
++ if (unlikely(skb_headroom(skb) < head_room)) {
++ struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
++ if (!skb2) {
++ IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
++ IPSTATS_MIB_OUTDISCARDS);
++ kfree_skb(skb);
++ return -ENOBUFS;
+ }
++ if (skb->sk)
++ skb_set_owner_w(skb2, skb->sk);
++ consume_skb(skb);
++ skb = skb2;
++ }
++
++ if (opt) {
++ seg_len += opt->opt_nflen + opt->opt_flen;
++
+ if (opt->opt_flen)
+ ipv6_push_frag_opts(skb, opt, &proto);
++
+ if (opt->opt_nflen)
+ ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
+ }
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-002-net-8139cp-fix-a-BUG-triggered-by-changing-mt.patch b/patches.kernel.org/4.4.168-002-net-8139cp-fix-a-BUG-triggered-by-changing-mt.patch
new file mode 100644
index 0000000000..6c191ab513
--- /dev/null
+++ b/patches.kernel.org/4.4.168-002-net-8139cp-fix-a-BUG-triggered-by-changing-mt.patch
@@ -0,0 +1,150 @@
+From: Su Yanjun <suyj.fnst@cn.fujitsu.com>
+Date: Mon, 3 Dec 2018 15:33:07 +0800
+Subject: [PATCH] net: 8139cp: fix a BUG triggered by changing mtu with network
+ traffic
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: a5d4a89245ead1f37ed135213653c5beebea4237
+
+[ Upstream commit a5d4a89245ead1f37ed135213653c5beebea4237 ]
+
+When changing mtu many times with traffic, a bug is triggered:
+
+[ 1035.684037] kernel BUG at lib/dynamic_queue_limits.c:26!
+[ 1035.684042] invalid opcode: 0000 [#1] SMP
+[ 1035.684049] Modules linked in: loop binfmt_misc 8139cp(OE) macsec
+tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag tcp_lp
+fuse uinput xt_CHECKSUM iptable_mangle ipt_MASQUERADE
+nf_nat_masquerade_ipv4 iptable_nat nf_nat_ipv4 nf_nat nf_conntrack_ipv4
+nf_defrag_ipv4 xt_conntrack nf_conntrack ipt_REJECT nf_reject_ipv4 tun
+bridge stp llc ebtable_filter ebtables ip6table_filter devlink
+ip6_tables iptable_filter sunrpc snd_hda_codec_generic snd_hda_intel
+snd_hda_codec snd_hda_core snd_hwdep ppdev snd_seq iosf_mbi crc32_pclmul
+parport_pc snd_seq_device ghash_clmulni_intel parport snd_pcm
+aesni_intel joydev lrw snd_timer virtio_balloon sg gf128mul glue_helper
+ablk_helper cryptd snd soundcore i2c_piix4 pcspkr ip_tables xfs
+libcrc32c sr_mod sd_mod cdrom crc_t10dif crct10dif_generic ata_generic
+[ 1035.684102] pata_acpi virtio_console qxl drm_kms_helper syscopyarea
+sysfillrect sysimgblt floppy fb_sys_fops crct10dif_pclmul
+crct10dif_common ttm crc32c_intel serio_raw ata_piix drm libata 8139too
+virtio_pci drm_panel_orientation_quirks virtio_ring virtio mii dm_mirror
+dm_region_hash dm_log dm_mod [last unloaded: 8139cp]
+[ 1035.684132] CPU: 9 PID: 25140 Comm: if-mtu-change Kdump: loaded
+Tainted: G OE ------------ T 3.10.0-957.el7.x86_64 #1
+[ 1035.684134] Hardware name: Red Hat KVM, BIOS 0.5.1 01/01/2011
+[ 1035.684136] task: ffff8f59b1f5a080 ti: ffff8f5a2e32c000 task.ti:
+ffff8f5a2e32c000
+[ 1035.684149] RIP: 0010:[<ffffffffba3a40d0>] [<ffffffffba3a40d0>]
+dql_completed+0x180/0x190
+[ 1035.684162] RSP: 0000:ffff8f5a75483e50 EFLAGS: 00010093
+[ 1035.684162] RAX: 00000000000000c2 RBX: ffff8f5a6f91c000 RCX:
+0000000000000000
+[ 1035.684162] RDX: 0000000000000000 RSI: 0000000000000184 RDI:
+ffff8f599fea3ec0
+[ 1035.684162] RBP: ffff8f5a75483ea8 R08: 00000000000000c2 R09:
+0000000000000000
+[ 1035.684162] R10: 00000000000616ef R11: ffff8f5a75483b56 R12:
+ffff8f599fea3e00
+[ 1035.684162] R13: 0000000000000001 R14: 0000000000000000 R15:
+0000000000000184
+[ 1035.684162] FS: 00007fa8434de740(0000) GS:ffff8f5a75480000(0000)
+knlGS:0000000000000000
+[ 1035.684162] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1035.684162] CR2: 00000000004305d0 CR3: 000000024eb66000 CR4:
+00000000001406e0
+[ 1035.684162] Call Trace:
+[ 1035.684162] <IRQ>
+[ 1035.684162] [<ffffffffc08cbaf8>] ? cp_interrupt+0x478/0x580 [8139cp]
+[ 1035.684162] [<ffffffffba14a294>]
+__handle_irq_event_percpu+0x44/0x1c0
+[ 1035.684162] [<ffffffffba14a442>] handle_irq_event_percpu+0x32/0x80
+[ 1035.684162] [<ffffffffba14a4cc>] handle_irq_event+0x3c/0x60
+[ 1035.684162] [<ffffffffba14db29>] handle_fasteoi_irq+0x59/0x110
+[ 1035.684162] [<ffffffffba02e554>] handle_irq+0xe4/0x1a0
+[ 1035.684162] [<ffffffffba7795dd>] do_IRQ+0x4d/0xf0
+[ 1035.684162] [<ffffffffba76b362>] common_interrupt+0x162/0x162
+[ 1035.684162] <EOI>
+[ 1035.684162] [<ffffffffba0c2ae4>] ? __wake_up_bit+0x24/0x70
+[ 1035.684162] [<ffffffffba1e46f5>] ? do_set_pte+0xd5/0x120
+[ 1035.684162] [<ffffffffba1b64fb>] unlock_page+0x2b/0x30
+[ 1035.684162] [<ffffffffba1e4879>] do_read_fault.isra.61+0x139/0x1b0
+[ 1035.684162] [<ffffffffba1e9134>] handle_pte_fault+0x2f4/0xd10
+[ 1035.684162] [<ffffffffba1ebc6d>] handle_mm_fault+0x39d/0x9b0
+[ 1035.684162] [<ffffffffba76f5e3>] __do_page_fault+0x203/0x500
+[ 1035.684162] [<ffffffffba76f9c6>] trace_do_page_fault+0x56/0x150
+[ 1035.684162] [<ffffffffba76ef42>] do_async_page_fault+0x22/0xf0
+[ 1035.684162] [<ffffffffba76b788>] async_page_fault+0x28/0x30
+[ 1035.684162] Code: 54 c7 47 54 ff ff ff ff 44 0f 49 ce 48 8b 35 48 2f
+9c 00 48 89 77 58 e9 fe fe ff ff 0f 1f 80 00 00 00 00 41 89 d1 e9 ef fe
+ff ff <0f> 0b 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 55 8d 42 ff 48
+[ 1035.684162] RIP [<ffffffffba3a40d0>] dql_completed+0x180/0x190
+[ 1035.684162] RSP <ffff8f5a75483e50>
+
+It's not the same as in 7fe0ee09 patch described.
+As 8139cp uses shared irq mode, other device irq will trigger
+cp_interrupt to execute.
+
+cp_change_mtu
+ -> cp_close
+ -> cp_open
+
+In cp_close routine just before free_irq(), some interrupt may occur.
+In my environment, cp_interrupt exectutes and IntrStatus is 0x4,
+exactly TxOk. That will cause cp_tx to wake device queue.
+
+As device queue is started, cp_start_xmit and cp_open will run at same
+time which will cause kernel BUG.
+
+For example:
+[#] for tx descriptor
+
+At start:
+
+[#][#][#]
+num_queued=3
+
+After cp_init_hw->cp_start_hw->netdev_reset_queue:
+
+[#][#][#]
+num_queued=0
+
+When 8139cp starts to work then cp_tx will check
+num_queued mismatchs the complete_bytes.
+
+The patch will check IntrMask before check IntrStatus in cp_interrupt.
+When 8139cp interrupt is disabled, just return.
+
+Signed-off-by: Su Yanjun <suyj.fnst@cn.fujitsu.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/net/ethernet/realtek/8139cp.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/realtek/8139cp.c b/drivers/net/ethernet/realtek/8139cp.c
+index deae10d7426d..9b588251f2a7 100644
+--- a/drivers/net/ethernet/realtek/8139cp.c
++++ b/drivers/net/ethernet/realtek/8139cp.c
+@@ -578,6 +578,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
+ struct cp_private *cp;
+ int handled = 0;
+ u16 status;
++ u16 mask;
+
+ if (unlikely(dev == NULL))
+ return IRQ_NONE;
+@@ -585,6 +586,10 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
+
+ spin_lock(&cp->lock);
+
++ mask = cpr16(IntrMask);
++ if (!mask)
++ goto out_unlock;
++
+ status = cpr16(IntrStatus);
+ if (!status || (status == 0xFFFF))
+ goto out_unlock;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-003-net-phy-don-t-allow-__set_phy_supported-to-ad.patch b/patches.kernel.org/4.4.168-003-net-phy-don-t-allow-__set_phy_supported-to-ad.patch
new file mode 100644
index 0000000000..3e1e6e648b
--- /dev/null
+++ b/patches.kernel.org/4.4.168-003-net-phy-don-t-allow-__set_phy_supported-to-ad.patch
@@ -0,0 +1,63 @@
+From: Heiner Kallweit <hkallweit1@gmail.com>
+Date: Mon, 3 Dec 2018 08:19:33 +0100
+Subject: [PATCH] net: phy: don't allow __set_phy_supported to add unsupported
+ modes
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: d2a36971ef595069b7a600d1144c2e0881a930a1
+
+[ Upstream commit d2a36971ef595069b7a600d1144c2e0881a930a1 ]
+
+Currently __set_phy_supported allows to add modes w/o checking whether
+the PHY supports them. This is wrong, it should never add modes but
+only remove modes we don't want to support.
+
+The commit marked as fixed didn't do anything wrong, it just copied
+existing functionality to the helper which is being fixed now.
+
+Fixes: f3a6bd393c2c ("phylib: Add phy_set_max_speed helper")
+Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/net/phy/phy_device.c | 19 ++++++++-----------
+ 1 file changed, 8 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 1f2f25a71d18..70f26b30729c 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -1265,20 +1265,17 @@ static int gen10g_resume(struct phy_device *phydev)
+
+ static int __set_phy_supported(struct phy_device *phydev, u32 max_speed)
+ {
+- phydev->supported &= ~(PHY_1000BT_FEATURES | PHY_100BT_FEATURES |
+- PHY_10BT_FEATURES);
+-
+ switch (max_speed) {
+- default:
+- return -ENOTSUPP;
+- case SPEED_1000:
+- phydev->supported |= PHY_1000BT_FEATURES;
++ case SPEED_10:
++ phydev->supported &= ~PHY_100BT_FEATURES;
+ /* fall through */
+ case SPEED_100:
+- phydev->supported |= PHY_100BT_FEATURES;
+- /* fall through */
+- case SPEED_10:
+- phydev->supported |= PHY_10BT_FEATURES;
++ phydev->supported &= ~PHY_1000BT_FEATURES;
++ break;
++ case SPEED_1000:
++ break;
++ default:
++ return -ENOTSUPP;
+ }
+
+ return 0;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-004-net-Prevent-invalid-access-to-skb-prev-in-__q.patch b/patches.kernel.org/4.4.168-004-net-Prevent-invalid-access-to-skb-prev-in-__q.patch
new file mode 100644
index 0000000000..4e246badf0
--- /dev/null
+++ b/patches.kernel.org/4.4.168-004-net-Prevent-invalid-access-to-skb-prev-in-__q.patch
@@ -0,0 +1,104 @@
+From: Christoph Paasch <cpaasch@apple.com>
+Date: Thu, 29 Nov 2018 16:01:04 -0800
+Subject: [PATCH] net: Prevent invalid access to skb->prev in __qdisc_drop_all
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 9410d386d0a829ace9558336263086c2fbbe8aed
+
+[ Upstream commit 9410d386d0a829ace9558336263086c2fbbe8aed ]
+
+__qdisc_drop_all() accesses skb->prev to get to the tail of the
+segment-list.
+
+With commit 68d2f84a1368 ("net: gro: properly remove skb from list")
+the skb-list handling has been changed to set skb->next to NULL and set
+the list-poison on skb->prev.
+
+With that change, __qdisc_drop_all() will panic when it tries to
+dereference skb->prev.
+
+Since commit 992cba7e276d ("net: Add and use skb_list_del_init().")
+__list_del_entry is used, leaving skb->prev unchanged (thus,
+pointing to the list-head if it's the first skb of the list).
+This will make __qdisc_drop_all modify the next-pointer of the list-head
+and result in a panic later on:
+
+[ 34.501053] general protection fault: 0000 [#1] SMP KASAN PTI
+[ 34.501968] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.20.0-rc2.mptcp #108
+[ 34.502887] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.5.1 01/01/2011
+[ 34.504074] RIP: 0010:dev_gro_receive+0x343/0x1f90
+[ 34.504751] Code: e0 48 c1 e8 03 42 80 3c 30 00 0f 85 4a 1c 00 00 4d 8b 24 24 4c 39 65 d0 0f 84 0a 04 00 00 49 8d 7c 24 38 48 89 f8 48 c1 e8 03 <42> 0f b6 04 30 84 c0 74 08 3c 04
+[ 34.507060] RSP: 0018:ffff8883af507930 EFLAGS: 00010202
+[ 34.507761] RAX: 0000000000000007 RBX: ffff8883970b2c80 RCX: 1ffff11072e165a6
+[ 34.508640] RDX: 1ffff11075867008 RSI: ffff8883ac338040 RDI: 0000000000000038
+[ 34.509493] RBP: ffff8883af5079d0 R08: ffff8883970b2d40 R09: 0000000000000062
+[ 34.510346] R10: 0000000000000034 R11: 0000000000000000 R12: 0000000000000000
+[ 34.511215] R13: 0000000000000000 R14: dffffc0000000000 R15: ffff8883ac338008
+[ 34.512082] FS: 0000000000000000(0000) GS:ffff8883af500000(0000) knlGS:0000000000000000
+[ 34.513036] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 34.513741] CR2: 000055ccc3e9d020 CR3: 00000003abf32000 CR4: 00000000000006e0
+[ 34.514593] Call Trace:
+[ 34.514893] <IRQ>
+[ 34.515157] napi_gro_receive+0x93/0x150
+[ 34.515632] receive_buf+0x893/0x3700
+[ 34.516094] ? __netif_receive_skb+0x1f/0x1a0
+[ 34.516629] ? virtnet_probe+0x1b40/0x1b40
+[ 34.517153] ? __stable_node_chain+0x4d0/0x850
+[ 34.517684] ? kfree+0x9a/0x180
+[ 34.518067] ? __kasan_slab_free+0x171/0x190
+[ 34.518582] ? detach_buf+0x1df/0x650
+[ 34.519061] ? lapic_next_event+0x5a/0x90
+[ 34.519539] ? virtqueue_get_buf_ctx+0x280/0x7f0
+[ 34.520093] virtnet_poll+0x2df/0xd60
+[ 34.520533] ? receive_buf+0x3700/0x3700
+[ 34.521027] ? qdisc_watchdog_schedule_ns+0xd5/0x140
+[ 34.521631] ? htb_dequeue+0x1817/0x25f0
+[ 34.522107] ? sch_direct_xmit+0x142/0xf30
+[ 34.522595] ? virtqueue_napi_schedule+0x26/0x30
+[ 34.523155] net_rx_action+0x2f6/0xc50
+[ 34.523601] ? napi_complete_done+0x2f0/0x2f0
+[ 34.524126] ? kasan_check_read+0x11/0x20
+[ 34.524608] ? _raw_spin_lock+0x7d/0xd0
+[ 34.525070] ? _raw_spin_lock_bh+0xd0/0xd0
+[ 34.525563] ? kvm_guest_apic_eoi_write+0x6b/0x80
+[ 34.526130] ? apic_ack_irq+0x9e/0xe0
+[ 34.526567] __do_softirq+0x188/0x4b5
+[ 34.527015] irq_exit+0x151/0x180
+[ 34.527417] do_IRQ+0xdb/0x150
+[ 34.527783] common_interrupt+0xf/0xf
+[ 34.528223] </IRQ>
+
+This patch makes sure that skb->prev is set to NULL when entering
+netem_enqueue.
+
+Cc: Prashant Bhole <bhole_prashant_q7@lab.ntt.co.jp>
+Cc: Tyler Hicks <tyhicks@canonical.com>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Fixes: 68d2f84a1368 ("net: gro: properly remove skb from list")
+Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: Christoph Paasch <cpaasch@apple.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ net/sched/sch_netem.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 743ff23885da..7acf1f2b8dfc 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -432,6 +432,9 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+ int count = 1;
+ int rc = NET_XMIT_SUCCESS;
+
++ /* Do not fool qdisc_drop_all() */
++ skb->prev = NULL;
++
+ /* Random duplication */
+ if (q->duplicate && q->duplicate >= get_crandom(&q->dup_cor))
+ ++count;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-005-rtnetlink-ndo_dflt_fdb_dump-only-work-for-ARP.patch b/patches.kernel.org/4.4.168-005-rtnetlink-ndo_dflt_fdb_dump-only-work-for-ARP.patch
new file mode 100644
index 0000000000..03979d103c
--- /dev/null
+++ b/patches.kernel.org/4.4.168-005-rtnetlink-ndo_dflt_fdb_dump-only-work-for-ARP.patch
@@ -0,0 +1,159 @@
+From: Eric Dumazet <edumazet@google.com>
+Date: Tue, 4 Dec 2018 09:40:35 -0800
+Subject: [PATCH] rtnetlink: ndo_dflt_fdb_dump() only work for ARPHRD_ETHER
+ devices
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 688838934c231bb08f46db687e57f6d8bf82709c
+
+[ Upstream commit 688838934c231bb08f46db687e57f6d8bf82709c ]
+
+kmsan was able to trigger a kernel-infoleak using a gre device [1]
+
+nlmsg_populate_fdb_fill() has a hard coded assumption
+that dev->addr_len is ETH_ALEN, as normally guaranteed
+for ARPHRD_ETHER devices.
+
+A similar issue was fixed recently in commit da71577545a5
+("rtnetlink: Disallow FDB configuration for non-Ethernet device")
+
+[1]
+BUG: KMSAN: kernel-infoleak in copyout lib/iov_iter.c:143 [inline]
+BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x4c0/0x2700 lib/iov_iter.c:576
+CPU: 0 PID: 6697 Comm: syz-executor310 Not tainted 4.20.0-rc3+ #95
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x32d/0x480 lib/dump_stack.c:113
+ kmsan_report+0x12c/0x290 mm/kmsan/kmsan.c:683
+ kmsan_internal_check_memory+0x32a/0xa50 mm/kmsan/kmsan.c:743
+ kmsan_copy_to_user+0x78/0xd0 mm/kmsan/kmsan_hooks.c:634
+ copyout lib/iov_iter.c:143 [inline]
+ _copy_to_iter+0x4c0/0x2700 lib/iov_iter.c:576
+ copy_to_iter include/linux/uio.h:143 [inline]
+ skb_copy_datagram_iter+0x4e2/0x1070 net/core/datagram.c:431
+ skb_copy_datagram_msg include/linux/skbuff.h:3316 [inline]
+ netlink_recvmsg+0x6f9/0x19d0 net/netlink/af_netlink.c:1975
+ sock_recvmsg_nosec net/socket.c:794 [inline]
+ sock_recvmsg+0x1d1/0x230 net/socket.c:801
+ ___sys_recvmsg+0x444/0xae0 net/socket.c:2278
+ __sys_recvmsg net/socket.c:2327 [inline]
+ __do_sys_recvmsg net/socket.c:2337 [inline]
+ __se_sys_recvmsg+0x2fa/0x450 net/socket.c:2334
+ __x64_sys_recvmsg+0x4a/0x70 net/socket.c:2334
+ do_syscall_64+0xcf/0x110 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+RIP: 0033:0x441119
+Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 db 0a fc ff c3 66 2e 0f 1f 84 00 00 00 00
+RSP: 002b:00007fffc7f008a8 EFLAGS: 00000207 ORIG_RAX: 000000000000002f
+RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 0000000000441119
+RDX: 0000000000000040 RSI: 00000000200005c0 RDI: 0000000000000003
+RBP: 00000000006cc018 R08: 0000000000000100 R09: 0000000000000100
+R10: 0000000000000100 R11: 0000000000000207 R12: 0000000000402080
+R13: 0000000000402110 R14: 0000000000000000 R15: 0000000000000000
+
+Uninit was stored to memory at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:246 [inline]
+ kmsan_save_stack mm/kmsan/kmsan.c:261 [inline]
+ kmsan_internal_chain_origin+0x13d/0x240 mm/kmsan/kmsan.c:469
+ kmsan_memcpy_memmove_metadata+0x1a9/0xf70 mm/kmsan/kmsan.c:344
+ kmsan_memcpy_metadata+0xb/0x10 mm/kmsan/kmsan.c:362
+ __msan_memcpy+0x61/0x70 mm/kmsan/kmsan_instr.c:162
+ __nla_put lib/nlattr.c:744 [inline]
+ nla_put+0x20a/0x2d0 lib/nlattr.c:802
+ nlmsg_populate_fdb_fill+0x444/0x810 net/core/rtnetlink.c:3466
+ nlmsg_populate_fdb net/core/rtnetlink.c:3775 [inline]
+ ndo_dflt_fdb_dump+0x73a/0x960 net/core/rtnetlink.c:3807
+ rtnl_fdb_dump+0x1318/0x1cb0 net/core/rtnetlink.c:3979
+ netlink_dump+0xc79/0x1c90 net/netlink/af_netlink.c:2244
+ __netlink_dump_start+0x10c4/0x11d0 net/netlink/af_netlink.c:2352
+ netlink_dump_start include/linux/netlink.h:216 [inline]
+ rtnetlink_rcv_msg+0x141b/0x1540 net/core/rtnetlink.c:4910
+ netlink_rcv_skb+0x394/0x640 net/netlink/af_netlink.c:2477
+ rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:4965
+ netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
+ netlink_unicast+0x1699/0x1740 net/netlink/af_netlink.c:1336
+ netlink_sendmsg+0x13c7/0x1440 net/netlink/af_netlink.c:1917
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xe3b/0x1240 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x305/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xcf/0x110 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+
+Uninit was created at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:246 [inline]
+ kmsan_internal_poison_shadow+0x6d/0x130 mm/kmsan/kmsan.c:170
+ kmsan_kmalloc+0xa1/0x100 mm/kmsan/kmsan_hooks.c:186
+ __kmalloc+0x14c/0x4d0 mm/slub.c:3825
+ kmalloc include/linux/slab.h:551 [inline]
+ __hw_addr_create_ex net/core/dev_addr_lists.c:34 [inline]
+ __hw_addr_add_ex net/core/dev_addr_lists.c:80 [inline]
+ __dev_mc_add+0x357/0x8a0 net/core/dev_addr_lists.c:670
+ dev_mc_add+0x6d/0x80 net/core/dev_addr_lists.c:687
+ ip_mc_filter_add net/ipv4/igmp.c:1128 [inline]
+ igmp_group_added+0x4d4/0xb80 net/ipv4/igmp.c:1311
+ __ip_mc_inc_group+0xea9/0xf70 net/ipv4/igmp.c:1444
+ ip_mc_inc_group net/ipv4/igmp.c:1453 [inline]
+ ip_mc_up+0x1c3/0x400 net/ipv4/igmp.c:1775
+ inetdev_event+0x1d03/0x1d80 net/ipv4/devinet.c:1522
+ notifier_call_chain kernel/notifier.c:93 [inline]
+ __raw_notifier_call_chain kernel/notifier.c:394 [inline]
+ raw_notifier_call_chain+0x13d/0x240 kernel/notifier.c:401
+ __dev_notify_flags+0x3da/0x860 net/core/dev.c:1733
+ dev_change_flags+0x1ac/0x230 net/core/dev.c:7569
+ do_setlink+0x165f/0x5ea0 net/core/rtnetlink.c:2492
+ rtnl_newlink+0x2ad7/0x35a0 net/core/rtnetlink.c:3111
+ rtnetlink_rcv_msg+0x1148/0x1540 net/core/rtnetlink.c:4947
+ netlink_rcv_skb+0x394/0x640 net/netlink/af_netlink.c:2477
+ rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:4965
+ netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
+ netlink_unicast+0x1699/0x1740 net/netlink/af_netlink.c:1336
+ netlink_sendmsg+0x13c7/0x1440 net/netlink/af_netlink.c:1917
+ sock_sendmsg_nosec net/socket.c:621 [inline]
+ sock_sendmsg net/socket.c:631 [inline]
+ ___sys_sendmsg+0xe3b/0x1240 net/socket.c:2116
+ __sys_sendmsg net/socket.c:2154 [inline]
+ __do_sys_sendmsg net/socket.c:2163 [inline]
+ __se_sys_sendmsg+0x305/0x460 net/socket.c:2161
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2161
+ do_syscall_64+0xcf/0x110 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+
+Bytes 36-37 of 105 are uninitialized
+Memory access of size 105 starts at ffff88819686c000
+Data copied to user address 0000000020000380
+
+Fixes: d83b06036048 ("net: add fdb generic dump routine")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: John Fastabend <john.fastabend@gmail.com>
+Cc: Ido Schimmel <idosch@mellanox.com>
+Cc: David Ahern <dsahern@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ net/core/rtnetlink.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index d2a46ffe6382..d52b633164c9 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -2931,6 +2931,9 @@ int ndo_dflt_fdb_dump(struct sk_buff *skb,
+ {
+ int err;
+
++ if (dev->type != ARPHRD_ETHER)
++ return -EINVAL;
++
+ netif_addr_lock_bh(dev);
+ err = nlmsg_populate_fdb(skb, cb, dev, &idx, &dev->uc);
+ if (err)
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-006-tcp-fix-NULL-ref-in-tail-loss-probe.patch b/patches.kernel.org/4.4.168-006-tcp-fix-NULL-ref-in-tail-loss-probe.patch
new file mode 100644
index 0000000000..49a99c6ec7
--- /dev/null
+++ b/patches.kernel.org/4.4.168-006-tcp-fix-NULL-ref-in-tail-loss-probe.patch
@@ -0,0 +1,58 @@
+From: Yuchung Cheng <ycheng@google.com>
+Date: Wed, 5 Dec 2018 14:38:38 -0800
+Subject: [PATCH] tcp: fix NULL ref in tail loss probe
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: b2b7af861122a0c0f6260155c29a1b2e594cd5b5
+
+[ Upstream commit b2b7af861122a0c0f6260155c29a1b2e594cd5b5 ]
+
+TCP loss probe timer may fire when the retranmission queue is empty but
+has a non-zero tp->packets_out counter. tcp_send_loss_probe will call
+tcp_rearm_rto which triggers NULL pointer reference by fetching the
+retranmission queue head in its sub-routines.
+
+Add a more detailed warning to help catch the root cause of the inflight
+accounting inconsistency.
+
+Reported-by: Rafael Tinoco <rafael.tinoco@linaro.org>
+Signed-off-by: Yuchung Cheng <ycheng@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ net/ipv4/tcp_output.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 2d3c9df8d75c..b55b8954dae5 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2263,14 +2263,18 @@ void tcp_send_loss_probe(struct sock *sk)
+ skb = tcp_write_queue_tail(sk);
+ }
+
++ if (unlikely(!skb)) {
++ WARN_ONCE(tp->packets_out,
++ "invalid inflight: %u state %u cwnd %u mss %d\n",
++ tp->packets_out, sk->sk_state, tp->snd_cwnd, mss);
++ inet_csk(sk)->icsk_pending = 0;
++ return;
++ }
++
+ /* At most one outstanding TLP retransmission. */
+ if (tp->tlp_high_seq)
+ goto rearm_timer;
+
+- /* Retransmit last segment. */
+- if (WARN_ON(!skb))
+- goto rearm_timer;
+-
+ if (skb_still_in_host_queue(sk, skb))
+ goto rearm_timer;
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-007-tun-forbid-iface-creation-with-rtnl-ops.patch b/patches.kernel.org/4.4.168-007-tun-forbid-iface-creation-with-rtnl-ops.patch
new file mode 100644
index 0000000000..bd90352fd8
--- /dev/null
+++ b/patches.kernel.org/4.4.168-007-tun-forbid-iface-creation-with-rtnl-ops.patch
@@ -0,0 +1,52 @@
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Thu, 29 Nov 2018 14:45:39 +0100
+Subject: [PATCH] tun: forbid iface creation with rtnl ops
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 35b827b6d06199841a83839e8bb69c0cd13a28be
+
+[ Upstream commit 35b827b6d06199841a83839e8bb69c0cd13a28be ]
+
+It's not supported right now (the goal of the initial patch was to support
+'ip link del' only).
+
+Before the patch:
+$ ip link add foo type tun
+[ 239.632660] BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
+[snip]
+[ 239.636410] RIP: 0010:register_netdevice+0x8e/0x3a0
+
+This panic occurs because dev->netdev_ops is not set by tun_setup(). But to
+have something usable, it will require more than just setting
+netdev_ops.
+
+Fixes: f019a7a594d9 ("tun: Implement ip link del tunXXX")
+CC: Eric W. Biederman <ebiederm@xmission.com>
+Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/net/tun.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 5ac0b850d6b1..fd9ff9eff237 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1475,9 +1475,9 @@ static void tun_setup(struct net_device *dev)
+ */
+ static int tun_validate(struct nlattr *tb[], struct nlattr *data[])
+ {
+- if (!data)
+- return 0;
+- return -EINVAL;
++ /* NL_SET_ERR_MSG(extack,
++ "tun/tap creation via rtnetlink is not supported."); */
++ return -EOPNOTSUPP;
+ }
+
+ static struct rtnl_link_ops tun_link_ops __read_mostly = {
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-008-neighbour-Avoid-writing-before-skb-head-in-ne.patch b/patches.kernel.org/4.4.168-008-neighbour-Avoid-writing-before-skb-head-in-ne.patch
new file mode 100644
index 0000000000..80ef4fac3c
--- /dev/null
+++ b/patches.kernel.org/4.4.168-008-neighbour-Avoid-writing-before-skb-head-in-ne.patch
@@ -0,0 +1,94 @@
+From: Stefano Brivio <sbrivio@redhat.com>
+Date: Thu, 6 Dec 2018 19:30:37 +0100
+Subject: [PATCH] neighbour: Avoid writing before skb->head in
+ neigh_hh_output()
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: e6ac64d4c4d095085d7dd71cbd05704ac99829b2
+
+[ Upstream commit e6ac64d4c4d095085d7dd71cbd05704ac99829b2 ]
+
+While skb_push() makes the kernel panic if the skb headroom is less than
+the unaligned hardware header size, it will proceed normally in case we
+copy more than that because of alignment, and we'll silently corrupt
+adjacent slabs.
+
+In the case fixed by the previous patch,
+"ipv6: Check available headroom in ip6_xmit() even without options", we
+end up in neigh_hh_output() with 14 bytes headroom, 14 bytes hardware
+header and write 16 bytes, starting 2 bytes before the allocated buffer.
+
+Always check we're not writing before skb->head and, if the headroom is
+not enough, warn and drop the packet.
+
+v2:
+ - instead of panicking with BUG_ON(), WARN_ON_ONCE() and drop the packet
+ (Eric Dumazet)
+ - if we avoid the panic, though, we need to explicitly check the headroom
+ before the memcpy(), otherwise we'll have corrupted slabs on a running
+ kernel, after we warn
+ - use __skb_push() instead of skb_push(), as the headroom check is
+ already implemented here explicitly (Eric Dumazet)
+
+Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ include/net/neighbour.h | 28 +++++++++++++++++++++++-----
+ 1 file changed, 23 insertions(+), 5 deletions(-)
+
+diff --git a/include/net/neighbour.h b/include/net/neighbour.h
+index 8b683841e574..f6017ddc4ded 100644
+--- a/include/net/neighbour.h
++++ b/include/net/neighbour.h
+@@ -448,6 +448,7 @@ static inline int neigh_hh_bridge(struct hh_cache *hh, struct sk_buff *skb)
+
+ static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb)
+ {
++ unsigned int hh_alen = 0;
+ unsigned int seq;
+ int hh_len;
+
+@@ -455,16 +456,33 @@ static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb
+ seq = read_seqbegin(&hh->hh_lock);
+ hh_len = hh->hh_len;
+ if (likely(hh_len <= HH_DATA_MOD)) {
+- /* this is inlined by gcc */
+- memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD);
++ hh_alen = HH_DATA_MOD;
++
++ /* skb_push() would proceed silently if we have room for
++ * the unaligned size but not for the aligned size:
++ * check headroom explicitly.
++ */
++ if (likely(skb_headroom(skb) >= HH_DATA_MOD)) {
++ /* this is inlined by gcc */
++ memcpy(skb->data - HH_DATA_MOD, hh->hh_data,
++ HH_DATA_MOD);
++ }
+ } else {
+- int hh_alen = HH_DATA_ALIGN(hh_len);
++ hh_alen = HH_DATA_ALIGN(hh_len);
+
+- memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
++ if (likely(skb_headroom(skb) >= hh_alen)) {
++ memcpy(skb->data - hh_alen, hh->hh_data,
++ hh_alen);
++ }
+ }
+ } while (read_seqretry(&hh->hh_lock, seq));
+
+- skb_push(skb, hh_len);
++ if (WARN_ON_ONCE(skb_headroom(skb) < hh_alen)) {
++ kfree_skb(skb);
++ return NET_XMIT_DROP;
++ }
++
++ __skb_push(skb, hh_len);
+ return dev_queue_xmit(skb);
+ }
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-009-ARM-OMAP2-prm44xx-Fix-section-annotation-on-o.patch b/patches.kernel.org/4.4.168-009-ARM-OMAP2-prm44xx-Fix-section-annotation-on-o.patch
new file mode 100644
index 0000000000..ed881aeebc
--- /dev/null
+++ b/patches.kernel.org/4.4.168-009-ARM-OMAP2-prm44xx-Fix-section-annotation-on-o.patch
@@ -0,0 +1,48 @@
+From: Nathan Chancellor <natechancellor@gmail.com>
+Date: Wed, 17 Oct 2018 17:54:00 -0700
+Subject: [PATCH] ARM: OMAP2+: prm44xx: Fix section annotation on
+ omap44xx_prm_enable_io_wakeup
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: eef3dc34a1e0b01d53328b88c25237bcc7323777
+
+[ Upstream commit eef3dc34a1e0b01d53328b88c25237bcc7323777 ]
+
+When building the kernel with Clang, the following section mismatch
+warning appears:
+
+WARNING: vmlinux.o(.text+0x38b3c): Section mismatch in reference from
+the function omap44xx_prm_late_init() to the function
+.init.text:omap44xx_prm_enable_io_wakeup()
+The function omap44xx_prm_late_init() references
+the function __init omap44xx_prm_enable_io_wakeup().
+This is often because omap44xx_prm_late_init lacks a __init
+annotation or the annotation of omap44xx_prm_enable_io_wakeup is wrong.
+
+Remove the __init annotation from omap44xx_prm_enable_io_wakeup so there
+is no more mismatch.
+
+Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/arm/mach-omap2/prm44xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
+index 30768003f854..8c505284bc0c 100644
+--- a/arch/arm/mach-omap2/prm44xx.c
++++ b/arch/arm/mach-omap2/prm44xx.c
+@@ -344,7 +344,7 @@ static void omap44xx_prm_reconfigure_io_chain(void)
+ * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
+ * omap44xx_prm_reconfigure_io_chain() must be called. No return value.
+ */
+-static void __init omap44xx_prm_enable_io_wakeup(void)
++static void omap44xx_prm_enable_io_wakeup(void)
+ {
+ s32 inst = omap4_prmst_get_prm_dev_inst();
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-010-ARM-OMAP1-ams-delta-Fix-possible-use-of-unini.patch b/patches.kernel.org/4.4.168-010-ARM-OMAP1-ams-delta-Fix-possible-use-of-unini.patch
new file mode 100644
index 0000000000..bbe53bdee9
--- /dev/null
+++ b/patches.kernel.org/4.4.168-010-ARM-OMAP1-ams-delta-Fix-possible-use-of-unini.patch
@@ -0,0 +1,44 @@
+From: Janusz Krzysztofik <jmkrzyszt@gmail.com>
+Date: Wed, 7 Nov 2018 22:30:31 +0100
+Subject: [PATCH] ARM: OMAP1: ams-delta: Fix possible use of uninitialized
+ field
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: cec83ff1241ec98113a19385ea9e9cfa9aa4125b
+
+[ Upstream commit cec83ff1241ec98113a19385ea9e9cfa9aa4125b ]
+
+While playing with initialization order of modem device, it has been
+discovered that under some circumstances (early console init, I
+believe) its .pm() callback may be called before the
+uart_port->private_data pointer is initialized from
+plat_serial8250_port->private_data, resulting in NULL pointer
+dereference. Fix it by checking for uninitialized pointer before using
+it in modem_pm().
+
+Fixes: aabf31737a6a ("ARM: OMAP1: ams-delta: update the modem to use regulator API")
+Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/arm/mach-omap1/board-ams-delta.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
+index a95499ea8706..fa1d41edce68 100644
+--- a/arch/arm/mach-omap1/board-ams-delta.c
++++ b/arch/arm/mach-omap1/board-ams-delta.c
+@@ -511,6 +511,9 @@ static void modem_pm(struct uart_port *port, unsigned int state, unsigned old)
+ {
+ struct modem_private_data *priv = port->private_data;
+
++ if (!priv)
++ return;
++
+ if (IS_ERR(priv->regulator))
+ return;
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-011-sysv-return-err-instead-of-0-in-__sysv_write_.patch b/patches.kernel.org/4.4.168-011-sysv-return-err-instead-of-0-in-__sysv_write_.patch
new file mode 100644
index 0000000000..f92ba1dc2f
--- /dev/null
+++ b/patches.kernel.org/4.4.168-011-sysv-return-err-instead-of-0-in-__sysv_write_.patch
@@ -0,0 +1,42 @@
+From: YueHaibing <yuehaibing@huawei.com>
+Date: Sat, 10 Nov 2018 04:13:24 +0000
+Subject: [PATCH] sysv: return 'err' instead of 0 in __sysv_write_inode
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: c4b7d1ba7d263b74bb72e9325262a67139605cde
+
+[ Upstream commit c4b7d1ba7d263b74bb72e9325262a67139605cde ]
+
+Fixes gcc '-Wunused-but-set-variable' warning:
+
+fs/sysv/inode.c: In function '__sysv_write_inode':
+fs/sysv/inode.c:239:6: warning:
+ variable 'err' set but not used [-Wunused-but-set-variable]
+
+__sysv_write_inode should return 'err' instead of 0
+
+Fixes: 05459ca81ac3 ("repair sysv_write_inode(), switch sysv to simple_fsync()")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/sysv/inode.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
+index 02fa1dcc5969..29f5b2e589a1 100644
+--- a/fs/sysv/inode.c
++++ b/fs/sysv/inode.c
+@@ -275,7 +275,7 @@ static int __sysv_write_inode(struct inode *inode, int wait)
+ }
+ }
+ brelse(bh);
+- return 0;
++ return err;
+ }
+
+ int sysv_write_inode(struct inode *inode, struct writeback_control *wbc)
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-012-s390-cpum_cf-Reject-request-for-sampling-in-e.patch b/patches.kernel.org/4.4.168-012-s390-cpum_cf-Reject-request-for-sampling-in-e.patch
new file mode 100644
index 0000000000..1bb7d139d9
--- /dev/null
+++ b/patches.kernel.org/4.4.168-012-s390-cpum_cf-Reject-request-for-sampling-in-e.patch
@@ -0,0 +1,117 @@
+From: Thomas Richter <tmricht@linux.ibm.com>
+Date: Tue, 13 Nov 2018 15:38:22 +0000
+Subject: [PATCH] s390/cpum_cf: Reject request for sampling in event
+ initialization
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 613a41b0d16e617f46776a93b975a1eeea96417c
+
+[ Upstream commit 613a41b0d16e617f46776a93b975a1eeea96417c ]
+
+On s390 command perf top fails
+[root@s35lp76 perf] # ./perf top -F100000 --stdio
+ Error:
+ cycles: PMU Hardware doesn't support sampling/overflow-interrupts.
+ Try 'perf stat'
+[root@s35lp76 perf] #
+
+Using event -e rb0000 works as designed. Event rb0000 is the event
+number of the sampling facility for basic sampling.
+
+During system start up the following PMUs are installed in the kernel's
+PMU list (from head to tail):
+ cpum_cf --> s390 PMU counter facility device driver
+ cpum_sf --> s390 PMU sampling facility device driver
+ uprobe
+ kprobe
+ tracepoint
+ task_clock
+ cpu_clock
+
+Perf top executes following functions and calls perf_event_open(2) system
+call with different parameters many times:
+
+cmd_top
+--> __cmd_top
+ --> perf_evlist__add_default
+ --> __perf_evlist__add_default
+ --> perf_evlist__new_cycles (creates event type:0 (HW)
+ config 0 (CPU_CYCLES)
+ --> perf_event_attr__set_max_precise_ip
+ Uses perf_event_open(2) to detect correct
+ precise_ip level. Fails 3 times on s390 which is ok.
+
+Then functions cmd_top
+--> __cmd_top
+ --> perf_top__start_counters
+ -->perf_evlist__config
+ --> perf_can_comm_exec
+ --> perf_probe_api
+ This functions test support for the following events:
+ "cycles:u", "instructions:u", "cpu-clock:u" using
+ --> perf_do_probe_api
+ --> perf_event_open_cloexec
+ Test the close on exec flag support with
+ perf_event_open(2).
+ perf_do_probe_api returns true if the event is
+ supported.
+ The function returns true because event cpu-clock is
+ supported by the PMU cpu_clock.
+ This is achieved by many calls to perf_event_open(2).
+
+Function perf_top__start_counters now calls perf_evsel__open() for every
+event, which is the default event cpu_cycles (config:0) and type HARDWARE
+(type:0) which a predfined frequence of 4000.
+
+Given the above order of the PMU list, the PMU cpum_cf gets called first
+and returns 0, which indicates support for this sampling. The event is
+fully allocated in the function perf_event_open (file kernel/event/core.c
+near line 10521 and the following check fails:
+
+ event = perf_event_alloc(&attr, cpu, task, group_leader, NULL,
+ NULL, NULL, cgroup_fd);
+ if (IS_ERR(event)) {
+ err = PTR_ERR(event);
+ goto err_cred;
+ }
+
+ if (is_sampling_event(event)) {
+ if (event->pmu->capabilities & PERF_PMU_CAP_NO_INTERRUPT) {
+ err = -EOPNOTSUPP;
+ goto err_alloc;
+ }
+ }
+
+The check for the interrupt capabilities fails and the system call
+perf_event_open() returns -EOPNOTSUPP (-95).
+
+Add a check to return -ENODEV when sampling is requested in PMU cpum_cf.
+This allows common kernel code in the perf_event_open() system call to
+test the next PMU in above list.
+
+Fixes: 97b1198fece0 (" "s390, perf: Use common PMU interrupt disabled code")
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Reviewed-by: Hendrik Brueckner <brueckner@linux.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/s390/kernel/perf_cpum_cf.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
+index 929c147e07b4..1b69bfdf59f9 100644
+--- a/arch/s390/kernel/perf_cpum_cf.c
++++ b/arch/s390/kernel/perf_cpum_cf.c
+@@ -344,6 +344,8 @@ static int __hw_perf_event_init(struct perf_event *event)
+ break;
+
+ case PERF_TYPE_HARDWARE:
++ if (is_sampling_event(event)) /* No sampling support */
++ return -ENOENT;
+ ev = attr->config;
+ /* Count user space (problem-state) only */
+ if (!attr->exclude_user && attr->exclude_kernel) {
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-013-hwmon-ina2xx-Fix-current-value-calculation.patch b/patches.kernel.org/4.4.168-013-hwmon-ina2xx-Fix-current-value-calculation.patch
new file mode 100644
index 0000000000..6abf7ab434
--- /dev/null
+++ b/patches.kernel.org/4.4.168-013-hwmon-ina2xx-Fix-current-value-calculation.patch
@@ -0,0 +1,42 @@
+From: Nicolin Chen <nicoleotsuka@gmail.com>
+Date: Tue, 13 Nov 2018 19:48:54 -0800
+Subject: [PATCH] hwmon: (ina2xx) Fix current value calculation
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 38cd989ee38c16388cde89db5b734f9d55b905f9
+
+[ Upstream commit 38cd989ee38c16388cde89db5b734f9d55b905f9 ]
+
+The current register (04h) has a sign bit at MSB. The comments
+for this calculation also mention that it's a signed register.
+
+However, the regval is unsigned type so result of calculation
+turns out to be an incorrect value when current is negative.
+
+This patch simply fixes this by adding a casting to s16.
+
+Fixes: 5d389b125186c ("hwmon: (ina2xx) Make calibration register value fixed")
+Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/hwmon/ina2xx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
+index 9ac6e1673375..1f291b344178 100644
+--- a/drivers/hwmon/ina2xx.c
++++ b/drivers/hwmon/ina2xx.c
+@@ -273,7 +273,7 @@ static int ina2xx_get_value(struct ina2xx_data *data, u8 reg,
+ break;
+ case INA2XX_CURRENT:
+ /* signed register, result in mA */
+- val = regval * data->current_lsb_uA;
++ val = (s16)regval * data->current_lsb_uA;
+ val = DIV_ROUND_CLOSEST(val, 1000);
+ break;
+ case INA2XX_CALIBRATION:
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-014-ASoC-dapm-Recalculate-audio-map-forcely-when-.patch b/patches.kernel.org/4.4.168-014-ASoC-dapm-Recalculate-audio-map-forcely-when-.patch
new file mode 100644
index 0000000000..3e8c392edd
--- /dev/null
+++ b/patches.kernel.org/4.4.168-014-ASoC-dapm-Recalculate-audio-map-forcely-when-.patch
@@ -0,0 +1,61 @@
+From: Tzung-Bi Shih <tzungbi@google.com>
+Date: Wed, 14 Nov 2018 17:06:13 +0800
+Subject: [PATCH] ASoC: dapm: Recalculate audio map forcely when card
+ instantiated
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 882eab6c28d23a970ae73b7eb831b169a672d456
+
+[ Upstream commit 882eab6c28d23a970ae73b7eb831b169a672d456 ]
+
+Audio map are possible in wrong state before card->instantiated has
+been set to true. Imaging the following examples:
+
+time 1: at the beginning
+
+ in:-1 in:-1 in:-1 in:-1
+ out:-1 out:-1 out:-1 out:-1
+ SIGGEN A B Spk
+
+time 2: after someone called snd_soc_dapm_new_widgets()
+(e.g. create_fill_widget_route_map() in sound/soc/codecs/hdac_hdmi.c)
+
+ in:1 in:0 in:0 in:0
+ out:0 out:0 out:0 out:1
+ SIGGEN A B Spk
+
+time 3: routes added
+
+ in:1 in:0 in:0 in:0
+ out:0 out:0 out:0 out:1
+ SIGGEN -----> A -----> B ---> Spk
+
+In the end, the path should be powered on but it did not. At time 3,
+"in" of SIGGEN and "out" of Spk did not propagate to their neighbors
+because snd_soc_dapm_add_path() will not invalidate the paths if
+the card has not instantiated (i.e. card->instantiated is false).
+To correct the state of audio map, recalculate the whole map forcely.
+
+Signed-off-by: Tzung-Bi Shih <tzungbi@google.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ sound/soc/soc-core.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
+index fa6b74a304a7..b927f9c81d92 100644
+--- a/sound/soc/soc-core.c
++++ b/sound/soc/soc-core.c
+@@ -1711,6 +1711,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
+ }
+
+ card->instantiated = 1;
++ dapm_mark_endpoints_dirty(card);
+ snd_soc_dapm_sync(&card->dapm);
+ mutex_unlock(&card->mutex);
+ mutex_unlock(&client_mutex);
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-015-hwmon-w83795-temp4_type-has-writable-permissi.patch b/patches.kernel.org/4.4.168-015-hwmon-w83795-temp4_type-has-writable-permissi.patch
new file mode 100644
index 0000000000..c41beff9e7
--- /dev/null
+++ b/patches.kernel.org/4.4.168-015-hwmon-w83795-temp4_type-has-writable-permissi.patch
@@ -0,0 +1,38 @@
+From: Huacai Chen <chenhc@lemote.com>
+Date: Thu, 15 Nov 2018 10:44:57 +0800
+Subject: [PATCH] hwmon: (w83795) temp4_type has writable permission
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 09aaf6813cfca4c18034fda7a43e68763f34abb1
+
+[ Upstream commit 09aaf6813cfca4c18034fda7a43e68763f34abb1 ]
+
+Both datasheet and comments of store_temp_mode() tell us that temp1~4_type
+is writable, so fix it.
+
+Signed-off-by: Yao Wang <wangyao@lemote.com>
+Signed-off-by: Huacai Chen <chenhc@lemote.com>
+Fixes: 39deb6993e7c (" hwmon: (w83795) Simplify temperature sensor type handling")
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/hwmon/w83795.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
+index 49276bbdac3d..1bb80f992aa8 100644
+--- a/drivers/hwmon/w83795.c
++++ b/drivers/hwmon/w83795.c
+@@ -1691,7 +1691,7 @@ store_sf_setup(struct device *dev, struct device_attribute *attr,
+ * somewhere else in the code
+ */
+ #define SENSOR_ATTR_TEMP(index) { \
+- SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \
++ SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 5 ? S_IWUSR : 0), \
+ show_temp_mode, store_temp_mode, NOT_USED, index - 1), \
+ SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp, \
+ NULL, TEMP_READ, index - 1), \
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-016-Btrfs-send-fix-infinite-loop-due-to-directory.patch b/patches.kernel.org/4.4.168-016-Btrfs-send-fix-infinite-loop-due-to-directory.patch
new file mode 100644
index 0000000000..88e78a58bf
--- /dev/null
+++ b/patches.kernel.org/4.4.168-016-Btrfs-send-fix-infinite-loop-due-to-directory.patch
@@ -0,0 +1,204 @@
+From: Robbie Ko <robbieko@synology.com>
+Date: Wed, 14 Nov 2018 18:32:37 +0000
+Subject: [PATCH] Btrfs: send, fix infinite loop due to directory rename
+ dependencies
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: a4390aee72713d9e73f1132bcdeb17d72fbbf974
+
+[ Upstream commit a4390aee72713d9e73f1132bcdeb17d72fbbf974 ]
+
+When doing an incremental send, due to the need of delaying directory move
+(rename) operations we can end up in infinite loop at
+apply_children_dir_moves().
+
+An example scenario that triggers this problem is described below, where
+directory names correspond to the numbers of their respective inodes.
+
+Parent snapshot:
+
+ .
+ |--- 261/
+ |--- 271/
+ |--- 266/
+ |--- 259/
+ |--- 260/
+ | |--- 267
+ |
+ |--- 264/
+ | |--- 258/
+ | |--- 257/
+ |
+ |--- 265/
+ |--- 268/
+ |--- 269/
+ | |--- 262/
+ |
+ |--- 270/
+ |--- 272/
+ | |--- 263/
+ | |--- 275/
+ |
+ |--- 274/
+ |--- 273/
+
+Send snapshot:
+
+ .
+ |-- 275/
+ |-- 274/
+ |-- 273/
+ |-- 262/
+ |-- 269/
+ |-- 258/
+ |-- 271/
+ |-- 268/
+ |-- 267/
+ |-- 270/
+ |-- 259/
+ | |-- 265/
+ |
+ |-- 272/
+ |-- 257/
+ |-- 260/
+ |-- 264/
+ |-- 263/
+ |-- 261/
+ |-- 266/
+
+When processing inode 257 we delay its move (rename) operation because its
+new parent in the send snapshot, inode 272, was not yet processed. Then
+when processing inode 272, we delay the move operation for that inode
+because inode 274 is its ancestor in the send snapshot. Finally we delay
+the move operation for inode 274 when processing it because inode 275 is
+its new parent in the send snapshot and was not yet moved.
+
+When finishing processing inode 275, we start to do the move operations
+that were previously delayed (at apply_children_dir_moves()), resulting in
+the following iterations:
+
+1) We issue the move operation for inode 274;
+
+2) Because inode 262 depended on the move operation of inode 274 (it was
+ delayed because 274 is its ancestor in the send snapshot), we issue the
+ move operation for inode 262;
+
+3) We issue the move operation for inode 272, because it was delayed by
+ inode 274 too (ancestor of 272 in the send snapshot);
+
+4) We issue the move operation for inode 269 (it was delayed by 262);
+
+5) We issue the move operation for inode 257 (it was delayed by 272);
+
+6) We issue the move operation for inode 260 (it was delayed by 272);
+
+7) We issue the move operation for inode 258 (it was delayed by 269);
+
+8) We issue the move operation for inode 264 (it was delayed by 257);
+
+9) We issue the move operation for inode 271 (it was delayed by 258);
+
+10) We issue the move operation for inode 263 (it was delayed by 264);
+
+11) We issue the move operation for inode 268 (it was delayed by 271);
+
+12) We verify if we can issue the move operation for inode 270 (it was
+ delayed by 271). We detect a path loop in the current state, because
+ inode 267 needs to be moved first before we can issue the move
+ operation for inode 270. So we delay again the move operation for
+ inode 270, this time we will attempt to do it after inode 267 is
+ moved;
+
+13) We issue the move operation for inode 261 (it was delayed by 263);
+
+14) We verify if we can issue the move operation for inode 266 (it was
+ delayed by 263). We detect a path loop in the current state, because
+ inode 270 needs to be moved first before we can issue the move
+ operation for inode 266. So we delay again the move operation for
+ inode 266, this time we will attempt to do it after inode 270 is
+ moved (its move operation was delayed in step 12);
+
+15) We issue the move operation for inode 267 (it was delayed by 268);
+
+16) We verify if we can issue the move operation for inode 266 (it was
+ delayed by 270). We detect a path loop in the current state, because
+ inode 270 needs to be moved first before we can issue the move
+ operation for inode 266. So we delay again the move operation for
+ inode 266, this time we will attempt to do it after inode 270 is
+ moved (its move operation was delayed in step 12). So here we added
+ again the same delayed move operation that we added in step 14;
+
+17) We attempt again to see if we can issue the move operation for inode
+ 266, and as in step 16, we realize we can not due to a path loop in
+ the current state due to a dependency on inode 270. Again we delay
+ inode's 266 rename to happen after inode's 270 move operation, adding
+ the same dependency to the empty stack that we did in steps 14 and 16.
+ The next iteration will pick the same move dependency on the stack
+ (the only entry) and realize again there is still a path loop and then
+ again the same dependency to the stack, over and over, resulting in
+ an infinite loop.
+
+So fix this by preventing adding the same move dependency entries to the
+stack by removing each pending move record from the red black tree of
+pending moves. This way the next call to get_pending_dir_moves() will
+not return anything for the current parent inode.
+
+A test case for fstests, with this reproducer, follows soon.
+
+Signed-off-by: Robbie Ko <robbieko@synology.com>
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+[Wrote changelog with example and more clear explanation]
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/btrfs/send.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index 83c73738165e..40d1ab957fb6 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -3232,7 +3232,8 @@ static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m)
+ kfree(m);
+ }
+
+-static void tail_append_pending_moves(struct pending_dir_move *moves,
++static void tail_append_pending_moves(struct send_ctx *sctx,
++ struct pending_dir_move *moves,
+ struct list_head *stack)
+ {
+ if (list_empty(&moves->list)) {
+@@ -3243,6 +3244,10 @@ static void tail_append_pending_moves(struct pending_dir_move *moves,
+ list_add_tail(&moves->list, stack);
+ list_splice_tail(&list, stack);
+ }
++ if (!RB_EMPTY_NODE(&moves->node)) {
++ rb_erase(&moves->node, &sctx->pending_dir_moves);
++ RB_CLEAR_NODE(&moves->node);
++ }
+ }
+
+ static int apply_children_dir_moves(struct send_ctx *sctx)
+@@ -3257,7 +3262,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx)
+ return 0;
+
+ INIT_LIST_HEAD(&stack);
+- tail_append_pending_moves(pm, &stack);
++ tail_append_pending_moves(sctx, pm, &stack);
+
+ while (!list_empty(&stack)) {
+ pm = list_first_entry(&stack, struct pending_dir_move, list);
+@@ -3268,7 +3273,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx)
+ goto out;
+ pm = get_pending_dir_moves(sctx, parent_ino);
+ if (pm)
+- tail_append_pending_moves(pm, &stack);
++ tail_append_pending_moves(sctx, pm, &stack);
+ }
+ return 0;
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-017-ASoC-omap-mcpdm-Add-pm_qos-handling-to-avoid-.patch b/patches.kernel.org/4.4.168-017-ASoC-omap-mcpdm-Add-pm_qos-handling-to-avoid-.patch
new file mode 100644
index 0000000000..21ffc75f1e
--- /dev/null
+++ b/patches.kernel.org/4.4.168-017-ASoC-omap-mcpdm-Add-pm_qos-handling-to-avoid-.patch
@@ -0,0 +1,130 @@
+From: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Date: Wed, 14 Nov 2018 13:06:22 +0200
+Subject: [PATCH] ASoC: omap-mcpdm: Add pm_qos handling to avoid under/overruns
+ with CPU_IDLE
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 373a500e34aea97971c9d71e45edad458d3da98f
+
+[ Upstream commit 373a500e34aea97971c9d71e45edad458d3da98f ]
+
+We need to block sleep states which would require longer time to leave than
+the time the DMA must react to the DMA request in order to keep the FIFO
+serviced without under of overrun.
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Acked-by: Jarkko Nikula <jarkko.nikula@bitmer.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ sound/soc/omap/omap-mcpdm.c | 43 ++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 42 insertions(+), 1 deletion(-)
+
+diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
+index 8d0d45d330e7..8eb2d12b6a34 100644
+--- a/sound/soc/omap/omap-mcpdm.c
++++ b/sound/soc/omap/omap-mcpdm.c
+@@ -54,6 +54,8 @@ struct omap_mcpdm {
+ unsigned long phys_base;
+ void __iomem *io_base;
+ int irq;
++ struct pm_qos_request pm_qos_req;
++ int latency[2];
+
+ struct mutex mutex;
+
+@@ -273,6 +275,9 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
++ int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
++ int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
++ int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
+
+ mutex_lock(&mcpdm->mutex);
+
+@@ -285,6 +290,14 @@ static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
+ }
+ }
+
++ if (mcpdm->latency[stream2])
++ pm_qos_update_request(&mcpdm->pm_qos_req,
++ mcpdm->latency[stream2]);
++ else if (mcpdm->latency[stream1])
++ pm_qos_remove_request(&mcpdm->pm_qos_req);
++
++ mcpdm->latency[stream1] = 0;
++
+ mutex_unlock(&mcpdm->mutex);
+ }
+
+@@ -296,7 +309,7 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
+ int stream = substream->stream;
+ struct snd_dmaengine_dai_dma_data *dma_data;
+ u32 threshold;
+- int channels;
++ int channels, latency;
+ int link_mask = 0;
+
+ channels = params_channels(params);
+@@ -336,14 +349,25 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
+
+ dma_data->maxburst =
+ (MCPDM_DN_THRES_MAX - threshold) * channels;
++ latency = threshold;
+ } else {
+ /* If playback is not running assume a stereo stream to come */
+ if (!mcpdm->config[!stream].link_mask)
+ mcpdm->config[!stream].link_mask = (0x3 << 3);
+
+ dma_data->maxburst = threshold * channels;
++ latency = (MCPDM_DN_THRES_MAX - threshold);
+ }
+
++ /*
++ * The DMA must act to a DMA request within latency time (usec) to avoid
++ * under/overflow
++ */
++ mcpdm->latency[stream] = latency * USEC_PER_SEC / params_rate(params);
++
++ if (!mcpdm->latency[stream])
++ mcpdm->latency[stream] = 10;
++
+ /* Check if we need to restart McPDM with this stream */
+ if (mcpdm->config[stream].link_mask &&
+ mcpdm->config[stream].link_mask != link_mask)
+@@ -358,6 +382,20 @@ static int omap_mcpdm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+ {
+ struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
++ struct pm_qos_request *pm_qos_req = &mcpdm->pm_qos_req;
++ int tx = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
++ int stream1 = tx ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
++ int stream2 = tx ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
++ int latency = mcpdm->latency[stream2];
++
++ /* Prevent omap hardware from hitting off between FIFO fills */
++ if (!latency || mcpdm->latency[stream1] < latency)
++ latency = mcpdm->latency[stream1];
++
++ if (pm_qos_request_active(pm_qos_req))
++ pm_qos_update_request(pm_qos_req, latency);
++ else if (latency)
++ pm_qos_add_request(pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency);
+
+ if (!omap_mcpdm_active(mcpdm)) {
+ omap_mcpdm_start(mcpdm);
+@@ -419,6 +457,9 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
+ free_irq(mcpdm->irq, (void *)mcpdm);
+ pm_runtime_disable(mcpdm->dev);
+
++ if (pm_qos_request_active(&mcpdm->pm_qos_req))
++ pm_qos_remove_request(&mcpdm->pm_qos_req);
++
+ return 0;
+ }
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-018-ASoC-omap-dmic-Add-pm_qos-handling-to-avoid-o.patch b/patches.kernel.org/4.4.168-018-ASoC-omap-dmic-Add-pm_qos-handling-to-avoid-o.patch
new file mode 100644
index 0000000000..d78ca67474
--- /dev/null
+++ b/patches.kernel.org/4.4.168-018-ASoC-omap-dmic-Add-pm_qos-handling-to-avoid-o.patch
@@ -0,0 +1,67 @@
+From: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Date: Wed, 14 Nov 2018 13:06:23 +0200
+Subject: [PATCH] ASoC: omap-dmic: Add pm_qos handling to avoid overruns with
+ CPU_IDLE
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: ffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb
+
+[ Upstream commit ffdcc3638c58d55a6fa68b6e5dfd4fb4109652eb ]
+
+We need to block sleep states which would require longer time to leave than
+the time the DMA must react to the DMA request in order to keep the FIFO
+serviced without overrun.
+
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
+Acked-by: Jarkko Nikula <jarkko.nikula@bitmer.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ sound/soc/omap/omap-dmic.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c
+index 09db2aec12a3..776e809a8aab 100644
+--- a/sound/soc/omap/omap-dmic.c
++++ b/sound/soc/omap/omap-dmic.c
+@@ -48,6 +48,8 @@ struct omap_dmic {
+ struct device *dev;
+ void __iomem *io_base;
+ struct clk *fclk;
++ struct pm_qos_request pm_qos_req;
++ int latency;
+ int fclk_freq;
+ int out_freq;
+ int clk_div;
+@@ -124,6 +126,8 @@ static void omap_dmic_dai_shutdown(struct snd_pcm_substream *substream,
+
+ mutex_lock(&dmic->mutex);
+
++ pm_qos_remove_request(&dmic->pm_qos_req);
++
+ if (!dai->active)
+ dmic->active = 0;
+
+@@ -226,6 +230,8 @@ static int omap_dmic_dai_hw_params(struct snd_pcm_substream *substream,
+ /* packet size is threshold * channels */
+ dma_data = snd_soc_dai_get_dma_data(dai, substream);
+ dma_data->maxburst = dmic->threshold * channels;
++ dmic->latency = (OMAP_DMIC_THRES_MAX - dmic->threshold) * USEC_PER_SEC /
++ params_rate(params);
+
+ return 0;
+ }
+@@ -236,6 +242,9 @@ static int omap_dmic_dai_prepare(struct snd_pcm_substream *substream,
+ struct omap_dmic *dmic = snd_soc_dai_get_drvdata(dai);
+ u32 ctrl;
+
++ if (pm_qos_request_active(&dmic->pm_qos_req))
++ pm_qos_update_request(&dmic->pm_qos_req, dmic->latency);
++
+ /* Configure uplink threshold */
+ omap_dmic_write(dmic, OMAP_DMIC_FIFO_CTRL_REG, dmic->threshold);
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-019-exportfs-do-not-read-dentry-after-free.patch b/patches.kernel.org/4.4.168-019-exportfs-do-not-read-dentry-after-free.patch
new file mode 100644
index 0000000000..e07011366c
--- /dev/null
+++ b/patches.kernel.org/4.4.168-019-exportfs-do-not-read-dentry-after-free.patch
@@ -0,0 +1,43 @@
+From: Pan Bian <bianpan2016@163.com>
+Date: Fri, 23 Nov 2018 15:56:33 +0800
+Subject: [PATCH] exportfs: do not read dentry after free
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 2084ac6c505a58f7efdec13eba633c6aaa085ca5
+
+[ Upstream commit 2084ac6c505a58f7efdec13eba633c6aaa085ca5 ]
+
+The function dentry_connected calls dput(dentry) to drop the previously
+acquired reference to dentry. In this case, dentry can be released.
+After that, IS_ROOT(dentry) checks the condition
+(dentry == dentry->d_parent), which may result in a use-after-free bug.
+This patch directly compares dentry with its parent obtained before
+dropping the reference.
+
+Fixes: a056cc8934c("exportfs: stop retrying once we race with
+rename/remove")
+
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/exportfs/expfs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
+index 714cd37a6ba3..6599c6124552 100644
+--- a/fs/exportfs/expfs.c
++++ b/fs/exportfs/expfs.c
+@@ -76,7 +76,7 @@ static bool dentry_connected(struct dentry *dentry)
+ struct dentry *parent = dget_parent(dentry);
+
+ dput(dentry);
+- if (IS_ROOT(dentry)) {
++ if (dentry == parent) {
+ dput(parent);
+ return false;
+ }
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-020-bpf-fix-check-of-allowed-specifiers-in-bpf_tr.patch b/patches.kernel.org/4.4.168-020-bpf-fix-check-of-allowed-specifiers-in-bpf_tr.patch
new file mode 100644
index 0000000000..9a30881b58
--- /dev/null
+++ b/patches.kernel.org/4.4.168-020-bpf-fix-check-of-allowed-specifiers-in-bpf_tr.patch
@@ -0,0 +1,47 @@
+From: Martynas Pumputis <m@lambda.lt>
+Date: Fri, 23 Nov 2018 17:43:26 +0100
+Subject: [PATCH] bpf: fix check of allowed specifiers in bpf_trace_printk
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 1efb6ee3edea57f57f9fb05dba8dcb3f7333f61f
+
+[ Upstream commit 1efb6ee3edea57f57f9fb05dba8dcb3f7333f61f ]
+
+A format string consisting of "%p" or "%s" followed by an invalid
+specifier (e.g. "%p%\n" or "%s%") could pass the check which
+would make format_decode (lib/vsprintf.c) to warn.
+
+Fixes: 9c959c863f82 ("tracing: Allow BPF programs to call bpf_trace_printk()")
+Reported-by: syzbot+1ec5c5ec949c4adaa0c4@syzkaller.appspotmail.com
+Signed-off-by: Martynas Pumputis <m@lambda.lt>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ kernel/trace/bpf_trace.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index 4228fd3682c3..3dd40c736067 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -119,11 +119,13 @@ static u64 bpf_trace_printk(u64 r1, u64 fmt_size, u64 r3, u64 r4, u64 r5)
+ i++;
+ } else if (fmt[i] == 'p' || fmt[i] == 's') {
+ mod[fmt_cnt]++;
+- i++;
+- if (!isspace(fmt[i]) && !ispunct(fmt[i]) && fmt[i] != 0)
++ /* disallow any further format extensions */
++ if (fmt[i + 1] != 0 &&
++ !isspace(fmt[i + 1]) &&
++ !ispunct(fmt[i + 1]))
+ return -EINVAL;
+ fmt_cnt++;
+- if (fmt[i - 1] == 's') {
++ if (fmt[i] == 's') {
+ if (str_seen)
+ /* allow only one '%s' per fmt string */
+ return -EINVAL;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-021-USB-omap_udc-use-devm_request_irq.patch b/patches.kernel.org/4.4.168-021-USB-omap_udc-use-devm_request_irq.patch
new file mode 100644
index 0000000000..b742d1ecb0
--- /dev/null
+++ b/patches.kernel.org/4.4.168-021-USB-omap_udc-use-devm_request_irq.patch
@@ -0,0 +1,105 @@
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+Date: Sun, 25 Nov 2018 00:17:04 +0200
+Subject: [PATCH] USB: omap_udc: use devm_request_irq()
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 286afdde1640d8ea8916a0f05e811441fbbf4b9d
+
+[ Upstream commit 286afdde1640d8ea8916a0f05e811441fbbf4b9d ]
+
+The current code fails to release the third irq on the error path
+(observed by reading the code), and we get also multiple WARNs with
+failing gadget drivers due to duplicate IRQ releases. Fix by using
+devm_request_irq().
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/usb/gadget/udc/omap_udc.c | 37 +++++++++----------------------
+ 1 file changed, 10 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
+index 9b7d39484ed3..b25eac2dcaf8 100644
+--- a/drivers/usb/gadget/udc/omap_udc.c
++++ b/drivers/usb/gadget/udc/omap_udc.c
+@@ -2886,8 +2886,8 @@ static int omap_udc_probe(struct platform_device *pdev)
+ udc->clr_halt = UDC_RESET_EP;
+
+ /* USB general purpose IRQ: ep0, state changes, dma, etc */
+- status = request_irq(pdev->resource[1].start, omap_udc_irq,
+- 0, driver_name, udc);
++ status = devm_request_irq(&pdev->dev, pdev->resource[1].start,
++ omap_udc_irq, 0, driver_name, udc);
+ if (status != 0) {
+ ERR("can't get irq %d, err %d\n",
+ (int) pdev->resource[1].start, status);
+@@ -2895,20 +2895,20 @@ static int omap_udc_probe(struct platform_device *pdev)
+ }
+
+ /* USB "non-iso" IRQ (PIO for all but ep0) */
+- status = request_irq(pdev->resource[2].start, omap_udc_pio_irq,
+- 0, "omap_udc pio", udc);
++ status = devm_request_irq(&pdev->dev, pdev->resource[2].start,
++ omap_udc_pio_irq, 0, "omap_udc pio", udc);
+ if (status != 0) {
+ ERR("can't get irq %d, err %d\n",
+ (int) pdev->resource[2].start, status);
+- goto cleanup2;
++ goto cleanup1;
+ }
+ #ifdef USE_ISO
+- status = request_irq(pdev->resource[3].start, omap_udc_iso_irq,
+- 0, "omap_udc iso", udc);
++ status = devm_request_irq(&pdev->dev, pdev->resource[3].start,
++ omap_udc_iso_irq, 0, "omap_udc iso", udc);
+ if (status != 0) {
+ ERR("can't get irq %d, err %d\n",
+ (int) pdev->resource[3].start, status);
+- goto cleanup3;
++ goto cleanup1;
+ }
+ #endif
+ if (cpu_is_omap16xx() || cpu_is_omap7xx()) {
+@@ -2921,22 +2921,11 @@ static int omap_udc_probe(struct platform_device *pdev)
+ create_proc_file();
+ status = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
+ omap_udc_release);
+- if (status)
+- goto cleanup4;
+-
+- return 0;
++ if (!status)
++ return 0;
+
+-cleanup4:
+ remove_proc_file();
+
+-#ifdef USE_ISO
+-cleanup3:
+- free_irq(pdev->resource[2].start, udc);
+-#endif
+-
+-cleanup2:
+- free_irq(pdev->resource[1].start, udc);
+-
+ cleanup1:
+ kfree(udc);
+ udc = NULL;
+@@ -2980,12 +2969,6 @@ static int omap_udc_remove(struct platform_device *pdev)
+
+ remove_proc_file();
+
+-#ifdef USE_ISO
+- free_irq(pdev->resource[3].start, udc);
+-#endif
+- free_irq(pdev->resource[2].start, udc);
+- free_irq(pdev->resource[1].start, udc);
+-
+ if (udc->dc_clk) {
+ if (udc->clk_requested)
+ omap_udc_enable_clock(0);
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-022-USB-omap_udc-fix-crashes-on-probe-error-and-m.patch b/patches.kernel.org/4.4.168-022-USB-omap_udc-fix-crashes-on-probe-error-and-m.patch
new file mode 100644
index 0000000000..c5209c7468
--- /dev/null
+++ b/patches.kernel.org/4.4.168-022-USB-omap_udc-fix-crashes-on-probe-error-and-m.patch
@@ -0,0 +1,117 @@
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+Date: Sun, 25 Nov 2018 00:17:05 +0200
+Subject: [PATCH] USB: omap_udc: fix crashes on probe error and module removal
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 99f700366fcea1aa2fa3c49c99f371670c3c62f8
+
+[ Upstream commit 99f700366fcea1aa2fa3c49c99f371670c3c62f8 ]
+
+We currently crash if usb_add_gadget_udc_release() fails, since the
+udc->done is not initialized until in the remove function.
+Furthermore, on module removal the udc data is accessed although
+the release function is already triggered by usb_del_gadget_udc()
+early in the function.
+
+Fix by rewriting the release and remove functions, basically moving
+all the cleanup into the release function, and doing the completion
+only in the module removal case.
+
+The patch fixes omap_udc module probe with a failing gadged, and also
+allows the removal of omap_udc. Tested by running "modprobe omap_udc;
+modprobe -r omap_udc" in a loop.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/usb/gadget/udc/omap_udc.c | 50 ++++++++++++-------------------
+ 1 file changed, 19 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
+index b25eac2dcaf8..da1030f69145 100644
+--- a/drivers/usb/gadget/udc/omap_udc.c
++++ b/drivers/usb/gadget/udc/omap_udc.c
+@@ -2612,9 +2612,22 @@ omap_ep_setup(char *name, u8 addr, u8 type,
+
+ static void omap_udc_release(struct device *dev)
+ {
+- complete(udc->done);
++ pullup_disable(udc);
++ if (!IS_ERR_OR_NULL(udc->transceiver)) {
++ usb_put_phy(udc->transceiver);
++ udc->transceiver = NULL;
++ }
++ omap_writew(0, UDC_SYSCON1);
++ remove_proc_file();
++ if (udc->dc_clk) {
++ if (udc->clk_requested)
++ omap_udc_enable_clock(0);
++ clk_put(udc->hhc_clk);
++ clk_put(udc->dc_clk);
++ }
++ if (udc->done)
++ complete(udc->done);
+ kfree(udc);
+- udc = NULL;
+ }
+
+ static int
+@@ -2919,12 +2932,8 @@ static int omap_udc_probe(struct platform_device *pdev)
+ }
+
+ create_proc_file();
+- status = usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
+- omap_udc_release);
+- if (!status)
+- return 0;
+-
+- remove_proc_file();
++ return usb_add_gadget_udc_release(&pdev->dev, &udc->gadget,
++ omap_udc_release);
+
+ cleanup1:
+ kfree(udc);
+@@ -2951,36 +2960,15 @@ static int omap_udc_remove(struct platform_device *pdev)
+ {
+ DECLARE_COMPLETION_ONSTACK(done);
+
+- if (!udc)
+- return -ENODEV;
+-
+- usb_del_gadget_udc(&udc->gadget);
+- if (udc->driver)
+- return -EBUSY;
+-
+ udc->done = &done;
+
+- pullup_disable(udc);
+- if (!IS_ERR_OR_NULL(udc->transceiver)) {
+- usb_put_phy(udc->transceiver);
+- udc->transceiver = NULL;
+- }
+- omap_writew(0, UDC_SYSCON1);
+-
+- remove_proc_file();
++ usb_del_gadget_udc(&udc->gadget);
+
+- if (udc->dc_clk) {
+- if (udc->clk_requested)
+- omap_udc_enable_clock(0);
+- clk_put(udc->hhc_clk);
+- clk_put(udc->dc_clk);
+- }
++ wait_for_completion(&done);
+
+ release_mem_region(pdev->resource[0].start,
+ pdev->resource[0].end - pdev->resource[0].start + 1);
+
+- wait_for_completion(&done);
+-
+ return 0;
+ }
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-023-USB-omap_udc-fix-omap_udc_start-on-15xx-machi.patch b/patches.kernel.org/4.4.168-023-USB-omap_udc-fix-omap_udc_start-on-15xx-machi.patch
new file mode 100644
index 0000000000..364e7aac36
--- /dev/null
+++ b/patches.kernel.org/4.4.168-023-USB-omap_udc-fix-omap_udc_start-on-15xx-machi.patch
@@ -0,0 +1,44 @@
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+Date: Sun, 25 Nov 2018 00:17:06 +0200
+Subject: [PATCH] USB: omap_udc: fix omap_udc_start() on 15xx machines
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 6ca6695f576b8453fe68865e84d25946d63b10ad
+
+[ Upstream commit 6ca6695f576b8453fe68865e84d25946d63b10ad ]
+
+On OMAP 15xx machines there are no transceivers, and omap_udc_start()
+always fails as it forgot to adjust the default return value.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/usb/gadget/udc/omap_udc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
+index da1030f69145..653963459d78 100644
+--- a/drivers/usb/gadget/udc/omap_udc.c
++++ b/drivers/usb/gadget/udc/omap_udc.c
+@@ -2045,7 +2045,7 @@ static inline int machine_without_vbus_sense(void)
+ static int omap_udc_start(struct usb_gadget *g,
+ struct usb_gadget_driver *driver)
+ {
+- int status = -ENODEV;
++ int status;
+ struct omap_ep *ep;
+ unsigned long flags;
+
+@@ -2083,6 +2083,7 @@ static int omap_udc_start(struct usb_gadget *g,
+ goto done;
+ }
+ } else {
++ status = 0;
+ if (can_pullup(udc))
+ pullup_enable(udc);
+ else
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-024-USB-omap_udc-fix-USB-gadget-functionality-on-.patch b/patches.kernel.org/4.4.168-024-USB-omap_udc-fix-USB-gadget-functionality-on-.patch
new file mode 100644
index 0000000000..30effcadcc
--- /dev/null
+++ b/patches.kernel.org/4.4.168-024-USB-omap_udc-fix-USB-gadget-functionality-on-.patch
@@ -0,0 +1,36 @@
+From: Aaro Koskinen <aaro.koskinen@iki.fi>
+Date: Sun, 25 Nov 2018 00:17:07 +0200
+Subject: [PATCH] USB: omap_udc: fix USB gadget functionality on Palm Tungsten
+ E
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 2c2322fbcab8102b8cadc09d66714700a2da42c2
+
+[ Upstream commit 2c2322fbcab8102b8cadc09d66714700a2da42c2 ]
+
+On Palm TE nothing happens when you try to use gadget drivers and plug
+the USB cable. Fix by adding the board to the vbus sense quirk list.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/usb/gadget/udc/omap_udc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c
+index 653963459d78..d1ed92acafa3 100644
+--- a/drivers/usb/gadget/udc/omap_udc.c
++++ b/drivers/usb/gadget/udc/omap_udc.c
+@@ -2037,6 +2037,7 @@ static inline int machine_without_vbus_sense(void)
+ {
+ return machine_is_omap_innovator()
+ || machine_is_omap_osk()
++ || machine_is_omap_palmte()
+ || machine_is_sx1()
+ /* No known omap7xx boards with vbus sense */
+ || cpu_is_omap7xx();
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-025-KVM-x86-fix-empty-body-warnings.patch b/patches.kernel.org/4.4.168-025-KVM-x86-fix-empty-body-warnings.patch
new file mode 100644
index 0000000000..e88481bd63
--- /dev/null
+++ b/patches.kernel.org/4.4.168-025-KVM-x86-fix-empty-body-warnings.patch
@@ -0,0 +1,46 @@
+From: Yi Wang <wang.yi59@zte.com.cn>
+Date: Thu, 8 Nov 2018 16:48:36 +0800
+Subject: [PATCH] KVM: x86: fix empty-body warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 354cb410d87314e2eda344feea84809e4261570a
+
+[ Upstream commit 354cb410d87314e2eda344feea84809e4261570a ]
+
+We get the following warnings about empty statements when building
+with 'W=1':
+
+arch/x86/kvm/lapic.c:632:53: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
+arch/x86/kvm/lapic.c:1907:42: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
+arch/x86/kvm/lapic.c:1936:65: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
+arch/x86/kvm/lapic.c:1975:44: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
+
+Rework the debug helper macro to get rid of these warnings.
+
+Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/lapic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index a1afd80a68aa..3c70f6c76d3a 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -56,7 +56,7 @@
+ #define APIC_BUS_CYCLE_NS 1
+
+ /* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
+-#define apic_debug(fmt, arg...)
++#define apic_debug(fmt, arg...) do {} while (0)
+
+ #define APIC_LVT_NUM 6
+ /* 14 is the version for Xeon and Pentium 8.4.8*/
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-026-net-thunderx-fix-NULL-pointer-dereference-in-.patch b/patches.kernel.org/4.4.168-026-net-thunderx-fix-NULL-pointer-dereference-in-.patch
new file mode 100644
index 0000000000..9418d29307
--- /dev/null
+++ b/patches.kernel.org/4.4.168-026-net-thunderx-fix-NULL-pointer-dereference-in-.patch
@@ -0,0 +1,85 @@
+From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
+Date: Mon, 26 Nov 2018 15:07:16 +0100
+Subject: [PATCH] net: thunderx: fix NULL pointer dereference in nic_remove
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 24a6d2dd263bc910de018c78d1148b3e33b94512
+
+[ Upstream commit 24a6d2dd263bc910de018c78d1148b3e33b94512 ]
+
+Fix a possible NULL pointer dereference in nic_remove routine
+removing the nicpf module if nic_probe fails.
+The issue can be triggered with the following reproducer:
+
+$rmmod nicvf
+$rmmod nicpf
+
+[ 521.412008] Unable to handle kernel access to user memory outside uaccess routines at virtual address 0000000000000014
+[ 521.422777] Mem abort info:
+[ 521.425561] ESR = 0x96000004
+[ 521.428624] Exception class = DABT (current EL), IL = 32 bits
+[ 521.434535] SET = 0, FnV = 0
+[ 521.437579] EA = 0, S1PTW = 0
+[ 521.440730] Data abort info:
+[ 521.443603] ISV = 0, ISS = 0x00000004
+[ 521.447431] CM = 0, WnR = 0
+[ 521.450417] user pgtable: 4k pages, 48-bit VAs, pgdp = 0000000072a3da42
+[ 521.457022] [0000000000000014] pgd=0000000000000000
+[ 521.461916] Internal error: Oops: 96000004 [#1] SMP
+[ 521.511801] Hardware name: GIGABYTE H270-T70/MT70-HD0, BIOS T49 02/02/2018
+[ 521.518664] pstate: 80400005 (Nzcv daif +PAN -UAO)
+[ 521.523451] pc : nic_remove+0x24/0x88 [nicpf]
+[ 521.527808] lr : pci_device_remove+0x48/0xd8
+[ 521.532066] sp : ffff000013433cc0
+[ 521.535370] x29: ffff000013433cc0 x28: ffff810f6ac50000
+[ 521.540672] x27: 0000000000000000 x26: 0000000000000000
+[ 521.545974] x25: 0000000056000000 x24: 0000000000000015
+[ 521.551274] x23: ffff8007ff89a110 x22: ffff000001667070
+[ 521.556576] x21: ffff8007ffb170b0 x20: ffff8007ffb17000
+[ 521.561877] x19: 0000000000000000 x18: 0000000000000025
+[ 521.567178] x17: 0000000000000000 x16: 000000000000010ffc33ff98 x8 : 0000000000000000
+[ 521.593683] x7 : 0000000000000000 x6 : 0000000000000001
+[ 521.598983] x5 : 0000000000000002 x4 : 0000000000000003
+[ 521.604284] x3 : ffff8007ffb17184 x2 : ffff8007ffb17184
+[ 521.609585] x1 : ffff000001662118 x0 : ffff000008557be0
+[ 521.614887] Process rmmod (pid: 1897, stack limit = 0x00000000859535c3)
+[ 521.621490] Call trace:
+[ 521.623928] nic_remove+0x24/0x88 [nicpf]
+[ 521.627927] pci_device_remove+0x48/0xd8
+[ 521.631847] device_release_driver_internal+0x1b0/0x248
+[ 521.637062] driver_detach+0x50/0xc0
+[ 521.640628] bus_remove_driver+0x60/0x100
+[ 521.644627] driver_unregister+0x34/0x60
+[ 521.648538] pci_unregister_driver+0x24/0xd8
+[ 521.652798] nic_cleanup_module+0x14/0x111c [nicpf]
+[ 521.657672] __arm64_sys_delete_module+0x150/0x218
+[ 521.662460] el0_svc_handler+0x94/0x110
+[ 521.666287] el0_svc+0x8/0xc
+[ 521.669160] Code: aa1e03e0 9102c295 d503201f f9404eb3 (b9401660)
+
+Fixes: 4863dea3fab0 ("net: Adding support for Cavium ThunderX network controller")
+Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/net/ethernet/cavium/thunder/nic_main.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/cavium/thunder/nic_main.c b/drivers/net/ethernet/cavium/thunder/nic_main.c
+index 16baaafed26c..cbdeb54eab51 100644
+--- a/drivers/net/ethernet/cavium/thunder/nic_main.c
++++ b/drivers/net/ethernet/cavium/thunder/nic_main.c
+@@ -1090,6 +1090,9 @@ static void nic_remove(struct pci_dev *pdev)
+ {
+ struct nicpf *nic = pci_get_drvdata(pdev);
+
++ if (!nic)
++ return;
++
+ if (nic->flags & NIC_SRIOV_ENABLED)
+ pci_disable_sriov(pdev);
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-027-ixgbe-recognize-1000BaseLX-SFP-modules-as-1Gb.patch b/patches.kernel.org/4.4.168-027-ixgbe-recognize-1000BaseLX-SFP-modules-as-1Gb.patch
new file mode 100644
index 0000000000..328ab2cbbb
--- /dev/null
+++ b/patches.kernel.org/4.4.168-027-ixgbe-recognize-1000BaseLX-SFP-modules-as-1Gb.patch
@@ -0,0 +1,46 @@
+From: Josh Elsasser <jelsasser@appneta.com>
+Date: Sat, 24 Nov 2018 12:57:33 -0800
+Subject: [PATCH] ixgbe: recognize 1000BaseLX SFP modules as 1Gbps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: a8bf879af7b1999eba36303ce9cc60e0e7dd816c
+
+[ Upstream commit a8bf879af7b1999eba36303ce9cc60e0e7dd816c ]
+
+Add the two 1000BaseLX enum values to the X550's check for 1Gbps modules,
+allowing the core driver code to establish a link over this SFP type.
+
+This is done by the out-of-tree driver but the fix wasn't in mainline.
+
+Fixes: e23f33367882 ("ixgbe: Fix 1G and 10G link stability for X550EM_x SFP+”)
+Fixes: 6a14ee0cfb19 ("ixgbe: Add X550 support function pointers")
+Signed-off-by: Josh Elsasser <jelsasser@appneta.com>
+Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+index ffd2e74e5638..dcd718ce13d5 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+@@ -1429,7 +1429,9 @@ static s32 ixgbe_get_link_capabilities_X550em(struct ixgbe_hw *hw,
+ *autoneg = false;
+
+ if (hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 ||
+- hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1) {
++ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1 ||
++ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core0 ||
++ hw->phy.sfp_type == ixgbe_sfp_type_1g_lx_core1) {
+ *speed = IXGBE_LINK_SPEED_1GB_FULL;
+ return 0;
+ }
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-028-net-hisilicon-remove-unexpected-free_netdev.patch b/patches.kernel.org/4.4.168-028-net-hisilicon-remove-unexpected-free_netdev.patch
new file mode 100644
index 0000000000..ecbaa486eb
--- /dev/null
+++ b/patches.kernel.org/4.4.168-028-net-hisilicon-remove-unexpected-free_netdev.patch
@@ -0,0 +1,40 @@
+From: Pan Bian <bianpan2016@163.com>
+Date: Wed, 28 Nov 2018 15:30:24 +0800
+Subject: [PATCH] net: hisilicon: remove unexpected free_netdev
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: c758940158bf29fe14e9d0f89d5848f227b48134
+
+[ Upstream commit c758940158bf29fe14e9d0f89d5848f227b48134 ]
+
+The net device ndev is freed via free_netdev when failing to register
+the device. The control flow then jumps to the error handling code
+block. ndev is used and freed again. Resulting in a use-after-free bug.
+
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/net/ethernet/hisilicon/hip04_eth.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/hisilicon/hip04_eth.c b/drivers/net/ethernet/hisilicon/hip04_eth.c
+index 253f8ed0537a..60c727b0b7ab 100644
+--- a/drivers/net/ethernet/hisilicon/hip04_eth.c
++++ b/drivers/net/ethernet/hisilicon/hip04_eth.c
+@@ -919,10 +919,8 @@ static int hip04_mac_probe(struct platform_device *pdev)
+ }
+
+ ret = register_netdev(ndev);
+- if (ret) {
+- free_netdev(ndev);
++ if (ret)
+ goto alloc_fail;
+- }
+
+ return 0;
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-029-drm-ast-fixed-reading-monitor-EDID-not-stable.patch b/patches.kernel.org/4.4.168-029-drm-ast-fixed-reading-monitor-EDID-not-stable.patch
new file mode 100644
index 0000000000..10a5c2f6a3
--- /dev/null
+++ b/patches.kernel.org/4.4.168-029-drm-ast-fixed-reading-monitor-EDID-not-stable.patch
@@ -0,0 +1,97 @@
+From: "Y.C. Chen" <yc_chen@aspeedtech.com>
+Date: Thu, 22 Nov 2018 11:56:28 +0800
+Subject: [PATCH] drm/ast: fixed reading monitor EDID not stable issue
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 300625620314194d9e6d4f6dda71f2dc9cf62d9f
+
+[ Upstream commit 300625620314194d9e6d4f6dda71f2dc9cf62d9f ]
+
+v1: over-sample data to increase the stability with some specific monitors
+v2: refine to avoid infinite loop
+v3: remove un-necessary "volatile" declaration
+
+[airlied: fix two checkpatch warnings]
+
+Signed-off-by: Y.C. Chen <yc_chen@aspeedtech.com>
+Signed-off-by: Dave Airlie <airlied@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/1542858988-1127-1-git-send-email-yc_chen@aspeedtech.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/gpu/drm/ast/ast_mode.c | 36 ++++++++++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
+index 21085f669e21..b19ba1792607 100644
+--- a/drivers/gpu/drm/ast/ast_mode.c
++++ b/drivers/gpu/drm/ast/ast_mode.c
+@@ -968,9 +968,21 @@ static int get_clock(void *i2c_priv)
+ {
+ struct ast_i2c_chan *i2c = i2c_priv;
+ struct ast_private *ast = i2c->dev->dev_private;
+- uint32_t val;
++ uint32_t val, val2, count, pass;
++
++ count = 0;
++ pass = 0;
++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
++ do {
++ val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
++ if (val == val2) {
++ pass++;
++ } else {
++ pass = 0;
++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01;
++ }
++ } while ((pass < 5) && (count++ < 0x10000));
+
+- val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4;
+ return val & 1 ? 1 : 0;
+ }
+
+@@ -978,9 +990,21 @@ static int get_data(void *i2c_priv)
+ {
+ struct ast_i2c_chan *i2c = i2c_priv;
+ struct ast_private *ast = i2c->dev->dev_private;
+- uint32_t val;
++ uint32_t val, val2, count, pass;
++
++ count = 0;
++ pass = 0;
++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
++ do {
++ val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
++ if (val == val2) {
++ pass++;
++ } else {
++ pass = 0;
++ val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01;
++ }
++ } while ((pass < 5) && (count++ < 0x10000));
+
+- val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5;
+ return val & 1 ? 1 : 0;
+ }
+
+@@ -993,7 +1017,7 @@ static void set_clock(void *i2c_priv, int clock)
+
+ for (i = 0; i < 0x10000; i++) {
+ ujcrb7 = ((clock & 0x01) ? 0 : 1);
+- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfe, ujcrb7);
++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7);
+ jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01);
+ if (ujcrb7 == jtemp)
+ break;
+@@ -1009,7 +1033,7 @@ static void set_data(void *i2c_priv, int data)
+
+ for (i = 0; i < 0x10000; i++) {
+ ujcrb7 = ((data & 0x01) ? 0 : 1) << 2;
+- ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfb, ujcrb7);
++ ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7);
+ jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04);
+ if (ujcrb7 == jtemp)
+ break;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-030-xen-xlate_mmu-add-missing-header-to-fix-W-1-w.patch b/patches.kernel.org/4.4.168-030-xen-xlate_mmu-add-missing-header-to-fix-W-1-w.patch
new file mode 100644
index 0000000000..003e71a832
--- /dev/null
+++ b/patches.kernel.org/4.4.168-030-xen-xlate_mmu-add-missing-header-to-fix-W-1-w.patch
@@ -0,0 +1,40 @@
+From: Srikanth Boddepalli <boddepalli.srikanth@gmail.com>
+Date: Tue, 27 Nov 2018 19:53:27 +0530
+Subject: [PATCH] xen: xlate_mmu: add missing header to fix 'W=1' warning
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 72791ac854fea36034fa7976b748fde585008e78
+
+[ Upstream commit 72791ac854fea36034fa7976b748fde585008e78 ]
+
+Add a missing header otherwise compiler warns about missed prototype:
+
+drivers/xen/xlate_mmu.c:183:5: warning: no previous prototype for 'xen_xlate_unmap_gfn_range?' [-Wmissing-prototypes]
+ int xen_xlate_unmap_gfn_range(struct vm_area_struct *vma,
+ ^~~~~~~~~~~~~~~~~~~~~~~~~
+
+Signed-off-by: Srikanth Boddepalli <boddepalli.srikanth@gmail.com>
+Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Reviewed-by: Joey Pabalinas <joeypabalinas@gmail.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/xen/xlate_mmu.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c
+index 5063c5e796b7..84a1fab0dd6b 100644
+--- a/drivers/xen/xlate_mmu.c
++++ b/drivers/xen/xlate_mmu.c
+@@ -34,6 +34,7 @@
+ #include <asm/xen/hypervisor.h>
+
+ #include <xen/xen.h>
++#include <xen/xen-ops.h>
+ #include <xen/page.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/memory.h>
+--
+2.20.1
+
diff --git a/patches.fixes/fscache-fix-race-between-enablement-and-dropping-of-.patch b/patches.kernel.org/4.4.168-031-fscache-fix-race-between-enablement-and-dropp.patch
index 9dc8ba9d46..e04d708e74 100644
--- a/patches.fixes/fscache-fix-race-between-enablement-and-dropping-of-.patch
+++ b/patches.kernel.org/4.4.168-031-fscache-fix-race-between-enablement-and-dropp.patch
@@ -1,9 +1,11 @@
From: NeilBrown <neilb@suse.com>
Date: Fri, 26 Oct 2018 17:16:29 +1100
Subject: [PATCH] fscache: fix race between enablement and dropping of object
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1107385
Git-commit: c5a94f434c82529afda290df3235e4d85873c5b4
-Patch-mainline: v4.20
-References: bsc#1107385
+
+[ Upstream commit c5a94f434c82529afda290df3235e4d85873c5b4 ]
It was observed that a process blocked indefintely in
__fscache_read_or_alloc_page(), waiting for FSCACHE_COOKIE_LOOKING_UP
@@ -32,7 +34,7 @@ reproduced with this fix.
The backtrace for the blocked process looked like:
-Pid: 29360 TASK: ffff881ff2ac0f80 CPU: 3 COMMAND: "zsh"
+PID: 29360 TASK: ffff881ff2ac0f80 CPU: 3 COMMAND: "zsh"
#0 [ffff881ff43efbf8] schedule at ffffffff815e56f1
#1 [ffff881ff43efc58] bit_wait at ffffffff815e64ed
#2 [ffff881ff43efc68] __wait_on_bit at ffffffff815e61b8
@@ -50,15 +52,17 @@ Pid: 29360 TASK: ffff881ff2ac0f80 CPU: 3 COMMAND: "zsh"
Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: David Howells <dhowells@redhat.com>
-Acked-by: NeilBrown <neilb@suse.com>
-
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- fs/fscache/object.c | 3 +++
+ fs/fscache/object.c | 3 +++
1 file changed, 3 insertions(+)
+diff --git a/fs/fscache/object.c b/fs/fscache/object.c
+index 7a182c87f378..ab1d7f35f6c2 100644
--- a/fs/fscache/object.c
+++ b/fs/fscache/object.c
-@@ -716,6 +716,9 @@ static const struct fscache_state *fscac
+@@ -715,6 +715,9 @@ static const struct fscache_state *fscache_drop_object(struct fscache_object *ob
if (awaken)
wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
@@ -68,3 +72,6 @@ Acked-by: NeilBrown <neilb@suse.com>
/* Prevent a race with our last child, which has to signal EV_CLEARED
* before dropping our spinlock.
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-032-fscache-cachefiles-remove-redundant-variable-.patch b/patches.kernel.org/4.4.168-032-fscache-cachefiles-remove-redundant-variable-.patch
new file mode 100644
index 0000000000..df0fcaf530
--- /dev/null
+++ b/patches.kernel.org/4.4.168-032-fscache-cachefiles-remove-redundant-variable-.patch
@@ -0,0 +1,42 @@
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 17 Jul 2018 09:53:42 +0100
+Subject: [PATCH] fscache, cachefiles: remove redundant variable 'cache'
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 31ffa563833576bd49a8bf53120568312755e6e2
+
+[ Upstream commit 31ffa563833576bd49a8bf53120568312755e6e2 ]
+
+Variable 'cache' is being assigned but is never used hence it is
+redundant and can be removed.
+
+Cleans up clang warning:
+warning: variable 'cache' set but not used [-Wunused-but-set-variable]
+
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/cachefiles/rdwr.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
+index 5b68cf526887..c05ab2ec0fef 100644
+--- a/fs/cachefiles/rdwr.c
++++ b/fs/cachefiles/rdwr.c
+@@ -963,11 +963,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
+ void cachefiles_uncache_page(struct fscache_object *_object, struct page *page)
+ {
+ struct cachefiles_object *object;
+- struct cachefiles_cache *cache;
+
+ object = container_of(_object, struct cachefiles_object, fscache);
+- cache = container_of(object->fscache.cache,
+- struct cachefiles_cache, cache);
+
+ _enter("%p,{%lu}", object, page->index);
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-033-ocfs2-fix-deadlock-caused-by-ocfs2_defrag_ext.patch b/patches.kernel.org/4.4.168-033-ocfs2-fix-deadlock-caused-by-ocfs2_defrag_ext.patch
new file mode 100644
index 0000000000..c65999597e
--- /dev/null
+++ b/patches.kernel.org/4.4.168-033-ocfs2-fix-deadlock-caused-by-ocfs2_defrag_ext.patch
@@ -0,0 +1,150 @@
+From: Larry Chen <lchen@suse.com>
+Date: Fri, 30 Nov 2018 14:08:56 -0800
+Subject: [PATCH] ocfs2: fix deadlock caused by ocfs2_defrag_extent()
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: e21e57445a64598b29a6f629688f9b9a39e7242a
+
+[ Upstream commit e21e57445a64598b29a6f629688f9b9a39e7242a ]
+
+ocfs2_defrag_extent may fall into deadlock.
+
+ocfs2_ioctl_move_extents
+ ocfs2_ioctl_move_extents
+ ocfs2_move_extents
+ ocfs2_defrag_extent
+ ocfs2_lock_allocators_move_extents
+
+ ocfs2_reserve_clusters
+ inode_lock GLOBAL_BITMAP_SYSTEM_INODE
+
+ __ocfs2_flush_truncate_log
+ inode_lock GLOBAL_BITMAP_SYSTEM_INODE
+
+As backtrace shows above, ocfs2_reserve_clusters() will call inode_lock
+against the global bitmap if local allocator has not sufficient cluters.
+Once global bitmap could meet the demand, ocfs2_reserve_cluster will
+return success with global bitmap locked.
+
+After ocfs2_reserve_cluster(), if truncate log is full,
+__ocfs2_flush_truncate_log() will definitely fall into deadlock because
+it needs to inode_lock global bitmap, which has already been locked.
+
+To fix this bug, we could remove from
+ocfs2_lock_allocators_move_extents() the code which intends to lock
+global allocator, and put the removed code after
+__ocfs2_flush_truncate_log().
+
+ocfs2_lock_allocators_move_extents() is referred by 2 places, one is
+here, the other does not need the data allocator context, which means
+this patch does not affect the caller so far.
+
+Link: http://lkml.kernel.org/r/20181101071422.14470-1-lchen@suse.com
+Signed-off-by: Larry Chen <lchen@suse.com>
+Reviewed-by: Changwei Ge <ge.changwei@h3c.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Joseph Qi <jiangqi903@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/ocfs2/move_extents.c | 47 +++++++++++++++++++++++------------------
+ 1 file changed, 26 insertions(+), 21 deletions(-)
+
+diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c
+index 124471d26a73..c1a83c58456e 100644
+--- a/fs/ocfs2/move_extents.c
++++ b/fs/ocfs2/move_extents.c
+@@ -156,18 +156,14 @@ static int __ocfs2_move_extent(handle_t *handle,
+ }
+
+ /*
+- * lock allocators, and reserving appropriate number of bits for
+- * meta blocks and data clusters.
+- *
+- * in some cases, we don't need to reserve clusters, just let data_ac
+- * be NULL.
++ * lock allocator, and reserve appropriate number of bits for
++ * meta blocks.
+ */
+-static int ocfs2_lock_allocators_move_extents(struct inode *inode,
++static int ocfs2_lock_meta_allocator_move_extents(struct inode *inode,
+ struct ocfs2_extent_tree *et,
+ u32 clusters_to_move,
+ u32 extents_to_split,
+ struct ocfs2_alloc_context **meta_ac,
+- struct ocfs2_alloc_context **data_ac,
+ int extra_blocks,
+ int *credits)
+ {
+@@ -192,13 +188,6 @@ static int ocfs2_lock_allocators_move_extents(struct inode *inode,
+ goto out;
+ }
+
+- if (data_ac) {
+- ret = ocfs2_reserve_clusters(osb, clusters_to_move, data_ac);
+- if (ret) {
+- mlog_errno(ret);
+- goto out;
+- }
+- }
+
+ *credits += ocfs2_calc_extend_credits(osb->sb, et->et_root_el);
+
+@@ -260,10 +249,10 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
+ }
+ }
+
+- ret = ocfs2_lock_allocators_move_extents(inode, &context->et, *len, 1,
+- &context->meta_ac,
+- &context->data_ac,
+- extra_blocks, &credits);
++ ret = ocfs2_lock_meta_allocator_move_extents(inode, &context->et,
++ *len, 1,
++ &context->meta_ac,
++ extra_blocks, &credits);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+@@ -286,6 +275,21 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,
+ }
+ }
+
++ /*
++ * Make sure ocfs2_reserve_cluster is called after
++ * __ocfs2_flush_truncate_log, otherwise, dead lock may happen.
++ *
++ * If ocfs2_reserve_cluster is called
++ * before __ocfs2_flush_truncate_log, dead lock on global bitmap
++ * may happen.
++ *
++ */
++ ret = ocfs2_reserve_clusters(osb, *len, &context->data_ac);
++ if (ret) {
++ mlog_errno(ret);
++ goto out_unlock_mutex;
++ }
++
+ handle = ocfs2_start_trans(osb, credits);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+@@ -606,9 +610,10 @@ static int ocfs2_move_extent(struct ocfs2_move_extents_context *context,
+ }
+ }
+
+- ret = ocfs2_lock_allocators_move_extents(inode, &context->et, len, 1,
+- &context->meta_ac,
+- NULL, extra_blocks, &credits);
++ ret = ocfs2_lock_meta_allocator_move_extents(inode, &context->et,
++ len, 1,
++ &context->meta_ac,
++ extra_blocks, &credits);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-034-hfs-do-not-free-node-before-using.patch b/patches.kernel.org/4.4.168-034-hfs-do-not-free-node-before-using.patch
new file mode 100644
index 0000000000..02d17375c1
--- /dev/null
+++ b/patches.kernel.org/4.4.168-034-hfs-do-not-free-node-before-using.patch
@@ -0,0 +1,52 @@
+From: Pan Bian <bianpan2016@163.com>
+Date: Fri, 30 Nov 2018 14:09:14 -0800
+Subject: [PATCH] hfs: do not free node before using
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: ce96a407adef126870b3f4a1b73529dd8aa80f49
+
+[ Upstream commit ce96a407adef126870b3f4a1b73529dd8aa80f49 ]
+
+hfs_bmap_free() frees the node via hfs_bnode_put(node). However, it
+then reads node->this when dumping error message on an error path, which
+may result in a use-after-free bug. This patch frees the node only when
+it is never again used.
+
+Link: http://lkml.kernel.org/r/1542963889-128825-1-git-send-email-bianpan2016@163.com
+Fixes: a1185ffa2fc ("HFS rewrite")
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: Joe Perches <joe@perches.com>
+Cc: Ernesto A. Fernandez <ernesto.mnd.fernandez@gmail.com>
+Cc: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/hfs/btree.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c
+index 1ab19e660e69..1ff5774a5382 100644
+--- a/fs/hfs/btree.c
++++ b/fs/hfs/btree.c
+@@ -328,13 +328,14 @@ void hfs_bmap_free(struct hfs_bnode *node)
+
+ nidx -= len * 8;
+ i = node->next;
+- hfs_bnode_put(node);
+ if (!i) {
+ /* panic */;
+ pr_crit("unable to free bnode %u. bmap not found!\n",
+ node->this);
++ hfs_bnode_put(node);
+ return;
+ }
++ hfs_bnode_put(node);
+ node = hfs_bnode_find(tree, i);
+ if (IS_ERR(node))
+ return;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-035-hfsplus-do-not-free-node-before-using.patch b/patches.kernel.org/4.4.168-035-hfsplus-do-not-free-node-before-using.patch
new file mode 100644
index 0000000000..ba4abaae6e
--- /dev/null
+++ b/patches.kernel.org/4.4.168-035-hfsplus-do-not-free-node-before-using.patch
@@ -0,0 +1,52 @@
+From: Pan Bian <bianpan2016@163.com>
+Date: Fri, 30 Nov 2018 14:09:18 -0800
+Subject: [PATCH] hfsplus: do not free node before using
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: c7d7d620dcbd2a1c595092280ca943f2fced7bbd
+
+[ Upstream commit c7d7d620dcbd2a1c595092280ca943f2fced7bbd ]
+
+hfs_bmap_free() frees node via hfs_bnode_put(node). However it then
+reads node->this when dumping error message on an error path, which may
+result in a use-after-free bug. This patch frees node only when it is
+never used.
+
+Link: http://lkml.kernel.org/r/1543053441-66942-1-git-send-email-bianpan2016@163.com
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: Ernesto A. Fernandez <ernesto.mnd.fernandez@gmail.com>
+Cc: Joe Perches <joe@perches.com>
+Cc: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/hfsplus/btree.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
+index 3345c7553edc..7adc8a327e03 100644
+--- a/fs/hfsplus/btree.c
++++ b/fs/hfsplus/btree.c
+@@ -453,14 +453,15 @@ void hfs_bmap_free(struct hfs_bnode *node)
+
+ nidx -= len * 8;
+ i = node->next;
+- hfs_bnode_put(node);
+ if (!i) {
+ /* panic */;
+ pr_crit("unable to free bnode %u. "
+ "bmap not found!\n",
+ node->this);
++ hfs_bnode_put(node);
+ return;
+ }
++ hfs_bnode_put(node);
+ node = hfs_bnode_find(tree, i);
+ if (IS_ERR(node))
+ return;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-036-debugobjects-avoid-recursive-calls-with-kmeml.patch b/patches.kernel.org/4.4.168-036-debugobjects-avoid-recursive-calls-with-kmeml.patch
new file mode 100644
index 0000000000..7abd2b0c01
--- /dev/null
+++ b/patches.kernel.org/4.4.168-036-debugobjects-avoid-recursive-calls-with-kmeml.patch
@@ -0,0 +1,61 @@
+From: Qian Cai <cai@gmx.us>
+Date: Fri, 30 Nov 2018 14:09:48 -0800
+Subject: [PATCH] debugobjects: avoid recursive calls with kmemleak
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 8de456cf87ba863e028c4dd01bae44255ce3d835
+
+[ Upstream commit 8de456cf87ba863e028c4dd01bae44255ce3d835 ]
+
+CONFIG_DEBUG_OBJECTS_RCU_HEAD does not play well with kmemleak due to
+recursive calls.
+
+fill_pool
+ kmemleak_ignore
+ make_black_object
+ put_object
+ __call_rcu (kernel/rcu/tree.c)
+ debug_rcu_head_queue
+ debug_object_activate
+ debug_object_init
+ fill_pool
+ kmemleak_ignore
+ make_black_object
+ ...
+
+So add SLAB_NOLEAKTRACE to kmem_cache_create() to not register newly
+allocated debug objects at all.
+
+Link: http://lkml.kernel.org/r/20181126165343.2339-1-cai@gmx.us
+Signed-off-by: Qian Cai <cai@gmx.us>
+Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
+Acked-by: Waiman Long <longman@redhat.com>
+Acked-by: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Yang Shi <yang.shi@linux.alibaba.com>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ lib/debugobjects.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/debugobjects.c b/lib/debugobjects.c
+index a26328ec39f1..bb37541cd441 100644
+--- a/lib/debugobjects.c
++++ b/lib/debugobjects.c
+@@ -1088,7 +1088,8 @@ void __init debug_objects_mem_init(void)
+
+ obj_cache = kmem_cache_create("debug_objects_cache",
+ sizeof (struct debug_obj), 0,
+- SLAB_DEBUG_OBJECTS, NULL);
++ SLAB_DEBUG_OBJECTS | SLAB_NOLEAKTRACE,
++ NULL);
+
+ if (!obj_cache || debug_objects_replace_static_objects()) {
+ debug_objects_enabled = 0;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-037-ocfs2-fix-potential-use-after-free.patch b/patches.kernel.org/4.4.168-037-ocfs2-fix-potential-use-after-free.patch
new file mode 100644
index 0000000000..7cb50bc046
--- /dev/null
+++ b/patches.kernel.org/4.4.168-037-ocfs2-fix-potential-use-after-free.patch
@@ -0,0 +1,50 @@
+From: Pan Bian <bianpan2016@163.com>
+Date: Fri, 30 Nov 2018 14:10:54 -0800
+Subject: [PATCH] ocfs2: fix potential use after free
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 164f7e586739d07eb56af6f6d66acebb11f315c8
+
+[ Upstream commit 164f7e586739d07eb56af6f6d66acebb11f315c8 ]
+
+ocfs2_get_dentry() calls iput(inode) to drop the reference count of
+inode, and if the reference count hits 0, inode is freed. However, in
+this function, it then reads inode->i_generation, which may result in a
+use after free bug. Move the put operation later.
+
+Link: http://lkml.kernel.org/r/1543109237-110227-1-git-send-email-bianpan2016@163.com
+Fixes: 781f200cb7a("ocfs2: Remove masklog ML_EXPORT.")
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Joseph Qi <jiangqi903@gmail.com>
+Cc: Changwei Ge <ge.changwei@h3c.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/ocfs2/export.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
+index 827fc9809bc2..3494e220b510 100644
+--- a/fs/ocfs2/export.c
++++ b/fs/ocfs2/export.c
+@@ -125,10 +125,10 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb,
+
+ check_gen:
+ if (handle->ih_generation != inode->i_generation) {
+- iput(inode);
+ trace_ocfs2_get_dentry_generation((unsigned long long)blkno,
+ handle->ih_generation,
+ inode->i_generation);
++ iput(inode);
+ result = ERR_PTR(-ESTALE);
+ goto bail;
+ }
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-038-pstore-Convert-console-write-to-use-write_buf.patch b/patches.kernel.org/4.4.168-038-pstore-Convert-console-write-to-use-write_buf.patch
new file mode 100644
index 0000000000..ec153a089a
--- /dev/null
+++ b/patches.kernel.org/4.4.168-038-pstore-Convert-console-write-to-use-write_buf.patch
@@ -0,0 +1,45 @@
+From: Namhyung Kim <namhyung@kernel.org>
+Date: Wed, 19 Oct 2016 10:23:41 +0900
+Subject: [PATCH] pstore: Convert console write to use ->write_buf
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 70ad35db3321a6d129245979de4ac9d06eed897c
+
+[ Upstream commit 70ad35db3321a6d129245979de4ac9d06eed897c ]
+
+Maybe I'm missing something, but I don't know why it needs to copy the
+input buffer to psinfo->buf and then write. Instead we can write the
+input buffer directly. The only implementation that supports console
+message (i.e. ramoops) already does it for ftrace messages.
+
+For the upcoming virtio backend driver, it needs to protect psinfo->buf
+overwritten from console messages. If it could use ->write_buf method
+instead of ->write, the problem will be solved easily.
+
+Cc: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/pstore/platform.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
+index 588461bb2dd4..e97e7d74e134 100644
+--- a/fs/pstore/platform.c
++++ b/fs/pstore/platform.c
+@@ -392,8 +392,8 @@ static void pstore_console_write(struct console *con, const char *s, unsigned c)
+ } else {
+ spin_lock_irqsave(&psinfo->buf_lock, flags);
+ }
+- memcpy(psinfo->buf, s, c);
+- psinfo->write(PSTORE_TYPE_CONSOLE, 0, &id, 0, 0, 0, c, psinfo);
++ psinfo->write_buf(PSTORE_TYPE_CONSOLE, 0, &id, 0,
++ s, 0, c, psinfo);
+ spin_unlock_irqrestore(&psinfo->buf_lock, flags);
+ s += c;
+ c = e - s;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-039-ALSA-pcm-remove-SNDRV_PCM_IOCTL1_INFO-interna.patch b/patches.kernel.org/4.4.168-039-ALSA-pcm-remove-SNDRV_PCM_IOCTL1_INFO-interna.patch
new file mode 100644
index 0000000000..a487066507
--- /dev/null
+++ b/patches.kernel.org/4.4.168-039-ALSA-pcm-remove-SNDRV_PCM_IOCTL1_INFO-interna.patch
@@ -0,0 +1,81 @@
+From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Date: Wed, 14 Jun 2017 19:30:03 +0900
+Subject: [PATCH] ALSA: pcm: remove SNDRV_PCM_IOCTL1_INFO internal command
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: e11f0f90a626f93899687b1cc909ee37dd6c5809
+
+commit e11f0f90a626f93899687b1cc909ee37dd6c5809 upstream.
+
+Drivers can implement 'struct snd_pcm_ops.ioctl' to handle some requests
+from ALSA PCM core. These requests are internal purpose in kernel land.
+Usually common set of operations are used for it.
+
+SNDRV_PCM_IOCTL1_INFO is one of the requests. According to code comment,
+it has been obsoleted in the old days.
+
+We can see old releases in ftp.alsa-project.org. The command was firstly
+introduced in v0.5.0 release as SND_PCM_IOCTL1_INFO, to allow drivers to
+fill data of 'struct snd_pcm_channel_info' type. In v0.9.0 release,
+this was obsoleted by the other commands for ioctl(2) such as
+SNDRV_PCM_IOCTL_CHANNEL_INFO.
+
+This commit removes the long-abandoned command, bye.
+
+Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ include/sound/pcm.h | 2 +-
+ sound/core/pcm_lib.c | 2 --
+ sound/core/pcm_native.c | 6 +-----
+ 3 files changed, 2 insertions(+), 8 deletions(-)
+
+diff --git a/include/sound/pcm.h b/include/sound/pcm.h
+index b0be09279943..ffc161906d36 100644
+--- a/include/sound/pcm.h
++++ b/include/sound/pcm.h
+@@ -100,7 +100,7 @@ struct snd_pcm_ops {
+ #endif
+
+ #define SNDRV_PCM_IOCTL1_RESET 0
+-#define SNDRV_PCM_IOCTL1_INFO 1
++/* 1 is absent slot. */
+ #define SNDRV_PCM_IOCTL1_CHANNEL_INFO 2
+ #define SNDRV_PCM_IOCTL1_GSTATE 3
+ #define SNDRV_PCM_IOCTL1_FIFO_SIZE 4
+diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
+index 5bc7ddf8fc70..3ce2b8771762 100644
+--- a/sound/core/pcm_lib.c
++++ b/sound/core/pcm_lib.c
+@@ -1849,8 +1849,6 @@ int snd_pcm_lib_ioctl(struct snd_pcm_substream *substream,
+ unsigned int cmd, void *arg)
+ {
+ switch (cmd) {
+- case SNDRV_PCM_IOCTL1_INFO:
+- return 0;
+ case SNDRV_PCM_IOCTL1_RESET:
+ return snd_pcm_lib_ioctl_reset(substream, arg);
+ case SNDRV_PCM_IOCTL1_CHANNEL_INFO:
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index 0ad194002c0c..9b6dcdea4431 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -214,11 +214,7 @@ int snd_pcm_info(struct snd_pcm_substream *substream, struct snd_pcm_info *info)
+ info->subdevices_avail = pstr->substream_count - pstr->substream_opened;
+ strlcpy(info->subname, substream->name, sizeof(info->subname));
+ runtime = substream->runtime;
+- /* AB: FIXME!!! This is definitely nonsense */
+- if (runtime) {
+- info->sync = runtime->sync;
+- substream->ops->ioctl(substream, SNDRV_PCM_IOCTL1_INFO, info);
+- }
++
+ return 0;
+ }
+
+--
+2.20.1
+
diff --git a/patches.fixes/kvm-nvmx-fix-msr-bitmaps-to-prevent-l2-from-accessing-l0-x2apic b/patches.kernel.org/4.4.168-040-KVM-nVMX-fix-msr-bitmaps-to-prevent-L2-from-a.patch
index 61cad64102..bfb56a007c 100644
--- a/patches.fixes/kvm-nvmx-fix-msr-bitmaps-to-prevent-l2-from-accessing-l0-x2apic
+++ b/patches.kernel.org/4.4.168-040-KVM-nVMX-fix-msr-bitmaps-to-prevent-L2-from-a.patch
@@ -1,12 +1,15 @@
From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com>
Date: Mon, 8 Aug 2016 20:16:22 +0200
-Subject: KVM: nVMX: fix msr bitmaps to prevent L2 from accessing L0 x2APIC
+Subject: [PATCH] KVM: nVMX: fix msr bitmaps to prevent L2 from accessing L0
+ x2APIC
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1051478
Git-commit: d048c098218e91ed0e10dfa1f0f80e2567fe4ef7
-Patch-mainline: v4.8-rc4
-References: bsc#1051478
+
+commit d048c098218e91ed0e10dfa1f0f80e2567fe4ef7 upstream.
msr bitmap can be used to avoid a VM exit (interception) on guest MSR
accesses. In some configurations of VMX controls, the guest can even
@@ -34,23 +37,30 @@ Reported-by: Jim Mattson <jmattson@google.com>
Suggested-by: Wincy Van <fanwenyi0529@gmail.com>
Reviewed-by: Wanpeng Li <wanpeng.li@hotmail.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
-Acked-by: Joerg Roedel <jroedel@suse.de>
+[bwh: Backported to 4.4:
+ - handle_vmon() doesn't allocate a cached vmcs12
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- arch/x86/kvm/vmx.c | 96 ++++++++++++++++++++---------------------------------
+ arch/x86/kvm/vmx.c | 96 ++++++++++++++++++----------------------------
1 file changed, 38 insertions(+), 58 deletions(-)
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index c5a4b1978cbf..3df636400ec8 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -431,6 +431,8 @@ struct nested_vmx {
- bool pi_pending;
u16 posted_intr_nv;
+ u64 msr_ia32_feature_control;
+ unsigned long *msr_bitmap;
+
struct hrtimer preemption_timer;
bool preemption_timer_expired;
-@@ -922,7 +924,6 @@ static unsigned long *vmx_msr_bitmap_leg
+@@ -912,7 +914,6 @@ static unsigned long *vmx_msr_bitmap_legacy;
static unsigned long *vmx_msr_bitmap_longmode;
static unsigned long *vmx_msr_bitmap_legacy_x2apic;
static unsigned long *vmx_msr_bitmap_longmode_x2apic;
@@ -58,7 +68,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
static unsigned long *vmx_vmread_bitmap;
static unsigned long *vmx_vmwrite_bitmap;
-@@ -2368,7 +2369,7 @@ static void vmx_set_msr_bitmap(struct kv
+@@ -2358,7 +2359,7 @@ static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu)
unsigned long *msr_bitmap;
if (is_guest_mode(vcpu))
@@ -67,7 +77,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
else if (vcpu->arch.apic_base & X2APIC_ENABLE) {
if (is_long_mode(vcpu))
msr_bitmap = vmx_msr_bitmap_longmode_x2apic;
-@@ -6223,13 +6224,6 @@ static __init int hardware_setup(void)
+@@ -6192,13 +6193,6 @@ static __init int hardware_setup(void)
if (!vmx_msr_bitmap_longmode_x2apic)
goto out4;
@@ -81,7 +91,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
if (!vmx_vmread_bitmap)
goto out6;
-@@ -6247,8 +6241,6 @@ static __init int hardware_setup(void)
+@@ -6216,8 +6210,6 @@ static __init int hardware_setup(void)
memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
@@ -90,7 +100,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (setup_vmcs_config(&vmcs_config) < 0) {
r = -EIO;
-@@ -6378,9 +6370,6 @@ out8:
+@@ -6354,9 +6346,6 @@ static __init int hardware_setup(void)
out7:
free_page((unsigned long)vmx_vmread_bitmap);
out6:
@@ -100,7 +110,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
out4:
free_page((unsigned long)vmx_msr_bitmap_longmode);
-@@ -6406,8 +6395,6 @@ static __exit void hardware_unsetup(void
+@@ -6382,8 +6371,6 @@ static __exit void hardware_unsetup(void)
free_page((unsigned long)vmx_io_bitmap_a);
free_page((unsigned long)vmx_vmwrite_bitmap);
free_page((unsigned long)vmx_vmread_bitmap);
@@ -109,7 +119,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
free_kvm_area();
}
-@@ -6850,10 +6837,17 @@ static int handle_vmon(struct kvm_vcpu *
+@@ -6825,10 +6812,17 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
return 1;
}
@@ -124,16 +134,16 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
shadow_vmcs = alloc_vmcs();
if (!shadow_vmcs)
- return -ENOMEM;
-+ goto out_cached_vmcs12;
++ goto out_shadow_vmcs;
/* mark vmcs as shadow */
shadow_vmcs->revision_id |= (1u << 31);
/* init shadow vmcs */
-@@ -6873,6 +6867,12 @@ static int handle_vmon(struct kvm_vcpu *
+@@ -6850,6 +6844,12 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
skip_emulated_instruction(vcpu);
nested_vmx_succeed(vcpu);
return 1;
+
-+out_cached_vmcs12:
++out_shadow_vmcs:
+ free_page((unsigned long)vmx->nested.msr_bitmap);
+
+out_msr_bitmap:
@@ -141,7 +151,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
/*
-@@ -6942,6 +6942,10 @@ static void free_nested(struct vcpu_vmx
+@@ -6919,6 +6919,10 @@ static void free_nested(struct vcpu_vmx *vmx)
vmx->nested.vmxon = false;
free_vpid(vmx->nested.vpid02);
nested_release_vmcs12(vmx);
@@ -152,7 +162,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (enable_shadow_vmcs)
free_vmcs(vmx->nested.current_shadow_vmcs);
/* Unpin physical memory we referred to in current vmcs02 */
-@@ -9299,8 +9303,10 @@ static inline bool nested_vmx_merge_msr_
+@@ -9248,8 +9252,10 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
{
int msr;
struct page *page;
@@ -164,7 +174,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (!nested_cpu_has_virt_x2apic_mode(vmcs12))
return false;
-@@ -9309,58 +9315,32 @@ static inline bool nested_vmx_merge_msr_
+@@ -9258,58 +9264,32 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
WARN_ON(1);
return false;
}
@@ -233,7 +243,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
}
kunmap(page);
nested_release_page_clean(page);
-@@ -9780,10 +9760,10 @@ static void prepare_vmcs02(struct kvm_vc
+@@ -9729,10 +9709,10 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
}
if (cpu_has_vmx_msr_bitmap() &&
@@ -248,3 +258,6 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
exec_control &= ~CPU_BASED_USE_MSR_BITMAPS;
/*
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-041-KVM-nVMX-mark-vmcs12-pages-dirty-on-L2-exit.patch b/patches.kernel.org/4.4.168-041-KVM-nVMX-mark-vmcs12-pages-dirty-on-L2-exit.patch
new file mode 100644
index 0000000000..9aa76a3629
--- /dev/null
+++ b/patches.kernel.org/4.4.168-041-KVM-nVMX-mark-vmcs12-pages-dirty-on-L2-exit.patch
@@ -0,0 +1,122 @@
+From: David Matlack <dmatlack@google.com>
+Date: Tue, 1 Aug 2017 14:00:40 -0700
+Subject: [PATCH] KVM: nVMX: mark vmcs12 pages dirty on L2 exit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: c9f04407f2e0b3fc9ff7913c65fcfcb0a4b61570
+
+commit c9f04407f2e0b3fc9ff7913c65fcfcb0a4b61570 upstream.
+
+The host physical addresses of L1's Virtual APIC Page and Posted
+Interrupt descriptor are loaded into the VMCS02. The CPU may write
+to these pages via their host physical address while L2 is running,
+bypassing address-translation-based dirty tracking (e.g. EPT write
+protection). Mark them dirty on every exit from L2 to prevent them
+from getting out of sync with dirty tracking.
+
+Also mark the virtual APIC page and the posted interrupt descriptor
+dirty when KVM is virtualizing posted interrupt processing.
+
+Signed-off-by: David Matlack <dmatlack@google.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/vmx.c | 53 +++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 43 insertions(+), 10 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 3df636400ec8..b886a7c9ed4b 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -4527,6 +4527,28 @@ static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu)
+ return enable_apicv && lapic_in_kernel(vcpu);
+ }
+
++static void nested_mark_vmcs12_pages_dirty(struct kvm_vcpu *vcpu)
++{
++ struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
++ gfn_t gfn;
++
++ /*
++ * Don't need to mark the APIC access page dirty; it is never
++ * written to by the CPU during APIC virtualization.
++ */
++
++ if (nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW)) {
++ gfn = vmcs12->virtual_apic_page_addr >> PAGE_SHIFT;
++ kvm_vcpu_mark_page_dirty(vcpu, gfn);
++ }
++
++ if (nested_cpu_has_posted_intr(vmcs12)) {
++ gfn = vmcs12->posted_intr_desc_addr >> PAGE_SHIFT;
++ kvm_vcpu_mark_page_dirty(vcpu, gfn);
++ }
++}
++
++
+ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
+ {
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+@@ -4534,18 +4556,15 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
+ void *vapic_page;
+ u16 status;
+
+- if (vmx->nested.pi_desc &&
+- vmx->nested.pi_pending) {
+- vmx->nested.pi_pending = false;
+- if (!pi_test_and_clear_on(vmx->nested.pi_desc))
+- return;
+-
+- max_irr = find_last_bit(
+- (unsigned long *)vmx->nested.pi_desc->pir, 256);
++ if (!vmx->nested.pi_desc || !vmx->nested.pi_pending)
++ return;
+
+- if (max_irr == 256)
+- return;
++ vmx->nested.pi_pending = false;
++ if (!pi_test_and_clear_on(vmx->nested.pi_desc))
++ return;
+
++ max_irr = find_last_bit((unsigned long *)vmx->nested.pi_desc->pir, 256);
++ if (max_irr != 256) {
+ vapic_page = kmap(vmx->nested.virtual_apic_page);
+ __kvm_apic_update_irr(vmx->nested.pi_desc->pir, vapic_page);
+ kunmap(vmx->nested.virtual_apic_page);
+@@ -4557,6 +4576,8 @@ static void vmx_complete_nested_posted_interrupt(struct kvm_vcpu *vcpu)
+ vmcs_write16(GUEST_INTR_STATUS, status);
+ }
+ }
++
++ nested_mark_vmcs12_pages_dirty(vcpu);
+ }
+
+ static inline bool kvm_vcpu_trigger_posted_interrupt(struct kvm_vcpu *vcpu)
+@@ -7761,6 +7782,18 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
+ vmcs_read32(VM_EXIT_INTR_ERROR_CODE),
+ KVM_ISA_VMX);
+
++ /*
++ * The host physical addresses of some pages of guest memory
++ * are loaded into VMCS02 (e.g. L1's Virtual APIC Page). The CPU
++ * may write to these pages via their host physical address while
++ * L2 is running, bypassing any address-translation-based dirty
++ * tracking (e.g. EPT write protection).
++ *
++ * Mark them dirty on every exit from L2 to prevent them from
++ * getting out of sync with dirty tracking.
++ */
++ nested_mark_vmcs12_pages_dirty(vcpu);
++
+ if (vmx->nested.nested_run_pending)
+ return false;
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-042-KVM-nVMX-Eliminate-vmcs02-pool.patch b/patches.kernel.org/4.4.168-042-KVM-nVMX-Eliminate-vmcs02-pool.patch
new file mode 100644
index 0000000000..7a9293d147
--- /dev/null
+++ b/patches.kernel.org/4.4.168-042-KVM-nVMX-Eliminate-vmcs02-pool.patch
@@ -0,0 +1,302 @@
+From: Jim Mattson <jmattson@google.com>
+Date: Mon, 27 Nov 2017 17:22:25 -0600
+Subject: [PATCH] KVM: nVMX: Eliminate vmcs02 pool
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: de3a0021a60635de96aa92713c1a31a96747d72c
+
+commit de3a0021a60635de96aa92713c1a31a96747d72c upstream.
+
+The potential performance advantages of a vmcs02 pool have never been
+realized. To simplify the code, eliminate the pool. Instead, a single
+vmcs02 is allocated per VCPU when the VCPU enters VMX operation.
+
+Signed-off-by: Jim Mattson <jmattson@google.com>
+Signed-off-by: Mark Kanda <mark.kanda@oracle.com>
+Reviewed-by: Ameya More <ameya.more@oracle.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4:
+ - No loaded_vmcs::shadow_vmcs field to initialise
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/vmx.c | 144 +++++++--------------------------------------
+ 1 file changed, 22 insertions(+), 122 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index b886a7c9ed4b..cf131f41d4b9 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -172,7 +172,6 @@ module_param(ple_window_max, int, S_IRUGO);
+ extern const ulong vmx_return;
+
+ #define NR_AUTOLOAD_MSRS 8
+-#define VMCS02_POOL_SIZE 1
+
+ struct vmcs {
+ u32 revision_id;
+@@ -205,7 +204,7 @@ struct shared_msr_entry {
+ * stored in guest memory specified by VMPTRLD, but is opaque to the guest,
+ * which must access it using VMREAD/VMWRITE/VMCLEAR instructions.
+ * More than one of these structures may exist, if L1 runs multiple L2 guests.
+- * nested_vmx_run() will use the data here to build a vmcs02: a VMCS for the
++ * nested_vmx_run() will use the data here to build the vmcs02: a VMCS for the
+ * underlying hardware which will be used to run L2.
+ * This structure is packed to ensure that its layout is identical across
+ * machines (necessary for live migration).
+@@ -384,13 +383,6 @@ struct __packed vmcs12 {
+ */
+ #define VMCS12_SIZE 0x1000
+
+-/* Used to remember the last vmcs02 used for some recently used vmcs12s */
+-struct vmcs02_list {
+- struct list_head list;
+- gpa_t vmptr;
+- struct loaded_vmcs vmcs02;
+-};
+-
+ /*
+ * The nested_vmx structure is part of vcpu_vmx, and holds information we need
+ * for correct emulation of VMX (i.e., nested VMX) on this vcpu.
+@@ -412,16 +404,16 @@ struct nested_vmx {
+ */
+ bool sync_shadow_vmcs;
+
+- /* vmcs02_list cache of VMCSs recently used to run L2 guests */
+- struct list_head vmcs02_pool;
+- int vmcs02_num;
+ u64 vmcs01_tsc_offset;
+ bool change_vmcs01_virtual_x2apic_mode;
+ /* L2 must run next, and mustn't decide to exit to L1. */
+ bool nested_run_pending;
++
++ struct loaded_vmcs vmcs02;
++
+ /*
+- * Guest pages referred to in vmcs02 with host-physical pointers, so
+- * we must keep them pinned while L2 runs.
++ * Guest pages referred to in the vmcs02 with host-physical
++ * pointers, so we must keep them pinned while L2 runs.
+ */
+ struct page *apic_access_page;
+ struct page *virtual_apic_page;
+@@ -6434,93 +6426,6 @@ static int handle_monitor(struct kvm_vcpu *vcpu)
+ return handle_nop(vcpu);
+ }
+
+-/*
+- * To run an L2 guest, we need a vmcs02 based on the L1-specified vmcs12.
+- * We could reuse a single VMCS for all the L2 guests, but we also want the
+- * option to allocate a separate vmcs02 for each separate loaded vmcs12 - this
+- * allows keeping them loaded on the processor, and in the future will allow
+- * optimizations where prepare_vmcs02 doesn't need to set all the fields on
+- * every entry if they never change.
+- * So we keep, in vmx->nested.vmcs02_pool, a cache of size VMCS02_POOL_SIZE
+- * (>=0) with a vmcs02 for each recently loaded vmcs12s, most recent first.
+- *
+- * The following functions allocate and free a vmcs02 in this pool.
+- */
+-
+-/* Get a VMCS from the pool to use as vmcs02 for the current vmcs12. */
+-static struct loaded_vmcs *nested_get_current_vmcs02(struct vcpu_vmx *vmx)
+-{
+- struct vmcs02_list *item;
+- list_for_each_entry(item, &vmx->nested.vmcs02_pool, list)
+- if (item->vmptr == vmx->nested.current_vmptr) {
+- list_move(&item->list, &vmx->nested.vmcs02_pool);
+- return &item->vmcs02;
+- }
+-
+- if (vmx->nested.vmcs02_num >= max(VMCS02_POOL_SIZE, 1)) {
+- /* Recycle the least recently used VMCS. */
+- item = list_entry(vmx->nested.vmcs02_pool.prev,
+- struct vmcs02_list, list);
+- item->vmptr = vmx->nested.current_vmptr;
+- list_move(&item->list, &vmx->nested.vmcs02_pool);
+- return &item->vmcs02;
+- }
+-
+- /* Create a new VMCS */
+- item = kmalloc(sizeof(struct vmcs02_list), GFP_KERNEL);
+- if (!item)
+- return NULL;
+- item->vmcs02.vmcs = alloc_vmcs();
+- if (!item->vmcs02.vmcs) {
+- kfree(item);
+- return NULL;
+- }
+- loaded_vmcs_init(&item->vmcs02);
+- item->vmptr = vmx->nested.current_vmptr;
+- list_add(&(item->list), &(vmx->nested.vmcs02_pool));
+- vmx->nested.vmcs02_num++;
+- return &item->vmcs02;
+-}
+-
+-/* Free and remove from pool a vmcs02 saved for a vmcs12 (if there is one) */
+-static void nested_free_vmcs02(struct vcpu_vmx *vmx, gpa_t vmptr)
+-{
+- struct vmcs02_list *item;
+- list_for_each_entry(item, &vmx->nested.vmcs02_pool, list)
+- if (item->vmptr == vmptr) {
+- free_loaded_vmcs(&item->vmcs02);
+- list_del(&item->list);
+- kfree(item);
+- vmx->nested.vmcs02_num--;
+- return;
+- }
+-}
+-
+-/*
+- * Free all VMCSs saved for this vcpu, except the one pointed by
+- * vmx->loaded_vmcs. We must be running L1, so vmx->loaded_vmcs
+- * must be &vmx->vmcs01.
+- */
+-static void nested_free_all_saved_vmcss(struct vcpu_vmx *vmx)
+-{
+- struct vmcs02_list *item, *n;
+-
+- WARN_ON(vmx->loaded_vmcs != &vmx->vmcs01);
+- list_for_each_entry_safe(item, n, &vmx->nested.vmcs02_pool, list) {
+- /*
+- * Something will leak if the above WARN triggers. Better than
+- * a use-after-free.
+- */
+- if (vmx->loaded_vmcs == &item->vmcs02)
+- continue;
+-
+- free_loaded_vmcs(&item->vmcs02);
+- list_del(&item->list);
+- kfree(item);
+- vmx->nested.vmcs02_num--;
+- }
+-}
+-
+ /*
+ * The following 3 functions, nested_vmx_succeed()/failValid()/failInvalid(),
+ * set the success or error code of an emulated VMX instruction, as specified
+@@ -6833,6 +6738,11 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ return 1;
+ }
+
++ vmx->nested.vmcs02.vmcs = alloc_vmcs();
++ if (!vmx->nested.vmcs02.vmcs)
++ goto out_vmcs02;
++ loaded_vmcs_init(&vmx->nested.vmcs02);
++
+ if (cpu_has_vmx_msr_bitmap()) {
+ vmx->nested.msr_bitmap =
+ (unsigned long *)__get_free_page(GFP_KERNEL);
+@@ -6851,9 +6761,6 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ vmx->nested.current_shadow_vmcs = shadow_vmcs;
+ }
+
+- INIT_LIST_HEAD(&(vmx->nested.vmcs02_pool));
+- vmx->nested.vmcs02_num = 0;
+-
+ hrtimer_init(&vmx->nested.preemption_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ vmx->nested.preemption_timer.function = vmx_preemption_timer_fn;
+@@ -6870,6 +6777,9 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ free_page((unsigned long)vmx->nested.msr_bitmap);
+
+ out_msr_bitmap:
++ free_loaded_vmcs(&vmx->nested.vmcs02);
++
++out_vmcs02:
+ return -ENOMEM;
+ }
+
+@@ -6946,7 +6856,7 @@ static void free_nested(struct vcpu_vmx *vmx)
+ }
+ if (enable_shadow_vmcs)
+ free_vmcs(vmx->nested.current_shadow_vmcs);
+- /* Unpin physical memory we referred to in current vmcs02 */
++ /* Unpin physical memory we referred to in the vmcs02 */
+ if (vmx->nested.apic_access_page) {
+ nested_release_page(vmx->nested.apic_access_page);
+ vmx->nested.apic_access_page = NULL;
+@@ -6962,7 +6872,7 @@ static void free_nested(struct vcpu_vmx *vmx)
+ vmx->nested.pi_desc = NULL;
+ }
+
+- nested_free_all_saved_vmcss(vmx);
++ free_loaded_vmcs(&vmx->nested.vmcs02);
+ }
+
+ /* Emulate the VMXOFF instruction */
+@@ -6996,8 +6906,6 @@ static int handle_vmclear(struct kvm_vcpu *vcpu)
+ vmptr + offsetof(struct vmcs12, launch_state),
+ &zero, sizeof(zero));
+
+- nested_free_vmcs02(vmx, vmptr);
+-
+ skip_emulated_instruction(vcpu);
+ nested_vmx_succeed(vcpu);
+ return 1;
+@@ -7784,10 +7692,11 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
+
+ /*
+ * The host physical addresses of some pages of guest memory
+- * are loaded into VMCS02 (e.g. L1's Virtual APIC Page). The CPU
+- * may write to these pages via their host physical address while
+- * L2 is running, bypassing any address-translation-based dirty
+- * tracking (e.g. EPT write protection).
++ * are loaded into the vmcs02 (e.g. vmcs12's Virtual APIC
++ * Page). The CPU may write to these pages via their host
++ * physical address while L2 is running, bypassing any
++ * address-translation-based dirty tracking (e.g. EPT write
++ * protection).
+ *
+ * Mark them dirty on every exit from L2 to prevent them from
+ * getting out of sync with dirty tracking.
+@@ -9889,7 +9798,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
+ struct vmcs12 *vmcs12;
+ struct vcpu_vmx *vmx = to_vmx(vcpu);
+ int cpu;
+- struct loaded_vmcs *vmcs02;
+ bool ia32e;
+ u32 msr_entry_idx;
+
+@@ -10029,10 +9937,6 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
+ * the nested entry.
+ */
+
+- vmcs02 = nested_get_current_vmcs02(vmx);
+- if (!vmcs02)
+- return -ENOMEM;
+-
+ enter_guest_mode(vcpu);
+
+ vmx->nested.vmcs01_tsc_offset = vmcs_read64(TSC_OFFSET);
+@@ -10041,7 +9945,7 @@ static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch)
+ vmx->nested.vmcs01_debugctl = vmcs_read64(GUEST_IA32_DEBUGCTL);
+
+ cpu = get_cpu();
+- vmx->loaded_vmcs = vmcs02;
++ vmx->loaded_vmcs = &vmx->nested.vmcs02;
+ vmx_vcpu_put(vcpu);
+ vmx_vcpu_load(vcpu, cpu);
+ vcpu->cpu = cpu;
+@@ -10553,10 +10457,6 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
+ vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS));
+ vmx_segment_cache_clear(vmx);
+
+- /* if no vmcs02 cache requested, remove the one we used */
+- if (VMCS02_POOL_SIZE == 0)
+- nested_free_vmcs02(vmx, vmx->nested.current_vmptr);
+-
+ load_vmcs12_host_state(vcpu, vmcs12);
+
+ /* Update TSC_OFFSET if TSC was changed while L2 ran */
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-043-KVM-VMX-introduce-alloc_loaded_vmcs.patch b/patches.kernel.org/4.4.168-043-KVM-VMX-introduce-alloc_loaded_vmcs.patch
new file mode 100644
index 0000000000..37541f37a7
--- /dev/null
+++ b/patches.kernel.org/4.4.168-043-KVM-VMX-introduce-alloc_loaded_vmcs.patch
@@ -0,0 +1,108 @@
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 11 Jan 2018 12:16:15 +0100
+Subject: [PATCH] KVM: VMX: introduce alloc_loaded_vmcs
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: f21f165ef922c2146cc5bdc620f542953c41714b
+
+commit f21f165ef922c2146cc5bdc620f542953c41714b upstream.
+
+Group together the calls to alloc_vmcs and loaded_vmcs_init. Soon we'll also
+allocate an MSR bitmap there.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4:
+ - No loaded_vmcs::shadow_vmcs field to initialise
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/vmx.c | 35 ++++++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 13 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index cf131f41d4b9..5ffc2731e14d 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -3345,11 +3345,6 @@ static struct vmcs *alloc_vmcs_cpu(int cpu)
+ return vmcs;
+ }
+
+-static struct vmcs *alloc_vmcs(void)
+-{
+- return alloc_vmcs_cpu(raw_smp_processor_id());
+-}
+-
+ static void free_vmcs(struct vmcs *vmcs)
+ {
+ free_pages((unsigned long)vmcs, vmcs_config.order);
+@@ -3367,6 +3362,21 @@ static void free_loaded_vmcs(struct loaded_vmcs *loaded_vmcs)
+ loaded_vmcs->vmcs = NULL;
+ }
+
++static struct vmcs *alloc_vmcs(void)
++{
++ return alloc_vmcs_cpu(raw_smp_processor_id());
++}
++
++static int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs)
++{
++ loaded_vmcs->vmcs = alloc_vmcs();
++ if (!loaded_vmcs->vmcs)
++ return -ENOMEM;
++
++ loaded_vmcs_init(loaded_vmcs);
++ return 0;
++}
++
+ static void free_kvm_area(void)
+ {
+ int cpu;
+@@ -6699,6 +6709,7 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ struct vmcs *shadow_vmcs;
+ const u64 VMXON_NEEDED_FEATURES = FEATURE_CONTROL_LOCKED
+ | FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
++ int r;
+
+ /* The Intel VMX Instruction Reference lists a bunch of bits that
+ * are prerequisite to running VMXON, most notably cr4.VMXE must be
+@@ -6738,10 +6749,9 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ return 1;
+ }
+
+- vmx->nested.vmcs02.vmcs = alloc_vmcs();
+- if (!vmx->nested.vmcs02.vmcs)
++ r = alloc_loaded_vmcs(&vmx->nested.vmcs02);
++ if (r < 0)
+ goto out_vmcs02;
+- loaded_vmcs_init(&vmx->nested.vmcs02);
+
+ if (cpu_has_vmx_msr_bitmap()) {
+ vmx->nested.msr_bitmap =
+@@ -8802,16 +8812,15 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
+ if (!vmx->guest_msrs)
+ goto free_pml;
+
+- vmx->loaded_vmcs = &vmx->vmcs01;
+- vmx->loaded_vmcs->vmcs = alloc_vmcs();
+- if (!vmx->loaded_vmcs->vmcs)
+- goto free_msrs;
+ if (!vmm_exclusive)
+ kvm_cpu_vmxon(__pa(per_cpu(vmxarea, raw_smp_processor_id())));
+- loaded_vmcs_init(vmx->loaded_vmcs);
++ err = alloc_loaded_vmcs(&vmx->vmcs01);
+ if (!vmm_exclusive)
+ kvm_cpu_vmxoff();
++ if (err < 0)
++ goto free_msrs;
+
++ vmx->loaded_vmcs = &vmx->vmcs01;
+ cpu = get_cpu();
+ vmx_vcpu_load(&vmx->vcpu, cpu);
+ vmx->vcpu.cpu = cpu;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-044-KVM-VMX-make-MSR-bitmaps-per-VCPU.patch b/patches.kernel.org/4.4.168-044-KVM-VMX-make-MSR-bitmaps-per-VCPU.patch
new file mode 100644
index 0000000000..4e36c6109c
--- /dev/null
+++ b/patches.kernel.org/4.4.168-044-KVM-VMX-make-MSR-bitmaps-per-VCPU.patch
@@ -0,0 +1,518 @@
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 16 Jan 2018 16:51:18 +0100
+Subject: [PATCH] KVM: VMX: make MSR bitmaps per-VCPU
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 904e14fb7cb96401a7dc803ca2863fd5ba32ffe6
+
+commit 904e14fb7cb96401a7dc803ca2863fd5ba32ffe6 upstream.
+
+Place the MSR bitmap in struct loaded_vmcs, and update it in place
+every time the x2apic or APICv state can change. This is rare and
+the loop can handle 64 MSRs per iteration, in a similar fashion as
+nested_vmx_prepare_msr_bitmap.
+
+This prepares for choosing, on a per-VM basis, whether to intercept
+the SPEC_CTRL and PRED_CMD MSRs.
+
+Suggested-by: Jim Mattson <jmattson@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4:
+ - APICv support looked different
+ - We still need to intercept the APIC_ID MSR
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/vmx.c | 254 ++++++++++++++++++++-------------------------
+ 1 file changed, 112 insertions(+), 142 deletions(-)
+
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 5ffc2731e14d..e0064855fbdb 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -109,6 +109,14 @@ static u64 __read_mostly host_xss;
+ static bool __read_mostly enable_pml = 1;
+ module_param_named(pml, enable_pml, bool, S_IRUGO);
+
++#define MSR_TYPE_R 1
++#define MSR_TYPE_W 2
++#define MSR_TYPE_RW 3
++
++#define MSR_BITMAP_MODE_X2APIC 1
++#define MSR_BITMAP_MODE_X2APIC_APICV 2
++#define MSR_BITMAP_MODE_LM 4
++
+ #define KVM_VMX_TSC_MULTIPLIER_MAX 0xffffffffffffffffULL
+
+ #define KVM_GUEST_CR0_MASK (X86_CR0_NW | X86_CR0_CD)
+@@ -188,6 +196,7 @@ struct loaded_vmcs {
+ struct vmcs *vmcs;
+ int cpu;
+ int launched;
++ unsigned long *msr_bitmap;
+ struct list_head loaded_vmcss_on_cpu_link;
+ };
+
+@@ -423,8 +432,6 @@ struct nested_vmx {
+ u16 posted_intr_nv;
+ u64 msr_ia32_feature_control;
+
+- unsigned long *msr_bitmap;
+-
+ struct hrtimer preemption_timer;
+ bool preemption_timer_expired;
+
+@@ -525,6 +532,7 @@ struct vcpu_vmx {
+ unsigned long host_rsp;
+ u8 fail;
+ bool nmi_known_unmasked;
++ u8 msr_bitmap_mode;
+ u32 exit_intr_info;
+ u32 idt_vectoring_info;
+ ulong rflags;
+@@ -883,6 +891,7 @@ static void vmx_sync_pir_to_irr_dummy(struct kvm_vcpu *vcpu);
+ static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
+ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
+ static int alloc_identity_pagetable(struct kvm *kvm);
++static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
+
+ static DEFINE_PER_CPU(struct vmcs *, vmxarea);
+ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
+@@ -902,10 +911,6 @@ static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock);
+
+ static unsigned long *vmx_io_bitmap_a;
+ static unsigned long *vmx_io_bitmap_b;
+-static unsigned long *vmx_msr_bitmap_legacy;
+-static unsigned long *vmx_msr_bitmap_longmode;
+-static unsigned long *vmx_msr_bitmap_legacy_x2apic;
+-static unsigned long *vmx_msr_bitmap_longmode_x2apic;
+ static unsigned long *vmx_vmread_bitmap;
+ static unsigned long *vmx_vmwrite_bitmap;
+
+@@ -2346,27 +2351,6 @@ static void move_msr_up(struct vcpu_vmx *vmx, int from, int to)
+ vmx->guest_msrs[from] = tmp;
+ }
+
+-static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu)
+-{
+- unsigned long *msr_bitmap;
+-
+- if (is_guest_mode(vcpu))
+- msr_bitmap = to_vmx(vcpu)->nested.msr_bitmap;
+- else if (vcpu->arch.apic_base & X2APIC_ENABLE) {
+- if (is_long_mode(vcpu))
+- msr_bitmap = vmx_msr_bitmap_longmode_x2apic;
+- else
+- msr_bitmap = vmx_msr_bitmap_legacy_x2apic;
+- } else {
+- if (is_long_mode(vcpu))
+- msr_bitmap = vmx_msr_bitmap_longmode;
+- else
+- msr_bitmap = vmx_msr_bitmap_legacy;
+- }
+-
+- vmcs_write64(MSR_BITMAP, __pa(msr_bitmap));
+-}
+-
+ /*
+ * Set up the vmcs to automatically save and restore system
+ * msrs. Don't touch the 64-bit msrs if the guest is in legacy
+@@ -2407,7 +2391,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
+ vmx->save_nmsrs = save_nmsrs;
+
+ if (cpu_has_vmx_msr_bitmap())
+- vmx_set_msr_bitmap(&vmx->vcpu);
++ vmx_update_msr_bitmap(&vmx->vcpu);
+ }
+
+ /*
+@@ -3360,6 +3344,8 @@ static void free_loaded_vmcs(struct loaded_vmcs *loaded_vmcs)
+ loaded_vmcs_clear(loaded_vmcs);
+ free_vmcs(loaded_vmcs->vmcs);
+ loaded_vmcs->vmcs = NULL;
++ if (loaded_vmcs->msr_bitmap)
++ free_page((unsigned long)loaded_vmcs->msr_bitmap);
+ }
+
+ static struct vmcs *alloc_vmcs(void)
+@@ -3374,7 +3360,18 @@ static int alloc_loaded_vmcs(struct loaded_vmcs *loaded_vmcs)
+ return -ENOMEM;
+
+ loaded_vmcs_init(loaded_vmcs);
++
++ if (cpu_has_vmx_msr_bitmap()) {
++ loaded_vmcs->msr_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
++ if (!loaded_vmcs->msr_bitmap)
++ goto out_vmcs;
++ memset(loaded_vmcs->msr_bitmap, 0xff, PAGE_SIZE);
++ }
+ return 0;
++
++out_vmcs:
++ free_loaded_vmcs(loaded_vmcs);
++ return -ENOMEM;
+ }
+
+ static void free_kvm_area(void)
+@@ -4373,10 +4370,8 @@ static void free_vpid(int vpid)
+ spin_unlock(&vmx_vpid_lock);
+ }
+
+-#define MSR_TYPE_R 1
+-#define MSR_TYPE_W 2
+-static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
+- u32 msr, int type)
++static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
++ u32 msr, int type)
+ {
+ int f = sizeof(unsigned long);
+
+@@ -4410,8 +4405,8 @@ static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
+ }
+ }
+
+-static void __vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,
+- u32 msr, int type)
++static void __always_inline vmx_enable_intercept_for_msr(unsigned long *msr_bitmap,
++ u32 msr, int type)
+ {
+ int f = sizeof(unsigned long);
+
+@@ -4491,37 +4486,76 @@ static void nested_vmx_disable_intercept_for_msr(unsigned long *msr_bitmap_l1,
+ }
+ }
+
+-static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only)
++static void __always_inline vmx_set_intercept_for_msr(unsigned long *msr_bitmap,
++ u32 msr, int type, bool value)
+ {
+- if (!longmode_only)
+- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy,
+- msr, MSR_TYPE_R | MSR_TYPE_W);
+- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode,
+- msr, MSR_TYPE_R | MSR_TYPE_W);
++ if (value)
++ vmx_enable_intercept_for_msr(msr_bitmap, msr, type);
++ else
++ vmx_disable_intercept_for_msr(msr_bitmap, msr, type);
+ }
+
+-static void vmx_enable_intercept_msr_read_x2apic(u32 msr)
++static u8 vmx_msr_bitmap_mode(struct kvm_vcpu *vcpu)
+ {
+- __vmx_enable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic,
+- msr, MSR_TYPE_R);
+- __vmx_enable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic,
+- msr, MSR_TYPE_R);
++ u8 mode = 0;
++
++ if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) {
++ mode |= MSR_BITMAP_MODE_X2APIC;
++ if (enable_apicv)
++ mode |= MSR_BITMAP_MODE_X2APIC_APICV;
++ }
++
++ if (is_long_mode(vcpu))
++ mode |= MSR_BITMAP_MODE_LM;
++
++ return mode;
+ }
+
+-static void vmx_disable_intercept_msr_read_x2apic(u32 msr)
++#define X2APIC_MSR(r) (APIC_BASE_MSR + ((r) >> 4))
++
++static void vmx_update_msr_bitmap_x2apic(unsigned long *msr_bitmap,
++ u8 mode)
+ {
+- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic,
+- msr, MSR_TYPE_R);
+- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic,
+- msr, MSR_TYPE_R);
++ int msr;
++
++ for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) {
++ unsigned word = msr / BITS_PER_LONG;
++ msr_bitmap[word] = (mode & MSR_BITMAP_MODE_X2APIC_APICV) ? 0 : ~0;
++ msr_bitmap[word + (0x800 / sizeof(long))] = ~0;
++ }
++
++ if (mode & MSR_BITMAP_MODE_X2APIC) {
++ /*
++ * TPR reads and writes can be virtualized even if virtual interrupt
++ * delivery is not in use.
++ */
++ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TASKPRI), MSR_TYPE_RW);
++ if (mode & MSR_BITMAP_MODE_X2APIC_APICV) {
++ vmx_enable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_ID), MSR_TYPE_R);
++ vmx_enable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_TMCCT), MSR_TYPE_R);
++ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_EOI), MSR_TYPE_W);
++ vmx_disable_intercept_for_msr(msr_bitmap, X2APIC_MSR(APIC_SELF_IPI), MSR_TYPE_W);
++ }
++ }
+ }
+
+-static void vmx_disable_intercept_msr_write_x2apic(u32 msr)
++static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu)
+ {
+- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic,
+- msr, MSR_TYPE_W);
+- __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic,
+- msr, MSR_TYPE_W);
++ struct vcpu_vmx *vmx = to_vmx(vcpu);
++ unsigned long *msr_bitmap = vmx->vmcs01.msr_bitmap;
++ u8 mode = vmx_msr_bitmap_mode(vcpu);
++ u8 changed = mode ^ vmx->msr_bitmap_mode;
++
++ if (!changed)
++ return;
++
++ vmx_set_intercept_for_msr(msr_bitmap, MSR_KERNEL_GS_BASE, MSR_TYPE_RW,
++ !(mode & MSR_BITMAP_MODE_LM));
++
++ if (changed & (MSR_BITMAP_MODE_X2APIC | MSR_BITMAP_MODE_X2APIC_APICV))
++ vmx_update_msr_bitmap_x2apic(msr_bitmap, mode);
++
++ vmx->msr_bitmap_mode = mode;
+ }
+
+ static int vmx_cpu_uses_apicv(struct kvm_vcpu *vcpu)
+@@ -4842,7 +4876,7 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
+ vmcs_write64(VMWRITE_BITMAP, __pa(vmx_vmwrite_bitmap));
+ }
+ if (cpu_has_vmx_msr_bitmap())
+- vmcs_write64(MSR_BITMAP, __pa(vmx_msr_bitmap_legacy));
++ vmcs_write64(MSR_BITMAP, __pa(vmx->vmcs01.msr_bitmap));
+
+ vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
+
+@@ -6183,7 +6217,7 @@ static void wakeup_handler(void)
+
+ static __init int hardware_setup(void)
+ {
+- int r = -ENOMEM, i, msr;
++ int r = -ENOMEM, i;
+
+ rdmsrl_safe(MSR_EFER, &host_efer);
+
+@@ -6198,31 +6232,13 @@ static __init int hardware_setup(void)
+ if (!vmx_io_bitmap_b)
+ goto out;
+
+- vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL);
+- if (!vmx_msr_bitmap_legacy)
+- goto out1;
+-
+- vmx_msr_bitmap_legacy_x2apic =
+- (unsigned long *)__get_free_page(GFP_KERNEL);
+- if (!vmx_msr_bitmap_legacy_x2apic)
+- goto out2;
+-
+- vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL);
+- if (!vmx_msr_bitmap_longmode)
+- goto out3;
+-
+- vmx_msr_bitmap_longmode_x2apic =
+- (unsigned long *)__get_free_page(GFP_KERNEL);
+- if (!vmx_msr_bitmap_longmode_x2apic)
+- goto out4;
+-
+ vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
+ if (!vmx_vmread_bitmap)
+- goto out6;
++ goto out1;
+
+ vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
+ if (!vmx_vmwrite_bitmap)
+- goto out7;
++ goto out2;
+
+ memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
+ memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
+@@ -6231,12 +6247,9 @@ static __init int hardware_setup(void)
+
+ memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
+
+- memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
+- memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
+-
+ if (setup_vmcs_config(&vmcs_config) < 0) {
+ r = -EIO;
+- goto out8;
++ goto out3;
+ }
+
+ if (boot_cpu_has(X86_FEATURE_NX))
+@@ -6302,38 +6315,8 @@ static __init int hardware_setup(void)
+ kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
+ }
+
+- vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
+- vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
+- vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
+- vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
+- vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
+- vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
+-
+- memcpy(vmx_msr_bitmap_legacy_x2apic,
+- vmx_msr_bitmap_legacy, PAGE_SIZE);
+- memcpy(vmx_msr_bitmap_longmode_x2apic,
+- vmx_msr_bitmap_longmode, PAGE_SIZE);
+-
+ set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
+
+- if (enable_apicv) {
+- for (msr = 0x800; msr <= 0x8ff; msr++)
+- vmx_disable_intercept_msr_read_x2apic(msr);
+-
+- /* According SDM, in x2apic mode, the whole id reg is used.
+- * But in KVM, it only use the highest eight bits. Need to
+- * intercept it */
+- vmx_enable_intercept_msr_read_x2apic(0x802);
+- /* TMCCT */
+- vmx_enable_intercept_msr_read_x2apic(0x839);
+- /* TPR */
+- vmx_disable_intercept_msr_write_x2apic(0x808);
+- /* EOI */
+- vmx_disable_intercept_msr_write_x2apic(0x80b);
+- /* SELF-IPI */
+- vmx_disable_intercept_msr_write_x2apic(0x83f);
+- }
+-
+ if (enable_ept) {
+ kvm_mmu_set_mask_ptes(0ull,
+ (enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
+@@ -6364,18 +6347,10 @@ static __init int hardware_setup(void)
+
+ return alloc_kvm_area();
+
+-out8:
+- free_page((unsigned long)vmx_vmwrite_bitmap);
+-out7:
+- free_page((unsigned long)vmx_vmread_bitmap);
+-out6:
+- free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
+-out4:
+- free_page((unsigned long)vmx_msr_bitmap_longmode);
+ out3:
+- free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
++ free_page((unsigned long)vmx_vmwrite_bitmap);
+ out2:
+- free_page((unsigned long)vmx_msr_bitmap_legacy);
++ free_page((unsigned long)vmx_vmread_bitmap);
+ out1:
+ free_page((unsigned long)vmx_io_bitmap_b);
+ out:
+@@ -6386,10 +6361,6 @@ static __init int hardware_setup(void)
+
+ static __exit void hardware_unsetup(void)
+ {
+- free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
+- free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
+- free_page((unsigned long)vmx_msr_bitmap_legacy);
+- free_page((unsigned long)vmx_msr_bitmap_longmode);
+ free_page((unsigned long)vmx_io_bitmap_b);
+ free_page((unsigned long)vmx_io_bitmap_a);
+ free_page((unsigned long)vmx_vmwrite_bitmap);
+@@ -6753,13 +6724,6 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ if (r < 0)
+ goto out_vmcs02;
+
+- if (cpu_has_vmx_msr_bitmap()) {
+- vmx->nested.msr_bitmap =
+- (unsigned long *)__get_free_page(GFP_KERNEL);
+- if (!vmx->nested.msr_bitmap)
+- goto out_msr_bitmap;
+- }
+-
+ if (enable_shadow_vmcs) {
+ shadow_vmcs = alloc_vmcs();
+ if (!shadow_vmcs)
+@@ -6784,9 +6748,6 @@ static int handle_vmon(struct kvm_vcpu *vcpu)
+ return 1;
+
+ out_shadow_vmcs:
+- free_page((unsigned long)vmx->nested.msr_bitmap);
+-
+-out_msr_bitmap:
+ free_loaded_vmcs(&vmx->nested.vmcs02);
+
+ out_vmcs02:
+@@ -6860,10 +6821,6 @@ static void free_nested(struct vcpu_vmx *vmx)
+ vmx->nested.vmxon = false;
+ free_vpid(vmx->nested.vpid02);
+ nested_release_vmcs12(vmx);
+- if (vmx->nested.msr_bitmap) {
+- free_page((unsigned long)vmx->nested.msr_bitmap);
+- vmx->nested.msr_bitmap = NULL;
+- }
+ if (enable_shadow_vmcs)
+ free_vmcs(vmx->nested.current_shadow_vmcs);
+ /* Unpin physical memory we referred to in the vmcs02 */
+@@ -8200,7 +8157,7 @@ static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set)
+ }
+ vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control);
+
+- vmx_set_msr_bitmap(vcpu);
++ vmx_update_msr_bitmap(vcpu);
+ }
+
+ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu, hpa_t hpa)
+@@ -8780,6 +8737,7 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
+ {
+ int err;
+ struct vcpu_vmx *vmx = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
++ unsigned long *msr_bitmap;
+ int cpu;
+
+ if (!vmx)
+@@ -8820,6 +8778,15 @@ static struct kvm_vcpu *vmx_create_vcpu(struct kvm *kvm, unsigned int id)
+ if (err < 0)
+ goto free_msrs;
+
++ msr_bitmap = vmx->vmcs01.msr_bitmap;
++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_FS_BASE, MSR_TYPE_RW);
++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_GS_BASE, MSR_TYPE_RW);
++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_KERNEL_GS_BASE, MSR_TYPE_RW);
++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_CS, MSR_TYPE_RW);
++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_ESP, MSR_TYPE_RW);
++ vmx_disable_intercept_for_msr(msr_bitmap, MSR_IA32_SYSENTER_EIP, MSR_TYPE_RW);
++ vmx->msr_bitmap_mode = 0;
++
+ vmx->loaded_vmcs = &vmx->vmcs01;
+ cpu = get_cpu();
+ vmx_vcpu_load(&vmx->vcpu, cpu);
+@@ -9204,7 +9171,7 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
+ int msr;
+ struct page *page;
+ unsigned long *msr_bitmap_l1;
+- unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.msr_bitmap;
++ unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap;
+
+ /* This shortcut is ok because we support only x2APIC MSRs so far. */
+ if (!nested_cpu_has_virt_x2apic_mode(vmcs12))
+@@ -9715,6 +9682,9 @@ static void prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
+ else
+ vmcs_write64(TSC_OFFSET, vmx->nested.vmcs01_tsc_offset);
+
++ if (cpu_has_vmx_msr_bitmap())
++ vmcs_write64(MSR_BITMAP, __pa(vmx->nested.vmcs02.msr_bitmap));
++
+ if (enable_vpid) {
+ /*
+ * There is no direct mapping between vpid02 and vpid12, the
+@@ -10415,7 +10385,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
+ vmcs_write64(GUEST_IA32_DEBUGCTL, 0);
+
+ if (cpu_has_vmx_msr_bitmap())
+- vmx_set_msr_bitmap(vcpu);
++ vmx_update_msr_bitmap(vcpu);
+
+ if (nested_vmx_load_msr(vcpu, vmcs12->vm_exit_msr_load_addr,
+ vmcs12->vm_exit_msr_load_count))
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-045-KVM-x86-Add-IBPB-support.patch b/patches.kernel.org/4.4.168-045-KVM-x86-Add-IBPB-support.patch
new file mode 100644
index 0000000000..37d584eeab
--- /dev/null
+++ b/patches.kernel.org/4.4.168-045-KVM-x86-Add-IBPB-support.patch
@@ -0,0 +1,358 @@
+From: Ashok Raj <ashok.raj@intel.com>
+Date: Thu, 1 Feb 2018 22:59:43 +0100
+Subject: [PATCH] KVM/x86: Add IBPB support
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1068032 bsc#1068032
+Git-commit: 15d45071523d89b3fb7372e2135fbd72f6af9506
+
+commit 15d45071523d89b3fb7372e2135fbd72f6af9506 upstream.
+
+The Indirect Branch Predictor Barrier (IBPB) is an indirect branch
+control mechanism. It keeps earlier branches from influencing
+later ones.
+
+Unlike IBRS and STIBP, IBPB does not define a new mode of operation.
+It's a command that ensures predicted branch targets aren't used after
+the barrier. Although IBRS and IBPB are enumerated by the same CPUID
+enumeration, IBPB is very different.
+
+IBPB helps mitigate against three potential attacks:
+
+* Mitigate guests from being attacked by other guests.
+ - This is addressed by issing IBPB when we do a guest switch.
+
+* Mitigate attacks from guest/ring3->host/ring3.
+ These would require a IBPB during context switch in host, or after
+ VMEXIT. The host process has two ways to mitigate
+ - Either it can be compiled with retpoline
+ - If its going through context switch, and has set !dumpable then
+ there is a IBPB in that path.
+ (Tim's patch: https://patchwork.kernel.org/patch/10192871)
+ - The case where after a VMEXIT you return back to Qemu might make
+ Qemu attackable from guest when Qemu isn't compiled with retpoline.
+ There are issues reported when doing IBPB on every VMEXIT that resulted
+ in some tsc calibration woes in guest.
+
+* Mitigate guest/ring0->host/ring0 attacks.
+ When host kernel is using retpoline it is safe against these attacks.
+ If host kernel isn't using retpoline we might need to do a IBPB flush on
+ every VMEXIT.
+
+Even when using retpoline for indirect calls, in certain conditions 'ret'
+can use the BTB on Skylake-era CPUs. There are other mitigations
+available like RSB stuffing/clearing.
+
+* IBPB is issued only for SVM during svm_free_vcpu().
+ VMX has a vmclear and SVM doesn't. Follow discussion here:
+ https://lkml.org/lkml/2018/1/15/146
+
+Please refer to the following spec for more details on the enumeration
+and control.
+
+Refer here to get documentation about mitigations.
+
+https://software.intel.com/en-us/side-channel-security-support
+
+[peterz: rebase and changelog rewrite]
+[karahmed: - rebase
+ - vmx: expose PRED_CMD if guest has it in CPUID
+ - svm: only pass through IBPB if guest has it in CPUID
+ - vmx: support !cpu_has_vmx_msr_bitmap()]
+ - vmx: support nested]
+[dwmw2: Expose CPUID bit too (AMD IBPB only for now as we lack IBRS)
+ PRED_CMD is a write-only MSR]
+
+Signed-off-by: Ashok Raj <ashok.raj@intel.com>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: kvm@vger.kernel.org
+Cc: Asit Mallick <asit.k.mallick@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Jun Nakajima <jun.nakajima@intel.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Link: http://lkml.kernel.org/r/1515720739-43819-6-git-send-email-ashok.raj@intel.com
+Link: https://lkml.kernel.org/r/1517522386-18410-3-git-send-email-karahmed@amazon.de
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4: adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/cpuid.c | 11 +++++-
+ arch/x86/kvm/cpuid.h | 12 +++++++
+ arch/x86/kvm/svm.c | 28 ++++++++++++++++
+ arch/x86/kvm/vmx.c | 79 ++++++++++++++++++++++++++++++++++++++++++--
+ 4 files changed, 127 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index 338d13d4fd2f..35196f8e1ba6 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -341,6 +341,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+ F(3DNOWPREFETCH) | F(OSVW) | 0 /* IBS */ | F(XOP) |
+ 0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM);
+
++ /* cpuid 0x80000008.ebx */
++ const u32 kvm_cpuid_8000_0008_ebx_x86_features =
++ F(IBPB);
++
+ /* cpuid 0xC0000001.edx */
+ const u32 kvm_supported_word5_x86_features =
+ F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) |
+@@ -583,7 +587,12 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+ if (!g_phys_as)
+ g_phys_as = phys_as;
+ entry->eax = g_phys_as | (virt_as << 8);
+- entry->ebx = entry->edx = 0;
++ entry->edx = 0;
++ /* IBPB isn't necessarily present in hardware cpuid */
++ if (boot_cpu_has(X86_FEATURE_IBPB))
++ entry->ebx |= F(IBPB);
++ entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
++ cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
+ break;
+ }
+ case 0x80000019:
+diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
+index d1534feefcfe..213102389795 100644
+--- a/arch/x86/kvm/cpuid.h
++++ b/arch/x86/kvm/cpuid.h
+@@ -159,6 +159,18 @@ static inline bool guest_cpuid_has_rdtscp(struct kvm_vcpu *vcpu)
+ return best && (best->edx & bit(X86_FEATURE_RDTSCP));
+ }
+
++static inline bool guest_cpuid_has_ibpb(struct kvm_vcpu *vcpu)
++{
++ struct kvm_cpuid_entry2 *best;
++
++ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
++ if (best && (best->ebx & bit(X86_FEATURE_IBPB)))
++ return true;
++ best = kvm_find_cpuid_entry(vcpu, 7, 0);
++ return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
++}
++
++
+ /*
+ * NRIPS is provided through cpuidfn 0x8000000a.edx bit 3
+ */
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index df7827a981dd..d489836da6f5 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -182,6 +182,7 @@ static const struct svm_direct_access_msrs {
+ { .index = MSR_CSTAR, .always = true },
+ { .index = MSR_SYSCALL_MASK, .always = true },
+ #endif
++ { .index = MSR_IA32_PRED_CMD, .always = false },
+ { .index = MSR_IA32_LASTBRANCHFROMIP, .always = false },
+ { .index = MSR_IA32_LASTBRANCHTOIP, .always = false },
+ { .index = MSR_IA32_LASTINTFROMIP, .always = false },
+@@ -411,6 +412,7 @@ struct svm_cpu_data {
+ struct kvm_ldttss_desc *tss_desc;
+
+ struct page *save_area;
++ struct vmcb *current_vmcb;
+ };
+
+ static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
+@@ -1210,11 +1212,17 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
+ __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
+ kvm_vcpu_uninit(vcpu);
+ kmem_cache_free(kvm_vcpu_cache, svm);
++ /*
++ * The vmcb page can be recycled, causing a false negative in
++ * svm_vcpu_load(). So do a full IBPB now.
++ */
++ indirect_branch_prediction_barrier();
+ }
+
+ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ {
+ struct vcpu_svm *svm = to_svm(vcpu);
++ struct svm_cpu_data *sd = per_cpu(svm_data, cpu);
+ int i;
+
+ if (unlikely(cpu != vcpu->cpu)) {
+@@ -1239,6 +1247,10 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
+ }
+ }
++ if (sd->current_vmcb != svm->vmcb) {
++ sd->current_vmcb = svm->vmcb;
++ indirect_branch_prediction_barrier();
++ }
+ }
+
+ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
+@@ -3125,6 +3137,22 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
+ case MSR_IA32_TSC:
+ kvm_write_tsc(vcpu, msr);
+ break;
++ case MSR_IA32_PRED_CMD:
++ if (!msr->host_initiated &&
++ !guest_cpuid_has_ibpb(vcpu))
++ return 1;
++
++ if (data & ~PRED_CMD_IBPB)
++ return 1;
++
++ if (!data)
++ break;
++
++ wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB);
++ if (is_guest_mode(vcpu))
++ break;
++ set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1);
++ break;
+ case MSR_STAR:
+ svm->vmcb->save.star = data;
+ break;
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index e0064855fbdb..a19116fad680 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -544,6 +544,7 @@ struct vcpu_vmx {
+ u64 msr_host_kernel_gs_base;
+ u64 msr_guest_kernel_gs_base;
+ #endif
++
+ u32 vm_entry_controls_shadow;
+ u32 vm_exit_controls_shadow;
+ /*
+@@ -892,6 +893,8 @@ static void copy_vmcs12_to_shadow(struct vcpu_vmx *vmx);
+ static void copy_shadow_to_vmcs12(struct vcpu_vmx *vmx);
+ static int alloc_identity_pagetable(struct kvm *kvm);
+ static void vmx_update_msr_bitmap(struct kvm_vcpu *vcpu);
++static void __always_inline vmx_disable_intercept_for_msr(unsigned long *msr_bitmap,
++ u32 msr, int type);
+
+ static DEFINE_PER_CPU(struct vmcs *, vmxarea);
+ static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
+@@ -1687,6 +1690,29 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
+ vmcs_write32(EXCEPTION_BITMAP, eb);
+ }
+
++/*
++ * Check if MSR is intercepted for L01 MSR bitmap.
++ */
++static bool msr_write_intercepted_l01(struct kvm_vcpu *vcpu, u32 msr)
++{
++ unsigned long *msr_bitmap;
++ int f = sizeof(unsigned long);
++
++ if (!cpu_has_vmx_msr_bitmap())
++ return true;
++
++ msr_bitmap = to_vmx(vcpu)->vmcs01.msr_bitmap;
++
++ if (msr <= 0x1fff) {
++ return !!test_bit(msr, msr_bitmap + 0x800 / f);
++ } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
++ msr &= 0x1fff;
++ return !!test_bit(msr, msr_bitmap + 0xc00 / f);
++ }
++
++ return true;
++}
++
+ static void clear_atomic_switch_msr_special(struct vcpu_vmx *vmx,
+ unsigned long entry, unsigned long exit)
+ {
+@@ -2072,6 +2098,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ if (per_cpu(current_vmcs, cpu) != vmx->loaded_vmcs->vmcs) {
+ per_cpu(current_vmcs, cpu) = vmx->loaded_vmcs->vmcs;
+ vmcs_load(vmx->loaded_vmcs->vmcs);
++ indirect_branch_prediction_barrier();
+ }
+
+ if (vmx->loaded_vmcs->cpu != cpu) {
+@@ -2904,6 +2931,33 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ case MSR_IA32_TSC:
+ kvm_write_tsc(vcpu, msr_info);
+ break;
++ case MSR_IA32_PRED_CMD:
++ if (!msr_info->host_initiated &&
++ !guest_cpuid_has_ibpb(vcpu))
++ return 1;
++
++ if (data & ~PRED_CMD_IBPB)
++ return 1;
++
++ if (!data)
++ break;
++
++ wrmsrl(MSR_IA32_PRED_CMD, PRED_CMD_IBPB);
++
++ /*
++ * For non-nested:
++ * When it's written (to non-zero) for the first time, pass
++ * it through.
++ *
++ * For nested:
++ * The handling of the MSR bitmap for L2 guests is done in
++ * nested_vmx_merge_msr_bitmap. We should not touch the
++ * vmcs02.msr_bitmap here since it gets completely overwritten
++ * in the merging.
++ */
++ vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD,
++ MSR_TYPE_W);
++ break;
+ case MSR_IA32_CR_PAT:
+ if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
+ if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
+@@ -9172,9 +9226,23 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
+ struct page *page;
+ unsigned long *msr_bitmap_l1;
+ unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap;
++ /*
++ * pred_cmd is trying to verify two things:
++ *
++ * 1. L0 gave a permission to L1 to actually passthrough the MSR. This
++ * ensures that we do not accidentally generate an L02 MSR bitmap
++ * from the L12 MSR bitmap that is too permissive.
++ * 2. That L1 or L2s have actually used the MSR. This avoids
++ * unnecessarily merging of the bitmap if the MSR is unused. This
++ * works properly because we only update the L01 MSR bitmap lazily.
++ * So even if L0 should pass L1 these MSRs, the L01 bitmap is only
++ * updated to reflect this when L1 (or its L2s) actually write to
++ * the MSR.
++ */
++ bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
+
+- /* This shortcut is ok because we support only x2APIC MSRs so far. */
+- if (!nested_cpu_has_virt_x2apic_mode(vmcs12))
++ if (!nested_cpu_has_virt_x2apic_mode(vmcs12) &&
++ !pred_cmd)
+ return false;
+
+ page = nested_get_page(vcpu, vmcs12->msr_bitmap);
+@@ -9209,6 +9277,13 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
+ MSR_TYPE_W);
+ }
+ }
++
++ if (pred_cmd)
++ nested_vmx_disable_intercept_for_msr(
++ msr_bitmap_l1, msr_bitmap_l0,
++ MSR_IA32_PRED_CMD,
++ MSR_TYPE_W);
++
+ kunmap(page);
+ nested_release_page_clean(page);
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-046-KVM-VMX-Emulate-MSR_IA32_ARCH_CAPABILITIES.patch b/patches.kernel.org/4.4.168-046-KVM-VMX-Emulate-MSR_IA32_ARCH_CAPABILITIES.patch
new file mode 100644
index 0000000000..1e75380595
--- /dev/null
+++ b/patches.kernel.org/4.4.168-046-KVM-VMX-Emulate-MSR_IA32_ARCH_CAPABILITIES.patch
@@ -0,0 +1,163 @@
+From: KarimAllah Ahmed <karahmed@amazon.de>
+Date: Thu, 1 Feb 2018 22:59:44 +0100
+Subject: [PATCH] KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 28c1c9fabf48d6ad596273a11c46e0d0da3e14cd
+
+commit 28c1c9fabf48d6ad596273a11c46e0d0da3e14cd upstream.
+
+Intel processors use MSR_IA32_ARCH_CAPABILITIES MSR to indicate RDCL_NO
+(bit 0) and IBRS_ALL (bit 1). This is a read-only MSR. By default the
+contents will come directly from the hardware, but user-space can still
+override it.
+
+[dwmw2: The bit in kvm_cpuid_7_0_edx_x86_features can be unconditional]
+
+Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Jim Mattson <jmattson@google.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Jun Nakajima <jun.nakajima@intel.com>
+Cc: kvm@vger.kernel.org
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Asit Mallick <asit.k.mallick@intel.com>
+Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Ashok Raj <ashok.raj@intel.com>
+Link: https://lkml.kernel.org/r/1517522386-18410-4-git-send-email-karahmed@amazon.de
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4: adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/cpuid.c | 11 +++++++++--
+ arch/x86/kvm/cpuid.h | 8 ++++++++
+ arch/x86/kvm/vmx.c | 15 +++++++++++++++
+ arch/x86/kvm/x86.c | 1 +
+ 4 files changed, 33 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index 35196f8e1ba6..2f3483e395bf 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -362,6 +362,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+ const u32 kvm_supported_word10_x86_features =
+ F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | f_xsaves;
+
++ /* cpuid 7.0.edx*/
++ const u32 kvm_cpuid_7_0_edx_x86_features =
++ F(ARCH_CAPABILITIES);
++
+ /* all calls to cpuid_count() should be made on the same cpu */
+ get_cpu();
+
+@@ -439,11 +443,14 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+ cpuid_mask(&entry->ebx, 9);
+ // TSC_ADJUST is emulated
+ entry->ebx |= F(TSC_ADJUST);
+- } else
++ entry->edx &= kvm_cpuid_7_0_edx_x86_features;
++ cpuid_mask(&entry->edx, CPUID_7_EDX);
++ } else {
+ entry->ebx = 0;
++ entry->edx = 0;
++ }
+ entry->eax = 0;
+ entry->ecx = 0;
+- entry->edx = 0;
+ break;
+ }
+ case 9:
+diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
+index 213102389795..67c35486d8d0 100644
+--- a/arch/x86/kvm/cpuid.h
++++ b/arch/x86/kvm/cpuid.h
+@@ -170,6 +170,14 @@ static inline bool guest_cpuid_has_ibpb(struct kvm_vcpu *vcpu)
+ return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
+ }
+
++static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
++{
++ struct kvm_cpuid_entry2 *best;
++
++ best = kvm_find_cpuid_entry(vcpu, 7, 0);
++ return best && (best->edx & bit(X86_FEATURE_ARCH_CAPABILITIES));
++}
++
+
+ /*
+ * NRIPS is provided through cpuidfn 0x8000000a.edx bit 3
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index a19116fad680..3a513997b1cb 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -545,6 +545,8 @@ struct vcpu_vmx {
+ u64 msr_guest_kernel_gs_base;
+ #endif
+
++ u64 arch_capabilities;
++
+ u32 vm_entry_controls_shadow;
+ u32 vm_exit_controls_shadow;
+ /*
+@@ -2832,6 +2834,12 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ case MSR_IA32_TSC:
+ msr_info->data = guest_read_tsc(vcpu);
+ break;
++ case MSR_IA32_ARCH_CAPABILITIES:
++ if (!msr_info->host_initiated &&
++ !guest_cpuid_has_arch_capabilities(vcpu))
++ return 1;
++ msr_info->data = to_vmx(vcpu)->arch_capabilities;
++ break;
+ case MSR_IA32_SYSENTER_CS:
+ msr_info->data = vmcs_read32(GUEST_SYSENTER_CS);
+ break;
+@@ -2958,6 +2966,11 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap, MSR_IA32_PRED_CMD,
+ MSR_TYPE_W);
+ break;
++ case MSR_IA32_ARCH_CAPABILITIES:
++ if (!msr_info->host_initiated)
++ return 1;
++ vmx->arch_capabilities = data;
++ break;
+ case MSR_IA32_CR_PAT:
+ if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
+ if (!kvm_mtrr_valid(vcpu, MSR_IA32_CR_PAT, data))
+@@ -5002,6 +5015,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx)
+ ++vmx->nmsrs;
+ }
+
++ if (boot_cpu_has(X86_FEATURE_ARCH_CAPABILITIES))
++ rdmsrl(MSR_IA32_ARCH_CAPABILITIES, vmx->arch_capabilities);
+
+ vm_exit_controls_init(vmx, vmcs_config.vmexit_ctrl);
+
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index e6ab034f0bc7..276f978efeed 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -961,6 +961,7 @@ static u32 msrs_to_save[] = {
+ #endif
+ MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
+ MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
++ MSR_IA32_ARCH_CAPABILITIES
+ };
+
+ static unsigned num_msrs_to_save;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-047-KVM-VMX-Allow-direct-access-to-MSR_IA32_SPEC_.patch b/patches.kernel.org/4.4.168-047-KVM-VMX-Allow-direct-access-to-MSR_IA32_SPEC_.patch
new file mode 100644
index 0000000000..966c059baf
--- /dev/null
+++ b/patches.kernel.org/4.4.168-047-KVM-VMX-Allow-direct-access-to-MSR_IA32_SPEC_.patch
@@ -0,0 +1,310 @@
+From: KarimAllah Ahmed <karahmed@amazon.de>
+Date: Thu, 1 Feb 2018 22:59:45 +0100
+Subject: [PATCH] KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1068032 bsc#1096242 bsc#1096281
+Git-commit: d28b387fb74da95d69d2615732f50cceb38e9a4d
+
+commit d28b387fb74da95d69d2615732f50cceb38e9a4d upstream.
+
+[ Based on a patch from Ashok Raj <ashok.raj@intel.com> ]
+
+Add direct access to MSR_IA32_SPEC_CTRL for guests. This is needed for
+guests that will only mitigate Spectre V2 through IBRS+IBPB and will not
+be using a retpoline+IBPB based approach.
+
+To avoid the overhead of saving and restoring the MSR_IA32_SPEC_CTRL for
+guests that do not actually use the MSR, only start saving and restoring
+when a non-zero is written to it.
+
+No attempt is made to handle STIBP here, intentionally. Filtering STIBP
+may be added in a future patch, which may require trapping all writes
+if we don't want to pass it through directly to the guest.
+
+[dwmw2: Clean up CPUID bits, save/restore manually, handle reset]
+
+Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Reviewed-by: Jim Mattson <jmattson@google.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Jun Nakajima <jun.nakajima@intel.com>
+Cc: kvm@vger.kernel.org
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Asit Mallick <asit.k.mallick@intel.com>
+Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Ashok Raj <ashok.raj@intel.com>
+Link: https://lkml.kernel.org/r/1517522386-18410-5-git-send-email-karahmed@amazon.de
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/cpuid.c | 8 ++--
+ arch/x86/kvm/cpuid.h | 11 +++++
+ arch/x86/kvm/vmx.c | 103 ++++++++++++++++++++++++++++++++++++++++++-
+ arch/x86/kvm/x86.c | 2 +-
+ 4 files changed, 118 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index 2f3483e395bf..0ab72a8387d4 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -343,7 +343,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+
+ /* cpuid 0x80000008.ebx */
+ const u32 kvm_cpuid_8000_0008_ebx_x86_features =
+- F(IBPB);
++ F(IBPB) | F(IBRS);
+
+ /* cpuid 0xC0000001.edx */
+ const u32 kvm_supported_word5_x86_features =
+@@ -364,7 +364,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+
+ /* cpuid 7.0.edx*/
+ const u32 kvm_cpuid_7_0_edx_x86_features =
+- F(ARCH_CAPABILITIES);
++ F(SPEC_CTRL) | F(ARCH_CAPABILITIES);
+
+ /* all calls to cpuid_count() should be made on the same cpu */
+ get_cpu();
+@@ -595,9 +595,11 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+ g_phys_as = phys_as;
+ entry->eax = g_phys_as | (virt_as << 8);
+ entry->edx = 0;
+- /* IBPB isn't necessarily present in hardware cpuid */
++ /* IBRS and IBPB aren't necessarily present in hardware cpuid */
+ if (boot_cpu_has(X86_FEATURE_IBPB))
+ entry->ebx |= F(IBPB);
++ if (boot_cpu_has(X86_FEATURE_IBRS))
++ entry->ebx |= F(IBRS);
+ entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
+ cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
+ break;
+diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
+index 67c35486d8d0..7f74d7e18a01 100644
+--- a/arch/x86/kvm/cpuid.h
++++ b/arch/x86/kvm/cpuid.h
+@@ -170,6 +170,17 @@ static inline bool guest_cpuid_has_ibpb(struct kvm_vcpu *vcpu)
+ return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
+ }
+
++static inline bool guest_cpuid_has_ibrs(struct kvm_vcpu *vcpu)
++{
++ struct kvm_cpuid_entry2 *best;
++
++ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
++ if (best && (best->ebx & bit(X86_FEATURE_IBRS)))
++ return true;
++ best = kvm_find_cpuid_entry(vcpu, 7, 0);
++ return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
++}
++
+ static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_cpuid_entry2 *best;
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 3a513997b1cb..b118d415ca08 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -546,6 +546,7 @@ struct vcpu_vmx {
+ #endif
+
+ u64 arch_capabilities;
++ u64 spec_ctrl;
+
+ u32 vm_entry_controls_shadow;
+ u32 vm_exit_controls_shadow;
+@@ -1692,6 +1693,29 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
+ vmcs_write32(EXCEPTION_BITMAP, eb);
+ }
+
++/*
++ * Check if MSR is intercepted for currently loaded MSR bitmap.
++ */
++static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
++{
++ unsigned long *msr_bitmap;
++ int f = sizeof(unsigned long);
++
++ if (!cpu_has_vmx_msr_bitmap())
++ return true;
++
++ msr_bitmap = to_vmx(vcpu)->loaded_vmcs->msr_bitmap;
++
++ if (msr <= 0x1fff) {
++ return !!test_bit(msr, msr_bitmap + 0x800 / f);
++ } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) {
++ msr &= 0x1fff;
++ return !!test_bit(msr, msr_bitmap + 0xc00 / f);
++ }
++
++ return true;
++}
++
+ /*
+ * Check if MSR is intercepted for L01 MSR bitmap.
+ */
+@@ -2834,6 +2858,13 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ case MSR_IA32_TSC:
+ msr_info->data = guest_read_tsc(vcpu);
+ break;
++ case MSR_IA32_SPEC_CTRL:
++ if (!msr_info->host_initiated &&
++ !guest_cpuid_has_ibrs(vcpu))
++ return 1;
++
++ msr_info->data = to_vmx(vcpu)->spec_ctrl;
++ break;
+ case MSR_IA32_ARCH_CAPABILITIES:
+ if (!msr_info->host_initiated &&
+ !guest_cpuid_has_arch_capabilities(vcpu))
+@@ -2939,6 +2970,36 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ case MSR_IA32_TSC:
+ kvm_write_tsc(vcpu, msr_info);
+ break;
++ case MSR_IA32_SPEC_CTRL:
++ if (!msr_info->host_initiated &&
++ !guest_cpuid_has_ibrs(vcpu))
++ return 1;
++
++ /* The STIBP bit doesn't fault even if it's not advertised */
++ if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP))
++ return 1;
++
++ vmx->spec_ctrl = data;
++
++ if (!data)
++ break;
++
++ /*
++ * For non-nested:
++ * When it's written (to non-zero) for the first time, pass
++ * it through.
++ *
++ * For nested:
++ * The handling of the MSR bitmap for L2 guests is done in
++ * nested_vmx_merge_msr_bitmap. We should not touch the
++ * vmcs02.msr_bitmap here since it gets completely overwritten
++ * in the merging. We update the vmcs01 here for L1 as well
++ * since it will end up touching the MSR anyway now.
++ */
++ vmx_disable_intercept_for_msr(vmx->vmcs01.msr_bitmap,
++ MSR_IA32_SPEC_CTRL,
++ MSR_TYPE_RW);
++ break;
+ case MSR_IA32_PRED_CMD:
+ if (!msr_info->host_initiated &&
+ !guest_cpuid_has_ibpb(vcpu))
+@@ -5045,6 +5106,7 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
+ u64 cr0;
+
+ vmx->rmode.vm86_active = 0;
++ vmx->spec_ctrl = 0;
+
+ vmx->soft_vnmi_blocked = 0;
+
+@@ -8589,6 +8651,15 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ atomic_switch_perf_msrs(vmx);
+ debugctlmsr = get_debugctlmsr();
+
++ /*
++ * If this vCPU has touched SPEC_CTRL, restore the guest's value if
++ * it's non-zero. Since vmentry is serialising on affected CPUs, there
++ * is no need to worry about the conditional branch over the wrmsr
++ * being speculatively taken.
++ */
++ if (vmx->spec_ctrl)
++ wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
++
+ vmx->__launched = vmx->loaded_vmcs->launched;
+ asm(
+ /* Store host registers */
+@@ -8707,6 +8778,27 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ #endif
+ );
+
++ /*
++ * We do not use IBRS in the kernel. If this vCPU has used the
++ * SPEC_CTRL MSR it may have left it on; save the value and
++ * turn it off. This is much more efficient than blindly adding
++ * it to the atomic save/restore list. Especially as the former
++ * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
++ *
++ * For non-nested case:
++ * If the L01 MSR bitmap does not intercept the MSR, then we need to
++ * save it.
++ *
++ * For nested case:
++ * If the L02 MSR bitmap does not intercept the MSR, then we need to
++ * save it.
++ */
++ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
++ rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
++
++ if (vmx->spec_ctrl)
++ wrmsrl(MSR_IA32_SPEC_CTRL, 0);
++
+ /* Eliminate branch target predictions from guest mode */
+ vmexit_fill_RSB();
+
+@@ -9242,7 +9334,7 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
+ unsigned long *msr_bitmap_l1;
+ unsigned long *msr_bitmap_l0 = to_vmx(vcpu)->nested.vmcs02.msr_bitmap;
+ /*
+- * pred_cmd is trying to verify two things:
++ * pred_cmd & spec_ctrl are trying to verify two things:
+ *
+ * 1. L0 gave a permission to L1 to actually passthrough the MSR. This
+ * ensures that we do not accidentally generate an L02 MSR bitmap
+@@ -9255,9 +9347,10 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
+ * the MSR.
+ */
+ bool pred_cmd = msr_write_intercepted_l01(vcpu, MSR_IA32_PRED_CMD);
++ bool spec_ctrl = msr_write_intercepted_l01(vcpu, MSR_IA32_SPEC_CTRL);
+
+ if (!nested_cpu_has_virt_x2apic_mode(vmcs12) &&
+- !pred_cmd)
++ !pred_cmd && !spec_ctrl)
+ return false;
+
+ page = nested_get_page(vcpu, vmcs12->msr_bitmap);
+@@ -9293,6 +9386,12 @@ static inline bool nested_vmx_merge_msr_bitmap(struct kvm_vcpu *vcpu,
+ }
+ }
+
++ if (spec_ctrl)
++ nested_vmx_disable_intercept_for_msr(
++ msr_bitmap_l1, msr_bitmap_l0,
++ MSR_IA32_SPEC_CTRL,
++ MSR_TYPE_R | MSR_TYPE_W);
++
+ if (pred_cmd)
+ nested_vmx_disable_intercept_for_msr(
+ msr_bitmap_l1, msr_bitmap_l0,
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 276f978efeed..12a91ea85d3a 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -961,7 +961,7 @@ static u32 msrs_to_save[] = {
+ #endif
+ MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA,
+ MSR_IA32_FEATURE_CONTROL, MSR_IA32_BNDCFGS, MSR_TSC_AUX,
+- MSR_IA32_ARCH_CAPABILITIES
++ MSR_IA32_SPEC_CTRL, MSR_IA32_ARCH_CAPABILITIES
+ };
+
+ static unsigned num_msrs_to_save;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-048-KVM-SVM-Allow-direct-access-to-MSR_IA32_SPEC_.patch b/patches.kernel.org/4.4.168-048-KVM-SVM-Allow-direct-access-to-MSR_IA32_SPEC_.patch
new file mode 100644
index 0000000000..73280460f6
--- /dev/null
+++ b/patches.kernel.org/4.4.168-048-KVM-SVM-Allow-direct-access-to-MSR_IA32_SPEC_.patch
@@ -0,0 +1,197 @@
+From: KarimAllah Ahmed <karahmed@amazon.de>
+Date: Sat, 3 Feb 2018 15:56:23 +0100
+Subject: [PATCH] KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1068032
+Git-commit: b2ac58f90540e39324e7a29a7ad471407ae0bf48
+
+commit b2ac58f90540e39324e7a29a7ad471407ae0bf48 upstream.
+
+[ Based on a patch from Paolo Bonzini <pbonzini@redhat.com> ]
+
+... basically doing exactly what we do for VMX:
+
+- Passthrough SPEC_CTRL to guests (if enabled in guest CPUID)
+- Save and restore SPEC_CTRL around VMExit and VMEntry only if the guest
+ actually used it.
+
+Signed-off-by: KarimAllah Ahmed <karahmed@amazon.de>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Jun Nakajima <jun.nakajima@intel.com>
+Cc: kvm@vger.kernel.org
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Asit Mallick <asit.k.mallick@intel.com>
+Cc: Arjan Van De Ven <arjan.van.de.ven@intel.com>
+Cc: Greg KH <gregkh@linuxfoundation.org>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Dan Williams <dan.j.williams@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Ashok Raj <ashok.raj@intel.com>
+Link: https://lkml.kernel.org/r/1517669783-20732-1-git-send-email-karahmed@amazon.de
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/svm.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 88 insertions(+)
+
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index d489836da6f5..9a390fb95b4b 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -147,6 +147,8 @@ struct vcpu_svm {
+ u64 gs_base;
+ } host;
+
++ u64 spec_ctrl;
++
+ u32 *msrpm;
+
+ ulong nmi_iret_rip;
+@@ -182,6 +184,7 @@ static const struct svm_direct_access_msrs {
+ { .index = MSR_CSTAR, .always = true },
+ { .index = MSR_SYSCALL_MASK, .always = true },
+ #endif
++ { .index = MSR_IA32_SPEC_CTRL, .always = false },
+ { .index = MSR_IA32_PRED_CMD, .always = false },
+ { .index = MSR_IA32_LASTBRANCHFROMIP, .always = false },
+ { .index = MSR_IA32_LASTBRANCHTOIP, .always = false },
+@@ -764,6 +767,25 @@ static bool valid_msr_intercept(u32 index)
+ return false;
+ }
+
++static bool msr_write_intercepted(struct kvm_vcpu *vcpu, unsigned msr)
++{
++ u8 bit_write;
++ unsigned long tmp;
++ u32 offset;
++ u32 *msrpm;
++
++ msrpm = is_guest_mode(vcpu) ? to_svm(vcpu)->nested.msrpm:
++ to_svm(vcpu)->msrpm;
++
++ offset = svm_msrpm_offset(msr);
++ bit_write = 2 * (msr & 0x0f) + 1;
++ tmp = msrpm[offset];
++
++ BUG_ON(offset == MSR_INVALID);
++
++ return !!test_bit(bit_write, &tmp);
++}
++
+ static void set_msr_interception(u32 *msrpm, unsigned msr,
+ int read, int write)
+ {
+@@ -1122,6 +1144,8 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
+ u32 dummy;
+ u32 eax = 1;
+
++ svm->spec_ctrl = 0;
++
+ if (!init_event) {
+ svm->vcpu.arch.apic_base = APIC_DEFAULT_PHYS_BASE |
+ MSR_IA32_APICBASE_ENABLE;
+@@ -3063,6 +3087,13 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ case MSR_VM_CR:
+ msr_info->data = svm->nested.vm_cr_msr;
+ break;
++ case MSR_IA32_SPEC_CTRL:
++ if (!msr_info->host_initiated &&
++ !guest_cpuid_has_ibrs(vcpu))
++ return 1;
++
++ msr_info->data = svm->spec_ctrl;
++ break;
+ case MSR_IA32_UCODE_REV:
+ msr_info->data = 0x01000065;
+ break;
+@@ -3137,6 +3168,33 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
+ case MSR_IA32_TSC:
+ kvm_write_tsc(vcpu, msr);
+ break;
++ case MSR_IA32_SPEC_CTRL:
++ if (!msr->host_initiated &&
++ !guest_cpuid_has_ibrs(vcpu))
++ return 1;
++
++ /* The STIBP bit doesn't fault even if it's not advertised */
++ if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP))
++ return 1;
++
++ svm->spec_ctrl = data;
++
++ if (!data)
++ break;
++
++ /*
++ * For non-nested:
++ * When it's written (to non-zero) for the first time, pass
++ * it through.
++ *
++ * For nested:
++ * The handling of the MSR bitmap for L2 guests is done in
++ * nested_svm_vmrun_msrpm.
++ * We update the L1 MSR bit as well since it will end up
++ * touching the MSR anyway now.
++ */
++ set_msr_interception(svm->msrpm, MSR_IA32_SPEC_CTRL, 1, 1);
++ break;
+ case MSR_IA32_PRED_CMD:
+ if (!msr->host_initiated &&
+ !guest_cpuid_has_ibpb(vcpu))
+@@ -3839,6 +3897,15 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+
+ local_irq_enable();
+
++ /*
++ * If this vCPU has touched SPEC_CTRL, restore the guest's value if
++ * it's non-zero. Since vmentry is serialising on affected CPUs, there
++ * is no need to worry about the conditional branch over the wrmsr
++ * being speculatively taken.
++ */
++ if (svm->spec_ctrl)
++ wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
++
+ asm volatile (
+ "push %%" _ASM_BP "; \n\t"
+ "mov %c[rbx](%[svm]), %%" _ASM_BX " \n\t"
+@@ -3931,6 +3998,27 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ #endif
+ );
+
++ /*
++ * We do not use IBRS in the kernel. If this vCPU has used the
++ * SPEC_CTRL MSR it may have left it on; save the value and
++ * turn it off. This is much more efficient than blindly adding
++ * it to the atomic save/restore list. Especially as the former
++ * (Saving guest MSRs on vmexit) doesn't even exist in KVM.
++ *
++ * For non-nested case:
++ * If the L01 MSR bitmap does not intercept the MSR, then we need to
++ * save it.
++ *
++ * For nested case:
++ * If the L02 MSR bitmap does not intercept the MSR, then we need to
++ * save it.
++ */
++ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
++ rdmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
++
++ if (svm->spec_ctrl)
++ wrmsrl(MSR_IA32_SPEC_CTRL, 0);
++
+ /* Eliminate branch target predictions from guest mode */
+ vmexit_fill_RSB();
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-049-KVM-x86-Remove-indirect-MSR-op-calls-from-SPE.patch b/patches.kernel.org/4.4.168-049-KVM-x86-Remove-indirect-MSR-op-calls-from-SPE.patch
new file mode 100644
index 0000000000..4298e62898
--- /dev/null
+++ b/patches.kernel.org/4.4.168-049-KVM-x86-Remove-indirect-MSR-op-calls-from-SPE.patch
@@ -0,0 +1,111 @@
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 22 Feb 2018 16:43:17 +0100
+Subject: [PATCH] KVM/x86: Remove indirect MSR op calls from SPEC_CTRL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: ecb586bd29c99fb4de599dec388658e74388daad
+
+commit ecb586bd29c99fb4de599dec388658e74388daad upstream.
+
+Having a paravirt indirect call in the IBRS restore path is not a
+good idea, since we are trying to protect from speculative execution
+of bogus indirect branch targets. It is also slower, so use
+native_wrmsrl() on the vmentry path too.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Jim Mattson <jmattson@google.com>
+Cc: David Woodhouse <dwmw@amazon.co.uk>
+Cc: KarimAllah Ahmed <karahmed@amazon.de>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Radim Krčmář <rkrcmar@redhat.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: kvm@vger.kernel.org
+Cc: stable@vger.kernel.org
+Fixes: d28b387fb74da95d69d2615732f50cceb38e9a4d
+Link: http://lkml.kernel.org/r/20180222154318.20361-2-pbonzini@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4: adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/svm.c | 7 ++++---
+ arch/x86/kvm/vmx.c | 7 ++++---
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index 9a390fb95b4b..e1f20e0d62c2 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -37,6 +37,7 @@
+ #include <asm/desc.h>
+ #include <asm/debugreg.h>
+ #include <asm/kvm_para.h>
++#include <asm/microcode.h>
+ #include <asm/spec-ctrl.h>
+
+ #include <asm/virtext.h>
+@@ -3904,7 +3905,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ * being speculatively taken.
+ */
+ if (svm->spec_ctrl)
+- wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
++ native_wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
+
+ asm volatile (
+ "push %%" _ASM_BP "; \n\t"
+@@ -4014,10 +4015,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ * save it.
+ */
+ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
+- rdmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
++ svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
+
+ if (svm->spec_ctrl)
+- wrmsrl(MSR_IA32_SPEC_CTRL, 0);
++ native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
+
+ /* Eliminate branch target predictions from guest mode */
+ vmexit_fill_RSB();
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index b118d415ca08..f7b5c009859e 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -48,6 +48,7 @@
+ #include <asm/kexec.h>
+ #include <asm/apic.h>
+ #include <asm/irq_remapping.h>
++#include <asm/microcode.h>
+ #include <asm/spec-ctrl.h>
+
+ #include "trace.h"
+@@ -8658,7 +8659,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ * being speculatively taken.
+ */
+ if (vmx->spec_ctrl)
+- wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
++ native_wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
+
+ vmx->__launched = vmx->loaded_vmcs->launched;
+ asm(
+@@ -8794,10 +8795,10 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ * save it.
+ */
+ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
+- rdmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
++ vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
+
+ if (vmx->spec_ctrl)
+- wrmsrl(MSR_IA32_SPEC_CTRL, 0);
++ native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
+
+ /* Eliminate branch target predictions from guest mode */
+ vmexit_fill_RSB();
+--
+2.20.1
+
diff --git a/patches.suse/x86-reorganize-SMAP-handling-in-user-space-accesses.patch b/patches.kernel.org/4.4.168-050-x86-reorganize-SMAP-handling-in-user-space-ac.patch
index 068758476d..938b1e89f8 100644
--- a/patches.suse/x86-reorganize-SMAP-handling-in-user-space-accesses.patch
+++ b/patches.kernel.org/4.4.168-050-x86-reorganize-SMAP-handling-in-user-space-ac.patch
@@ -1,12 +1,12 @@
-From 39da83e14bd2798605905275b526d0df2d6a76e4 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Thu, 17 Dec 2015 09:45:09 -0800
Subject: [PATCH] x86: reorganize SMAP handling in user space accesses
-
-References: x86 performance -- uaccess
-Patch-mainline: v4.5
+Patch-mainline: 4.4.168
+References: -- bnc#1012382 performance uaccess x86
Git-commit: 11f1a4b9755f5dbc3e822a96502ebe9b044b14d8
+commit 11f1a4b9755f5dbc3e822a96502ebe9b044b14d8 upstream.
+
This reorganizes how we do the stac/clac instructions in the user access
code. Instead of adding the instructions directly to the same inline
asm that does the actual user level access and exception handling, add
@@ -28,17 +28,19 @@ Other than those two cleanups that happened naturally from the
re-organization, this should not make any difference. Yet.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Mel Gorman <mgorman@suse.de>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- arch/x86/include/asm/uaccess.h | 53 ++++++++++++++--------
- arch/x86/include/asm/uaccess_64.h | 94 +++++++++++++++++++++++++++------------
+ arch/x86/include/asm/uaccess.h | 53 +++++++++++------
+ arch/x86/include/asm/uaccess_64.h | 94 ++++++++++++++++++++++---------
2 files changed, 101 insertions(+), 46 deletions(-)
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
-index 09b1b0ab94b7..cc228f4713da 100644
+index d788b0cdc0ad..e93a69f9a225 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
-@@ -134,6 +134,9 @@ extern int __get_user_4(void);
+@@ -144,6 +144,9 @@ extern int __get_user_4(void);
extern int __get_user_8(void);
extern int __get_user_bad(void);
@@ -48,7 +50,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
/*
* This is a type: either unsigned long, if the argument fits into
* that type, or otherwise unsigned long long.
-@@ -193,10 +196,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
+@@ -203,10 +206,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
#ifdef CONFIG_X86_32
#define __put_user_asm_u64(x, addr, err, errret) \
@@ -61,7 +63,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
".section .fixup,\"ax\"\n" \
"4: movl %3,%0\n" \
" jmp 3b\n" \
-@@ -207,10 +210,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
+@@ -217,10 +220,10 @@ __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
: "A" (x), "r" (addr), "i" (errret), "0" (err))
#define __put_user_asm_ex_u64(x, addr) \
@@ -74,7 +76,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
_ASM_EXTABLE_EX(1b, 2b) \
_ASM_EXTABLE_EX(2b, 3b) \
: : "A" (x), "r" (addr))
-@@ -304,6 +307,10 @@ do { \
+@@ -314,6 +317,10 @@ do { \
} \
} while (0)
@@ -85,7 +87,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
#define __put_user_size_ex(x, ptr, size) \
do { \
__chk_user_ptr(ptr); \
-@@ -358,9 +365,9 @@ do { \
+@@ -368,9 +375,9 @@ do { \
} while (0)
#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
@@ -97,7 +99,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
".section .fixup,\"ax\"\n" \
"3: mov %3,%0\n" \
" xor"itype" %"rtype"1,%"rtype"1\n" \
-@@ -370,6 +377,10 @@ do { \
+@@ -380,6 +387,10 @@ do { \
: "=r" (err), ltype(x) \
: "m" (__m(addr)), "i" (errret), "0" (err))
@@ -108,7 +110,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
#define __get_user_size_ex(x, ptr, size) \
do { \
__chk_user_ptr(ptr); \
-@@ -400,7 +411,9 @@ do { \
+@@ -410,7 +421,9 @@ do { \
#define __put_user_nocheck(x, ptr, size) \
({ \
int __pu_err; \
@@ -118,7 +120,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
__builtin_expect(__pu_err, 0); \
})
-@@ -408,7 +421,9 @@ do { \
+@@ -418,7 +431,9 @@ do { \
({ \
int __gu_err; \
unsigned long __gu_val; \
@@ -128,7 +130,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
(x) = (__force __typeof__(*(ptr)))__gu_val; \
__builtin_expect(__gu_err, 0); \
})
-@@ -423,9 +438,9 @@ struct __large_struct { unsigned long buf[100]; };
+@@ -433,9 +448,9 @@ struct __large_struct { unsigned long buf[100]; };
* aliasing issues.
*/
#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
@@ -140,7 +142,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
".section .fixup,\"ax\"\n" \
"3: mov %3,%0\n" \
" jmp 2b\n" \
-@@ -445,11 +460,11 @@ struct __large_struct { unsigned long buf[100]; };
+@@ -455,11 +470,11 @@ struct __large_struct { unsigned long buf[100]; };
*/
#define uaccess_try do { \
current_thread_info()->uaccess_err = 0; \
@@ -154,7 +156,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
(err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \
} while (0)
-@@ -547,12 +562,13 @@ extern void __cmpxchg_wrong_size(void)
+@@ -557,12 +572,13 @@ extern void __cmpxchg_wrong_size(void)
__typeof__(ptr) __uval = (uval); \
__typeof__(*(ptr)) __old = (old); \
__typeof__(*(ptr)) __new = (new); \
@@ -170,7 +172,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
-@@ -566,9 +582,9 @@ extern void __cmpxchg_wrong_size(void)
+@@ -576,9 +592,9 @@ extern void __cmpxchg_wrong_size(void)
} \
case 2: \
{ \
@@ -182,7 +184,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
-@@ -582,9 +598,9 @@ extern void __cmpxchg_wrong_size(void)
+@@ -592,9 +608,9 @@ extern void __cmpxchg_wrong_size(void)
} \
case 4: \
{ \
@@ -194,7 +196,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
-@@ -601,9 +617,9 @@ extern void __cmpxchg_wrong_size(void)
+@@ -611,9 +627,9 @@ extern void __cmpxchg_wrong_size(void)
if (!IS_ENABLED(CONFIG_X86_64)) \
__cmpxchg_wrong_size(); \
\
@@ -206,7 +208,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
"\t.section .fixup, \"ax\"\n" \
"3:\tmov %3, %0\n" \
"\tjmp 2b\n" \
-@@ -618,6 +634,7 @@ extern void __cmpxchg_wrong_size(void)
+@@ -628,6 +644,7 @@ extern void __cmpxchg_wrong_size(void)
default: \
__cmpxchg_wrong_size(); \
} \
@@ -215,7 +217,7 @@ index 09b1b0ab94b7..cc228f4713da 100644
__ret; \
})
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
-index f2f9b39b274a..b89c34c4019b 100644
+index d83a55b95a48..307698688fa1 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -56,35 +56,49 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size)
@@ -396,3 +398,6 @@ index f2f9b39b274a..b89c34c4019b 100644
return ret;
}
default:
+--
+2.20.1
+
diff --git a/patches.suse/0001-x86-fix-SMAP-in-32-bit-environments.patch b/patches.kernel.org/4.4.168-051-x86-fix-SMAP-in-32-bit-environments.patch
index 456e6f3418..b62c81d9f0 100644
--- a/patches.suse/0001-x86-fix-SMAP-in-32-bit-environments.patch
+++ b/patches.kernel.org/4.4.168-051-x86-fix-SMAP-in-32-bit-environments.patch
@@ -1,10 +1,11 @@
-From de9e478b9d49f3a0214310d921450cf5bb4a21e6 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <torvalds@linux-foundation.org>
Date: Tue, 23 Feb 2016 14:58:52 -0800
Subject: [PATCH] x86: fix SMAP in 32-bit environments
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#971070
Git-commit: de9e478b9d49f3a0214310d921450cf5bb4a21e6
-Patch-mainline: v4.5-rc6
-References: bsc#971070
+
+commit de9e478b9d49f3a0214310d921450cf5bb4a21e6 upstream.
In commit 11f1a4b9755f ("x86: reorganize SMAP handling in user space
accesses") I changed how the stac/clac instructions were generated
@@ -27,13 +28,11 @@ should be cleaned up to avoid all the duplicated code in it, and this
commit just expands on the problem. But this just fixes the bug without
any bigger cleanup surgery.
-XXX: SLE12-SP2: this is backported as the change that caused the issue
-was also backported via 2b085e4c045.
-
Reported-and-tested-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
-
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
arch/x86/include/asm/uaccess_32.h | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
@@ -132,5 +131,5 @@ index f5dcb5204dcd..3fe0eac59462 100644
}
}
--
-2.1.4
+2.20.1
diff --git a/patches.suse/0005-x86-Introduce-__uaccess_begin_nospec-and-uaccess_try.patch b/patches.kernel.org/4.4.168-052-x86-Introduce-__uaccess_begin_nospec-and-uacc.patch
index 89131b3296..85a640366b 100644
--- a/patches.suse/0005-x86-Introduce-__uaccess_begin_nospec-and-uaccess_try.patch
+++ b/patches.kernel.org/4.4.168-052-x86-Introduce-__uaccess_begin_nospec-and-uacc.patch
@@ -1,9 +1,12 @@
From: Dan Williams <dan.j.williams@intel.com>
Date: Mon, 29 Jan 2018 17:02:39 -0800
-Subject: x86: Introduce __uaccess_begin_nospec() and uaccess_try_nospec
+Subject: [PATCH] x86: Introduce __uaccess_begin_nospec() and
+ uaccess_try_nospec
+Patch-mainline: 4.4.168
+References: CVE-2017-5753 bnc#1012382 bsc#1068032
Git-commit: b3bbfb3fb5d25776b8e3f361d2eedaabb0b496cd
-Patch-mainline: v4.16-rc1
-References: bsc#1068032 CVE-2017-5753
+
+commit b3bbfb3fb5d25776b8e3f361d2eedaabb0b496cd upstream.
For __get_user() paths, do not allow the kernel to speculate on the value
of a user controlled pointer. In addition to the 'stac' instruction for
@@ -44,11 +47,16 @@ Cc: gregkh@linuxfoundation.org
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: alan@linux.intel.com
Link: https://lkml.kernel.org/r/151727415922.33451.5796614273104346583.stgit@dwillia2-desk3.amr.corp.intel.com
+[bwh: Backported to 4.4: use current_thread_info()]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- arch/x86/include/asm/uaccess.h | 9 +++++++++
+ arch/x86/include/asm/uaccess.h | 9 +++++++++
1 file changed, 9 insertions(+)
+diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
+index e93a69f9a225..4b50bc52ea3e 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -146,6 +146,11 @@ extern int __get_user_bad(void);
@@ -63,7 +71,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
/*
* This is a type: either unsigned long, if the argument fits into
-@@ -473,6 +478,10 @@ struct __large_struct { unsigned long bu
+@@ -473,6 +478,10 @@ struct __large_struct { unsigned long buf[100]; };
__uaccess_begin(); \
barrier();
@@ -74,3 +82,6 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
#define uaccess_catch(err) \
__uaccess_end(); \
(err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \
+--
+2.20.1
+
diff --git a/patches.suse/0006-x86-usercopy-Replace-open-coded-stac-clac-with-__uac.patch b/patches.kernel.org/4.4.168-053-x86-usercopy-Replace-open-coded-stac-clac-wit.patch
index d23e51babe..af801536ab 100644
--- a/patches.suse/0006-x86-usercopy-Replace-open-coded-stac-clac-with-__uac.patch
+++ b/patches.kernel.org/4.4.168-053-x86-usercopy-Replace-open-coded-stac-clac-wit.patch
@@ -1,10 +1,12 @@
From: Dan Williams <dan.j.williams@intel.com>
Date: Mon, 29 Jan 2018 17:02:44 -0800
-Subject: x86/usercopy: Replace open coded stac/clac with __uaccess_{begin,
- end}
+Subject: [PATCH] x86/usercopy: Replace open coded stac/clac with
+ __uaccess_{begin, end}
+Patch-mainline: 4.4.168
+References: CVE-2017-5753 bnc#1012382 bsc#1068032
Git-commit: b5c4ae4f35325d520b230bab6eb3310613b72ac1
-Patch-mainline: v4.16-rc1
-References: bsc#1068032 CVE-2017-5753
+
+commit b5c4ae4f35325d520b230bab6eb3310613b72ac1 upstream.
In preparation for converting some __uaccess_begin() instances to
__uacess_begin_nospec(), make sure all 'from user' uaccess paths are
@@ -25,11 +27,19 @@ Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: torvalds@linux-foundation.org
Cc: alan@linux.intel.com
Link: https://lkml.kernel.org/r/151727416438.33451.17309465232057176966.stgit@dwillia2-desk3.amr.corp.intel.com
+[bwh: Backported to 4.4:
+ - Convert several more functions to use __uaccess_begin_nospec(), that
+ are just wrappers in mainline
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- arch/x86/lib/usercopy_32.c | 20 ++++++++++----------
+ arch/x86/lib/usercopy_32.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
+diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
+index 91d93b95bd86..5755942f5eb2 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
@@ -570,12 +570,12 @@ do { \
@@ -78,7 +88,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
return n;
}
EXPORT_SYMBOL(__copy_from_user_ll_nozero);
-@@ -610,7 +610,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero
+@@ -610,7 +610,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero);
unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,
unsigned long n)
{
@@ -87,7 +97,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
#ifdef CONFIG_X86_INTEL_USERCOPY
if (n > 64 && cpu_has_xmm2)
n = __copy_user_zeroing_intel_nocache(to, from, n);
-@@ -619,7 +619,7 @@ unsigned long __copy_from_user_ll_nocach
+@@ -619,7 +619,7 @@ unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,
#else
__copy_user_zeroing(to, from, n);
#endif
@@ -96,7 +106,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
return n;
}
EXPORT_SYMBOL(__copy_from_user_ll_nocache);
-@@ -627,7 +627,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocach
+@@ -627,7 +627,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocache);
unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from,
unsigned long n)
{
@@ -105,7 +115,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
#ifdef CONFIG_X86_INTEL_USERCOPY
if (n > 64 && cpu_has_xmm2)
n = __copy_user_intel_nocache(to, from, n);
-@@ -636,7 +636,7 @@ unsigned long __copy_from_user_ll_nocach
+@@ -636,7 +636,7 @@ unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *fr
#else
__copy_user(to, from, n);
#endif
@@ -114,3 +124,6 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
return n;
}
EXPORT_SYMBOL(__copy_from_user_ll_nocache_nozero);
+--
+2.20.1
+
diff --git a/patches.suse/0007-x86-uaccess-Use-__uaccess_begin_nospec-and-uaccess_t.patch b/patches.kernel.org/4.4.168-054-x86-uaccess-Use-__uaccess_begin_nospec-and-ua.patch
index 6a00b33779..70ae3571f5 100644
--- a/patches.suse/0007-x86-uaccess-Use-__uaccess_begin_nospec-and-uaccess_t.patch
+++ b/patches.kernel.org/4.4.168-054-x86-uaccess-Use-__uaccess_begin_nospec-and-ua.patch
@@ -1,9 +1,12 @@
From: Dan Williams <dan.j.williams@intel.com>
Date: Mon, 29 Jan 2018 17:02:49 -0800
-Subject: x86/uaccess: Use __uaccess_begin_nospec() and uaccess_try_nospec
+Subject: [PATCH] x86/uaccess: Use __uaccess_begin_nospec() and
+ uaccess_try_nospec
+Patch-mainline: 4.4.168
+References: CVE-2017-5753 bnc#1012382 bsc#1068032
Git-commit: 304ec1b050310548db33063e567123fae8fd0301
-Patch-mainline: v4.16-rc1
-References: bsc#1068032 CVE-2017-5753
+
+commit 304ec1b050310548db33063e567123fae8fd0301 upstream.
Quoting Linus:
@@ -21,9 +24,6 @@ limit check is far away from the user pointer de-reference. In those cases
a barrier_nospec() prevents speculation with a potential pointer to
privileged memory. uaccess_try_nospec covers get_user_try.
-[js] use __uaccess_begin_nospec in all old copy_from_user (there are
- more in 4.4)
-
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Suggested-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
@@ -35,14 +35,22 @@ Cc: gregkh@linuxfoundation.org
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: alan@linux.intel.com
Link: https://lkml.kernel.org/r/151727416953.33451.10508284228526170604.stgit@dwillia2-desk3.amr.corp.intel.com
+[bwh: Backported to 4.4:
+ - Convert several more functions to use __uaccess_begin_nospec(), that
+ are just wrappers in mainline
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- arch/x86/include/asm/uaccess.h | 6 +++---
- arch/x86/include/asm/uaccess_32.h | 18 +++++++++---------
- arch/x86/include/asm/uaccess_64.h | 20 ++++++++++----------
- arch/x86/lib/usercopy_32.c | 8 ++++----
- 4 files changed, 26 insertions(+), 26 deletions(-)
+ arch/x86/include/asm/uaccess.h | 6 +++---
+ arch/x86/include/asm/uaccess_32.h | 26 +++++++++++++-------------
+ arch/x86/include/asm/uaccess_64.h | 20 ++++++++++----------
+ arch/x86/lib/usercopy_32.c | 10 +++++-----
+ 4 files changed, 31 insertions(+), 31 deletions(-)
+diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
+index 4b50bc52ea3e..6f8eadf0681f 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -436,7 +436,7 @@ do { \
@@ -54,7 +62,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \
__uaccess_end(); \
(x) = (__force __typeof__(*(ptr)))__gu_val; \
-@@ -546,7 +546,7 @@ struct __large_struct { unsigned long bu
+@@ -546,7 +546,7 @@ struct __large_struct { unsigned long buf[100]; };
* get_user_ex(...);
* } get_user_catch(err)
*/
@@ -72,9 +80,41 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
switch (size) { \
case 1: \
{ \
+diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h
+index 3fe0eac59462..f575ee3aea5c 100644
--- a/arch/x86/include/asm/uaccess_32.h
+++ b/arch/x86/include/asm/uaccess_32.h
-@@ -111,17 +111,17 @@ __copy_from_user_inatomic(void *to, cons
+@@ -48,25 +48,25 @@ __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n)
+
+ switch (n) {
+ case 1:
+- __uaccess_begin();
++ __uaccess_begin_nospec();
+ __put_user_size(*(u8 *)from, (u8 __user *)to,
+ 1, ret, 1);
+ __uaccess_end();
+ return ret;
+ case 2:
+- __uaccess_begin();
++ __uaccess_begin_nospec();
+ __put_user_size(*(u16 *)from, (u16 __user *)to,
+ 2, ret, 2);
+ __uaccess_end();
+ return ret;
+ case 4:
+- __uaccess_begin();
++ __uaccess_begin_nospec();
+ __put_user_size(*(u32 *)from, (u32 __user *)to,
+ 4, ret, 4);
+ __uaccess_end();
+ return ret;
+ case 8:
+- __uaccess_begin();
++ __uaccess_begin_nospec();
+ __put_user_size(*(u64 *)from, (u64 __user *)to,
+ 8, ret, 8);
+ __uaccess_end();
+@@ -111,17 +111,17 @@ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n)
switch (n) {
case 1:
@@ -95,7 +135,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_size(*(u32 *)to, from, 4, ret, 4);
__uaccess_end();
return ret;
-@@ -162,17 +162,17 @@ __copy_from_user(void *to, const void __
+@@ -162,17 +162,17 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
switch (n) {
case 1:
@@ -116,7 +156,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_size(*(u32 *)to, from, 4, ret, 4);
__uaccess_end();
return ret;
-@@ -190,17 +190,17 @@ static __always_inline unsigned long __c
+@@ -190,17 +190,17 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to,
switch (n) {
case 1:
@@ -137,9 +177,11 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_size(*(u32 *)to, from, 4, ret, 4);
__uaccess_end();
return ret;
+diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
+index 307698688fa1..dc2d00e7ced3 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
-@@ -57,31 +57,31 @@ int __copy_from_user_nocheck(void *dst,
+@@ -57,31 +57,31 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size)
return copy_user_generic(dst, (__force void *)src, size);
switch (size) {
case 1:
@@ -176,7 +218,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_asm(*(u64 *)dst, (u64 __user *)src,
ret, "q", "", "=r", 10);
if (likely(!ret))
-@@ -91,7 +91,7 @@ int __copy_from_user_nocheck(void *dst,
+@@ -91,7 +91,7 @@ int __copy_from_user_nocheck(void *dst, const void __user *src, unsigned size)
__uaccess_end();
return ret;
case 16:
@@ -185,7 +227,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_asm(*(u64 *)dst, (u64 __user *)src,
ret, "q", "", "=r", 16);
if (likely(!ret))
-@@ -190,7 +190,7 @@ int __copy_in_user(void __user *dst, con
+@@ -190,7 +190,7 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
switch (size) {
case 1: {
u8 tmp;
@@ -194,7 +236,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_asm(tmp, (u8 __user *)src,
ret, "b", "b", "=q", 1);
if (likely(!ret))
-@@ -201,7 +201,7 @@ int __copy_in_user(void __user *dst, con
+@@ -201,7 +201,7 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
}
case 2: {
u16 tmp;
@@ -203,7 +245,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_asm(tmp, (u16 __user *)src,
ret, "w", "w", "=r", 2);
if (likely(!ret))
-@@ -213,7 +213,7 @@ int __copy_in_user(void __user *dst, con
+@@ -213,7 +213,7 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
case 4: {
u32 tmp;
@@ -212,7 +254,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_asm(tmp, (u32 __user *)src,
ret, "l", "k", "=r", 4);
if (likely(!ret))
-@@ -224,7 +224,7 @@ int __copy_in_user(void __user *dst, con
+@@ -224,7 +224,7 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
}
case 8: {
u64 tmp;
@@ -221,8 +263,19 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
__get_user_asm(tmp, (u64 __user *)src,
ret, "q", "", "=r", 8);
if (likely(!ret))
+diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c
+index 5755942f5eb2..0a6fcae404f8 100644
--- a/arch/x86/lib/usercopy_32.c
+++ b/arch/x86/lib/usercopy_32.c
+@@ -570,7 +570,7 @@ do { \
+ unsigned long __copy_to_user_ll(void __user *to, const void *from,
+ unsigned long n)
+ {
+- __uaccess_begin();
++ __uaccess_begin_nospec();
+ if (movsl_is_ok(to, from, n))
+ __copy_user(to, from, n);
+ else
@@ -583,7 +583,7 @@ EXPORT_SYMBOL(__copy_to_user_ll);
unsigned long __copy_from_user_ll(void *to, const void __user *from,
unsigned long n)
@@ -241,7 +294,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
if (movsl_is_ok(to, from, n))
__copy_user(to, from, n);
else
-@@ -610,7 +610,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero
+@@ -610,7 +610,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nozero);
unsigned long __copy_from_user_ll_nocache(void *to, const void __user *from,
unsigned long n)
{
@@ -250,7 +303,7 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
#ifdef CONFIG_X86_INTEL_USERCOPY
if (n > 64 && cpu_has_xmm2)
n = __copy_user_zeroing_intel_nocache(to, from, n);
-@@ -627,7 +627,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocach
+@@ -627,7 +627,7 @@ EXPORT_SYMBOL(__copy_from_user_ll_nocache);
unsigned long __copy_from_user_ll_nocache_nozero(void *to, const void __user *from,
unsigned long n)
{
@@ -259,3 +312,6 @@ Signed-off-by: Jiri Slaby <jslaby@suse.cz>
#ifdef CONFIG_X86_INTEL_USERCOPY
if (n > 64 && cpu_has_xmm2)
n = __copy_user_intel_nocache(to, from, n);
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-055-x86-bugs-KVM-Support-the-combination-of-guest.patch b/patches.kernel.org/4.4.168-055-x86-bugs-KVM-Support-the-combination-of-guest.patch
new file mode 100644
index 0000000000..df7f230fc8
--- /dev/null
+++ b/patches.kernel.org/4.4.168-055-x86-bugs-KVM-Support-the-combination-of-guest.patch
@@ -0,0 +1,89 @@
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Wed, 25 Apr 2018 22:04:19 -0400
+Subject: [PATCH] x86/bugs, KVM: Support the combination of guest and host IBRS
+Patch-mainline: 4.4.168
+References: CVE-2018-3639 bnc#1012382 bsc#1087082
+Git-commit: 5cf687548705412da47c9cec342fd952d71ed3d5
+
+commit 5cf687548705412da47c9cec342fd952d71ed3d5 upstream.
+
+A guest may modify the SPEC_CTRL MSR from the value used by the
+kernel. Since the kernel doesn't use IBRS, this means a value of zero is
+what is needed in the host.
+
+But the 336996-Speculative-Execution-Side-Channel-Mitigations.pdf refers to
+the other bits as reserved so the kernel should respect the boot time
+SPEC_CTRL value and use that.
+
+This allows to deal with future extensions to the SPEC_CTRL interface if
+any at all.
+
+Note: This uses wrmsrl() instead of native_wrmsl(). I does not make any
+difference as paravirt will over-write the callq *0xfff.. with the wrmsrl
+assembler code.
+
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Ingo Molnar <mingo@kernel.org>
+[bwh: Backported to 4.4: This was partly applied before; apply just the
+ missing bits]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/svm.c | 6 ++----
+ arch/x86/kvm/vmx.c | 6 ++----
+ 2 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index e1f20e0d62c2..f86303592768 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -3904,8 +3904,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ * is no need to worry about the conditional branch over the wrmsr
+ * being speculatively taken.
+ */
+- if (svm->spec_ctrl)
+- native_wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl);
++ x86_spec_ctrl_set_guest(svm->spec_ctrl);
+
+ asm volatile (
+ "push %%" _ASM_BP "; \n\t"
+@@ -4017,8 +4016,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
+ svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
+
+- if (svm->spec_ctrl)
+- native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
++ x86_spec_ctrl_restore_host(svm->spec_ctrl);
+
+ /* Eliminate branch target predictions from guest mode */
+ vmexit_fill_RSB();
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index f7b5c009859e..0fffd247037b 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -8658,8 +8658,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ * is no need to worry about the conditional branch over the wrmsr
+ * being speculatively taken.
+ */
+- if (vmx->spec_ctrl)
+- native_wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl);
++ x86_spec_ctrl_set_guest(vmx->spec_ctrl);
+
+ vmx->__launched = vmx->loaded_vmcs->launched;
+ asm(
+@@ -8797,8 +8796,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
+ vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
+
+- if (vmx->spec_ctrl)
+- native_wrmsrl(MSR_IA32_SPEC_CTRL, 0);
++ x86_spec_ctrl_restore_host(vmx->spec_ctrl);
+
+ /* Eliminate branch target predictions from guest mode */
+ vmexit_fill_RSB();
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-056-x86-KVM-VMX-Expose-SPEC_CTRL-Bit-2-to-the-gue.patch b/patches.kernel.org/4.4.168-056-x86-KVM-VMX-Expose-SPEC_CTRL-Bit-2-to-the-gue.patch
new file mode 100644
index 0000000000..13edc97481
--- /dev/null
+++ b/patches.kernel.org/4.4.168-056-x86-KVM-VMX-Expose-SPEC_CTRL-Bit-2-to-the-gue.patch
@@ -0,0 +1,126 @@
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Wed, 25 Apr 2018 22:04:25 -0400
+Subject: [PATCH] x86/KVM/VMX: Expose SPEC_CTRL Bit(2) to the guest
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Patch-mainline: 4.4.168
+References: CVE-2018-3639 bnc#1012382 bsc#1087082
+Git-commit: da39556f66f5cfe8f9c989206974f1cb16ca5d7c
+
+commit da39556f66f5cfe8f9c989206974f1cb16ca5d7c upstream.
+
+Expose the CPUID.7.EDX[31] bit to the guest, and also guard against various
+combinations of SPEC_CTRL MSR values.
+
+The handling of the MSR (to take into account the host value of SPEC_CTRL
+Bit(2)) is taken care of in patch:
+
+ KVM/SVM/VMX/x86/spectre_v2: Support the combination of guest and host IBRS
+
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Ingo Molnar <mingo@kernel.org>
+
+[dwmw2: Handle 4.9 guest CPUID differences, rename
+ guest_cpu_has_ibrs() → guest_cpu_has_spec_ctrl()]
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4: Update feature bit name]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/cpuid.c | 2 +-
+ arch/x86/kvm/cpuid.h | 4 ++--
+ arch/x86/kvm/svm.c | 4 ++--
+ arch/x86/kvm/vmx.c | 6 +++---
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index 0ab72a8387d4..6b20e0a823da 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -364,7 +364,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+
+ /* cpuid 7.0.edx*/
+ const u32 kvm_cpuid_7_0_edx_x86_features =
+- F(SPEC_CTRL) | F(ARCH_CAPABILITIES);
++ F(SPEC_CTRL) | F(SPEC_CTRL_SSBD) | F(ARCH_CAPABILITIES);
+
+ /* all calls to cpuid_count() should be made on the same cpu */
+ get_cpu();
+diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
+index 7f74d7e18a01..31ff5d2d0536 100644
+--- a/arch/x86/kvm/cpuid.h
++++ b/arch/x86/kvm/cpuid.h
+@@ -170,7 +170,7 @@ static inline bool guest_cpuid_has_ibpb(struct kvm_vcpu *vcpu)
+ return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
+ }
+
+-static inline bool guest_cpuid_has_ibrs(struct kvm_vcpu *vcpu)
++static inline bool guest_cpuid_has_spec_ctrl(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_cpuid_entry2 *best;
+
+@@ -178,7 +178,7 @@ static inline bool guest_cpuid_has_ibrs(struct kvm_vcpu *vcpu)
+ if (best && (best->ebx & bit(X86_FEATURE_IBRS)))
+ return true;
+ best = kvm_find_cpuid_entry(vcpu, 7, 0);
+- return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
++ return best && (best->edx & (bit(X86_FEATURE_SPEC_CTRL) | bit(X86_FEATURE_SPEC_CTRL_SSBD)));
+ }
+
+ static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index f86303592768..9b3ac8c54a59 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -3090,7 +3090,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ break;
+ case MSR_IA32_SPEC_CTRL:
+ if (!msr_info->host_initiated &&
+- !guest_cpuid_has_ibrs(vcpu))
++ !guest_cpuid_has_spec_ctrl(vcpu))
+ return 1;
+
+ msr_info->data = svm->spec_ctrl;
+@@ -3171,7 +3171,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
+ break;
+ case MSR_IA32_SPEC_CTRL:
+ if (!msr->host_initiated &&
+- !guest_cpuid_has_ibrs(vcpu))
++ !guest_cpuid_has_spec_ctrl(vcpu))
+ return 1;
+
+ /* The STIBP bit doesn't fault even if it's not advertised */
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 0fffd247037b..ea2e36d85569 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -2861,7 +2861,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ break;
+ case MSR_IA32_SPEC_CTRL:
+ if (!msr_info->host_initiated &&
+- !guest_cpuid_has_ibrs(vcpu))
++ !guest_cpuid_has_spec_ctrl(vcpu))
+ return 1;
+
+ msr_info->data = to_vmx(vcpu)->spec_ctrl;
+@@ -2973,11 +2973,11 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+ break;
+ case MSR_IA32_SPEC_CTRL:
+ if (!msr_info->host_initiated &&
+- !guest_cpuid_has_ibrs(vcpu))
++ !guest_cpuid_has_spec_ctrl(vcpu))
+ return 1;
+
+ /* The STIBP bit doesn't fault even if it's not advertised */
+- if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP))
++ if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD))
+ return 1;
+
+ vmx->spec_ctrl = data;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-057-KVM-SVM-Move-spec-control-call-after-restore-.patch b/patches.kernel.org/4.4.168-057-KVM-SVM-Move-spec-control-call-after-restore-.patch
new file mode 100644
index 0000000000..0757b3208d
--- /dev/null
+++ b/patches.kernel.org/4.4.168-057-KVM-SVM-Move-spec-control-call-after-restore-.patch
@@ -0,0 +1,75 @@
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Fri, 11 May 2018 15:21:01 +0200
+Subject: [PATCH] KVM: SVM: Move spec control call after restore of GS
+Patch-mainline: 4.4.168
+References: CVE-2018-3639 bnc#1012382 bsc#1087082
+Git-commit: 15e6c22fd8e5a42c5ed6d487b7c9fe44c2517765
+
+commit 15e6c22fd8e5a42c5ed6d487b7c9fe44c2517765 upstream.
+
+svm_vcpu_run() invokes x86_spec_ctrl_restore_host() after VMEXIT, but
+before the host GS is restored. x86_spec_ctrl_restore_host() uses 'current'
+to determine the host SSBD state of the thread. 'current' is GS based, but
+host GS is not yet restored and the access causes a triple fault.
+
+Move the call after the host GS restore.
+
+Fixes: 885f82bfbc6f x86/process: Allow runtime control of Speculative Store Bypass
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/svm.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index 9b3ac8c54a59..49d5543ebc98 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -3998,6 +3998,18 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ #endif
+ );
+
++ /* Eliminate branch target predictions from guest mode */
++ vmexit_fill_RSB();
++
++#ifdef CONFIG_X86_64
++ wrmsrl(MSR_GS_BASE, svm->host.gs_base);
++#else
++ loadsegment(fs, svm->host.fs);
++#ifndef CONFIG_X86_32_LAZY_GS
++ loadsegment(gs, svm->host.gs);
++#endif
++#endif
++
+ /*
+ * We do not use IBRS in the kernel. If this vCPU has used the
+ * SPEC_CTRL MSR it may have left it on; save the value and
+@@ -4018,18 +4030,6 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+
+ x86_spec_ctrl_restore_host(svm->spec_ctrl);
+
+- /* Eliminate branch target predictions from guest mode */
+- vmexit_fill_RSB();
+-
+-#ifdef CONFIG_X86_64
+- wrmsrl(MSR_GS_BASE, svm->host.gs_base);
+-#else
+- loadsegment(fs, svm->host.fs);
+-#ifndef CONFIG_X86_32_LAZY_GS
+- loadsegment(gs, svm->host.gs);
+-#endif
+-#endif
+-
+ reload_tss(vcpu);
+
+ local_irq_disable();
+--
+2.20.1
+
diff --git a/patches.arch/39-x86-bugs-kvm-extend-speculation-control-for-virt_spec_ctrl.patch b/patches.kernel.org/4.4.168-058-x86-bugs-KVM-Extend-speculation-control-for-V.patch
index 84440dd657..7fda3c5ecd 100644
--- a/patches.arch/39-x86-bugs-kvm-extend-speculation-control-for-virt_spec_ctrl.patch
+++ b/patches.kernel.org/4.4.168-058-x86-bugs-KVM-Extend-speculation-control-for-V.patch
@@ -1,9 +1,11 @@
From: Thomas Gleixner <tglx@linutronix.de>
Date: Wed, 9 May 2018 23:01:01 +0200
-Subject: x86/bugs, KVM: Extend speculation control for VIRT_SPEC_CTRL
-Git-commit: ccbcd2674472a978b48c91c1fbfb66c0ff959f24 (partial)
-Patch-mainline: v4.17-rc7
-References: bsc#1087082 CVE-2018-3639
+Subject: [PATCH] x86/bugs, KVM: Extend speculation control for VIRT_SPEC_CTRL
+Patch-mainline: 4.4.168
+References: CVE-2018-3639 bnc#1012382 bsc#1087082
+Git-commit: ccbcd2674472a978b48c91c1fbfb66c0ff959f24
+
+commit ccbcd2674472a978b48c91c1fbfb66c0ff959f24 upstream.
AMD is proposing a VIRT_SPEC_CTRL MSR to handle the Speculative Store
Bypass Disable via MSR_AMD64_LS_CFG so that guests do not have to care
@@ -18,22 +20,27 @@ Hand in 0 from VMX and in SVM add a new virt_spec_ctrl member to the CPU
data structure which is going to be used in later patches for the actual
implementation.
-[js] 4.4.144 brought part of the upstream commit in, omitting the kvm
- part. We do the kvm part here.
-
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-Acked-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4: This was partly applied before; apply just the
+ missing bits]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- arch/x86/kvm/svm.c | 11 +++++++++--
- arch/x86/kvm/vmx.c | 4 ++--
- 2 files changed, 11 insertions(+), 4 deletions(-)
+ arch/x86/kvm/svm.c | 11 +++++++++--
+ arch/x86/kvm/vmx.c | 5 +++--
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index 49d5543ebc98..9abcc08f4e93 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
-@@ -177,6 +177,12 @@ struct vcpu_svm {
- u64 next_rip;
+@@ -149,6 +149,12 @@ struct vcpu_svm {
+ } host;
u64 spec_ctrl;
+ /*
@@ -43,27 +50,27 @@ Acked-by: Borislav Petkov <bp@suse.de>
+ */
+ u64 virt_spec_ctrl;
- u64 host_user_msrs[NR_HOST_SAVE_USER_MSRS];
- struct {
-@@ -1542,6 +1548,7 @@ static void svm_vcpu_reset(struct kvm_vc
- struct vcpu_svm *svm = to_svm(vcpu);
- u32 dummy;
+ u32 *msrpm;
+
+@@ -1146,6 +1152,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
u32 eax = 1;
+
+ svm->spec_ctrl = 0;
+ svm->virt_spec_ctrl = 0;
if (!init_event) {
svm->vcpu.arch.apic_base = APIC_DEFAULT_PHYS_BASE |
-@@ -4832,7 +4839,7 @@ static void svm_vcpu_run(struct kvm_vcpu
-
- local_irq_enable();
-
+@@ -3904,7 +3911,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ * is no need to worry about the conditional branch over the wrmsr
+ * being speculatively taken.
+ */
- x86_spec_ctrl_set_guest(svm->spec_ctrl);
+ x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl);
asm volatile (
"push %%" _ASM_BP "; \n\t"
-@@ -4938,7 +4945,7 @@ static void svm_vcpu_run(struct kvm_vcpu
- if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
+@@ -4028,7 +4035,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
+ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
- x86_spec_ctrl_restore_host(svm->spec_ctrl);
@@ -71,19 +78,24 @@ Acked-by: Borislav Petkov <bp@suse.de>
reload_tss(vcpu);
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index ea2e36d85569..e99994cc1266 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
-@@ -8625,7 +8625,7 @@ static void __noclone vmx_vcpu_run(struc
-
- debugctlmsr = get_debugctlmsr();
-
+@@ -8658,9 +8658,10 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ * is no need to worry about the conditional branch over the wrmsr
+ * being speculatively taken.
+ */
- x86_spec_ctrl_set_guest(vmx->spec_ctrl);
+ x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0);
vmx->__launched = vmx->loaded_vmcs->launched;
++
asm(
-@@ -8745,7 +8745,7 @@ static void __noclone vmx_vcpu_run(struc
- if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL))
+ /* Store host registers */
+ "push %%" _ASM_DX "; push %%" _ASM_BP ";"
+@@ -8796,7 +8797,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+ if (!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))
vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL);
- x86_spec_ctrl_restore_host(vmx->spec_ctrl);
@@ -91,3 +103,6 @@ Acked-by: Borislav Petkov <bp@suse.de>
/* Eliminate branch target predictions from guest mode */
vmexit_fill_RSB();
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-059-x86-speculation-Use-synthetic-bits-for-IBRS-I.patch b/patches.kernel.org/4.4.168-059-x86-speculation-Use-synthetic-bits-for-IBRS-I.patch
new file mode 100644
index 0000000000..4104ebd7ca
--- /dev/null
+++ b/patches.kernel.org/4.4.168-059-x86-speculation-Use-synthetic-bits-for-IBRS-I.patch
@@ -0,0 +1,92 @@
+From: Borislav Petkov <bp@suse.de>
+Date: Wed, 2 May 2018 18:15:14 +0200
+Subject: [PATCH] x86/speculation: Use synthetic bits for IBRS/IBPB/STIBP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: e7c587da125291db39ddf1f49b18e5970adbac17
+
+commit e7c587da125291db39ddf1f49b18e5970adbac17 upstream.
+
+Intel and AMD have different CPUID bits hence for those use synthetic bits
+which get set on the respective vendor's in init_speculation_control(). So
+that debacles like what the commit message of
+
+ c65732e4f721 ("x86/cpu: Restore CPUID_8000_0008_EBX reload")
+
+talks about don't happen anymore.
+
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Tested-by: Jörg Otte <jrg.otte@gmail.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Link: https://lkml.kernel.org/r/20180504161815.GG9257@pd.tnic
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[bwh: Backported to 4.4: This was partly applied before; apply just the
+ missing bits]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/kvm/cpuid.c | 10 +++++-----
+ arch/x86/kvm/cpuid.h | 4 ++--
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index 6b20e0a823da..b0371a77cbc8 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -343,7 +343,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+
+ /* cpuid 0x80000008.ebx */
+ const u32 kvm_cpuid_8000_0008_ebx_x86_features =
+- F(IBPB) | F(IBRS);
++ F(AMD_IBPB) | F(AMD_IBRS);
+
+ /* cpuid 0xC0000001.edx */
+ const u32 kvm_supported_word5_x86_features =
+@@ -596,10 +596,10 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+ entry->eax = g_phys_as | (virt_as << 8);
+ entry->edx = 0;
+ /* IBRS and IBPB aren't necessarily present in hardware cpuid */
+- if (boot_cpu_has(X86_FEATURE_IBPB))
+- entry->ebx |= F(IBPB);
+- if (boot_cpu_has(X86_FEATURE_IBRS))
+- entry->ebx |= F(IBRS);
++ if (boot_cpu_has(X86_FEATURE_AMD_IBPB))
++ entry->ebx |= F(AMD_IBPB);
++ if (boot_cpu_has(X86_FEATURE_AMD_IBRS))
++ entry->ebx |= F(AMD_IBRS);
+ entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
+ cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
+ break;
+diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
+index 31ff5d2d0536..ba8988707e9d 100644
+--- a/arch/x86/kvm/cpuid.h
++++ b/arch/x86/kvm/cpuid.h
+@@ -164,7 +164,7 @@ static inline bool guest_cpuid_has_ibpb(struct kvm_vcpu *vcpu)
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
+- if (best && (best->ebx & bit(X86_FEATURE_IBPB)))
++ if (best && (best->ebx & bit(X86_FEATURE_AMD_IBPB)))
+ return true;
+ best = kvm_find_cpuid_entry(vcpu, 7, 0);
+ return best && (best->edx & bit(X86_FEATURE_SPEC_CTRL));
+@@ -175,7 +175,7 @@ static inline bool guest_cpuid_has_spec_ctrl(struct kvm_vcpu *vcpu)
+ struct kvm_cpuid_entry2 *best;
+
+ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
+- if (best && (best->ebx & bit(X86_FEATURE_IBRS)))
++ if (best && (best->ebx & bit(X86_FEATURE_AMD_IBRS)))
+ return true;
+ best = kvm_find_cpuid_entry(vcpu, 7, 0);
+ return best && (best->edx & (bit(X86_FEATURE_SPEC_CTRL) | bit(X86_FEATURE_SPEC_CTRL_SSBD)));
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-060-KVM-SVM-Implement-VIRT_SPEC_CTRL-support-for-.patch b/patches.kernel.org/4.4.168-060-KVM-SVM-Implement-VIRT_SPEC_CTRL-support-for-.patch
new file mode 100644
index 0000000000..f0ba12e901
--- /dev/null
+++ b/patches.kernel.org/4.4.168-060-KVM-SVM-Implement-VIRT_SPEC_CTRL-support-for-.patch
@@ -0,0 +1,246 @@
+From: Tom Lendacky <thomas.lendacky@amd.com>
+Date: Thu, 10 May 2018 22:06:39 +0200
+Subject: [PATCH] KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD
+Patch-mainline: 4.4.168
+References: CVE-2018-3639 bnc#1012382 bsc#1087082
+Git-commit: bc226f07dcd3c9ef0b7f6236fe356ea4a9cb4769
+
+commit bc226f07dcd3c9ef0b7f6236fe356ea4a9cb4769 upstream.
+
+Expose the new virtualized architectural mechanism, VIRT_SSBD, for using
+speculative store bypass disable (SSBD) under SVM. This will allow guests
+to use SSBD on hardware that uses non-architectural mechanisms for enabling
+SSBD.
+
+[ tglx: Folded the migration fixup from Paolo Bonzini ]
+
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/x86/include/asm/kvm_host.h | 2 +-
+ arch/x86/kernel/cpu/common.c | 3 ++-
+ arch/x86/kvm/cpuid.c | 11 +++++++++--
+ arch/x86/kvm/cpuid.h | 9 +++++++++
+ arch/x86/kvm/svm.c | 21 +++++++++++++++++++--
+ arch/x86/kvm/vmx.c | 18 +++++++++++++++---
+ arch/x86/kvm/x86.c | 13 ++++---------
+ 7 files changed, 59 insertions(+), 18 deletions(-)
+
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index 3a37cdbdfbaa..c048d0d70cc4 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -765,7 +765,7 @@ struct kvm_x86_ops {
+ int (*hardware_setup)(void); /* __init */
+ void (*hardware_unsetup)(void); /* __exit */
+ bool (*cpu_has_accelerated_tpr)(void);
+- bool (*cpu_has_high_real_mode_segbase)(void);
++ bool (*has_emulated_msr)(int index);
+ void (*cpuid_update)(struct kvm_vcpu *vcpu);
+
+ /* Create, but do not attach this VCPU */
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index b12c0287d6cf..e8b46f575306 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -693,7 +693,8 @@ static void init_speculation_control(struct cpuinfo_x86 *c)
+ if (cpu_has(c, X86_FEATURE_INTEL_STIBP))
+ set_cpu_cap(c, X86_FEATURE_STIBP);
+
+- if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD))
++ if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD) ||
++ cpu_has(c, X86_FEATURE_VIRT_SSBD))
+ set_cpu_cap(c, X86_FEATURE_SSBD);
+
+ if (cpu_has(c, X86_FEATURE_AMD_IBRS)) {
+diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
+index b0371a77cbc8..b857bb9f6f23 100644
+--- a/arch/x86/kvm/cpuid.c
++++ b/arch/x86/kvm/cpuid.c
+@@ -343,7 +343,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+
+ /* cpuid 0x80000008.ebx */
+ const u32 kvm_cpuid_8000_0008_ebx_x86_features =
+- F(AMD_IBPB) | F(AMD_IBRS);
++ F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD);
+
+ /* cpuid 0xC0000001.edx */
+ const u32 kvm_supported_word5_x86_features =
+@@ -595,13 +595,20 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
+ g_phys_as = phys_as;
+ entry->eax = g_phys_as | (virt_as << 8);
+ entry->edx = 0;
+- /* IBRS and IBPB aren't necessarily present in hardware cpuid */
++ /*
++ * IBRS, IBPB and VIRT_SSBD aren't necessarily present in
++ * hardware cpuid
++ */
+ if (boot_cpu_has(X86_FEATURE_AMD_IBPB))
+ entry->ebx |= F(AMD_IBPB);
+ if (boot_cpu_has(X86_FEATURE_AMD_IBRS))
+ entry->ebx |= F(AMD_IBRS);
++ if (boot_cpu_has(X86_FEATURE_VIRT_SSBD))
++ entry->ebx |= F(VIRT_SSBD);
+ entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features;
+ cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX);
++ if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD))
++ entry->ebx |= F(VIRT_SSBD);
+ break;
+ }
+ case 0x80000019:
+diff --git a/arch/x86/kvm/cpuid.h b/arch/x86/kvm/cpuid.h
+index ba8988707e9d..72f159f4d456 100644
+--- a/arch/x86/kvm/cpuid.h
++++ b/arch/x86/kvm/cpuid.h
+@@ -189,6 +189,15 @@ static inline bool guest_cpuid_has_arch_capabilities(struct kvm_vcpu *vcpu)
+ return best && (best->edx & bit(X86_FEATURE_ARCH_CAPABILITIES));
+ }
+
++static inline bool guest_cpuid_has_virt_ssbd(struct kvm_vcpu *vcpu)
++{
++ struct kvm_cpuid_entry2 *best;
++
++ best = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
++ return best && (best->ebx & bit(X86_FEATURE_VIRT_SSBD));
++}
++
++
+
+ /*
+ * NRIPS is provided through cpuidfn 0x8000000a.edx bit 3
+diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
+index 9abcc08f4e93..ecdf724da371 100644
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -3102,6 +3102,13 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
+
+ msr_info->data = svm->spec_ctrl;
+ break;
++ case MSR_AMD64_VIRT_SPEC_CTRL:
++ if (!msr_info->host_initiated &&
++ !guest_cpuid_has_virt_ssbd(vcpu))
++ return 1;
++
++ msr_info->data = svm->virt_spec_ctrl;
++ break;
+ case MSR_IA32_UCODE_REV:
+ msr_info->data = 0x01000065;
+ break;
+@@ -3219,6 +3226,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
+ break;
+ set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1);
+ break;
++ case MSR_AMD64_VIRT_SPEC_CTRL:
++ if (!msr->host_initiated &&
++ !guest_cpuid_has_virt_ssbd(vcpu))
++ return 1;
++
++ if (data & ~SPEC_CTRL_SSBD)
++ return 1;
++
++ svm->virt_spec_ctrl = data;
++ break;
+ case MSR_STAR:
+ svm->vmcb->save.star = data;
+ break;
+@@ -4137,7 +4154,7 @@ static bool svm_cpu_has_accelerated_tpr(void)
+ return false;
+ }
+
+-static bool svm_has_high_real_mode_segbase(void)
++static bool svm_has_emulated_msr(int index)
+ {
+ return true;
+ }
+@@ -4421,7 +4438,7 @@ static struct kvm_x86_ops svm_x86_ops = {
+ .hardware_enable = svm_hardware_enable,
+ .hardware_disable = svm_hardware_disable,
+ .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr,
+- .cpu_has_high_real_mode_segbase = svm_has_high_real_mode_segbase,
++ .has_emulated_msr = svm_has_emulated_msr,
+
+ .vcpu_create = svm_create_vcpu,
+ .vcpu_free = svm_free_vcpu,
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index e99994cc1266..e4b5fd72ca24 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -8458,9 +8458,21 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu)
+ local_irq_enable();
+ }
+
+-static bool vmx_has_high_real_mode_segbase(void)
++static bool vmx_has_emulated_msr(int index)
+ {
+- return enable_unrestricted_guest || emulate_invalid_guest_state;
++ switch (index) {
++ case MSR_IA32_SMBASE:
++ /*
++ * We cannot do SMM unless we can run the guest in big
++ * real mode.
++ */
++ return enable_unrestricted_guest || emulate_invalid_guest_state;
++ case MSR_AMD64_VIRT_SPEC_CTRL:
++ /* This is AMD only. */
++ return false;
++ default:
++ return true;
++ }
+ }
+
+ static bool vmx_mpx_supported(void)
+@@ -10952,7 +10964,7 @@ static struct kvm_x86_ops vmx_x86_ops = {
+ .hardware_enable = hardware_enable,
+ .hardware_disable = hardware_disable,
+ .cpu_has_accelerated_tpr = report_flexpriority,
+- .cpu_has_high_real_mode_segbase = vmx_has_high_real_mode_segbase,
++ .has_emulated_msr = vmx_has_emulated_msr,
+
+ .vcpu_create = vmx_create_vcpu,
+ .vcpu_free = vmx_free_vcpu,
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 12a91ea85d3a..aa1a0277a678 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -985,6 +985,7 @@ static u32 emulated_msrs[] = {
+ MSR_IA32_MCG_STATUS,
+ MSR_IA32_MCG_CTL,
+ MSR_IA32_SMBASE,
++ MSR_AMD64_VIRT_SPEC_CTRL,
+ };
+
+ static unsigned num_emulated_msrs;
+@@ -2584,7 +2585,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
+ * fringe case that is not enabled except via specific settings
+ * of the module parameters.
+ */
+- r = kvm_x86_ops->cpu_has_high_real_mode_segbase();
++ r = kvm_x86_ops->has_emulated_msr(MSR_IA32_SMBASE);
+ break;
+ case KVM_CAP_COALESCED_MMIO:
+ r = KVM_COALESCED_MMIO_PAGE_OFFSET;
+@@ -4073,14 +4074,8 @@ static void kvm_init_msr_list(void)
+ num_msrs_to_save = j;
+
+ for (i = j = 0; i < ARRAY_SIZE(emulated_msrs); i++) {
+- switch (emulated_msrs[i]) {
+- case MSR_IA32_SMBASE:
+- if (!kvm_x86_ops->cpu_has_high_real_mode_segbase())
+- continue;
+- break;
+- default:
+- break;
+- }
++ if (!kvm_x86_ops->has_emulated_msr(emulated_msrs[i]))
++ continue;
+
+ if (j < i)
+ emulated_msrs[j] = emulated_msrs[i];
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-061-bpf-support-8-byte-metafield-access.patch b/patches.kernel.org/4.4.168-061-bpf-support-8-byte-metafield-access.patch
new file mode 100644
index 0000000000..01cf21ebe8
--- /dev/null
+++ b/patches.kernel.org/4.4.168-061-bpf-support-8-byte-metafield-access.patch
@@ -0,0 +1,57 @@
+From: Alexei Starovoitov <ast@fb.com>
+Date: Thu, 1 Sep 2016 18:37:21 -0700
+Subject: [PATCH] bpf: support 8-byte metafield access
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: cedaf52693f02372010548c63b2e63228b959099
+
+commit cedaf52693f02372010548c63b2e63228b959099 upstream.
+
+The verifier supported only 4-byte metafields in
+struct __sk_buff and struct xdp_md. The metafields in upcoming
+struct bpf_perf_event are 8-byte to match register width in struct pt_regs.
+Teach verifier to recognize 8-byte metafield access.
+The patch doesn't affect safety of sockets and xdp programs.
+They check for 4-byte only ctx access before these conditions are hit.
+
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ kernel/bpf/verifier.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 35dfa9e9d69e..a937611c2570 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1844,7 +1844,8 @@ static int do_check(struct verifier_env *env)
+ if (err)
+ return err;
+
+- if (BPF_SIZE(insn->code) != BPF_W) {
++ if (BPF_SIZE(insn->code) != BPF_W &&
++ BPF_SIZE(insn->code) != BPF_DW) {
+ insn_idx++;
+ continue;
+ }
+@@ -2220,9 +2221,11 @@ static int convert_ctx_accesses(struct verifier_env *env)
+ for (i = 0; i < insn_cnt; i++, insn++) {
+ u32 cnt;
+
+- if (insn->code == (BPF_LDX | BPF_MEM | BPF_W))
++ if (insn->code == (BPF_LDX | BPF_MEM | BPF_W) ||
++ insn->code == (BPF_LDX | BPF_MEM | BPF_DW))
+ type = BPF_READ;
+- else if (insn->code == (BPF_STX | BPF_MEM | BPF_W))
++ else if (insn->code == (BPF_STX | BPF_MEM | BPF_W) ||
++ insn->code == (BPF_STX | BPF_MEM | BPF_DW))
+ type = BPF_WRITE;
+ else
+ continue;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-062-bpf-verifier-Add-spi-variable-to-check_stack_.patch b/patches.kernel.org/4.4.168-062-bpf-verifier-Add-spi-variable-to-check_stack_.patch
new file mode 100644
index 0000000000..59dc1878f1
--- /dev/null
+++ b/patches.kernel.org/4.4.168-062-bpf-verifier-Add-spi-variable-to-check_stack_.patch
@@ -0,0 +1,53 @@
+From: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Date: Wed, 5 Dec 2018 22:45:15 +0000
+Subject: [PATCH] bpf/verifier: Add spi variable to check_stack_write()
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 168cb9b7b2839e861278f9fde03820aba32c4ee0
+
+Extracted from commit dc503a8ad984 "bpf/verifier: track liveness for
+pruning".
+
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ kernel/bpf/verifier.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index a937611c2570..4756b88c828e 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -572,7 +572,7 @@ static bool is_spillable_regtype(enum bpf_reg_type type)
+ static int check_stack_write(struct verifier_state *state, int off, int size,
+ int value_regno)
+ {
+- int i;
++ int i, spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE;
+ /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0,
+ * so it's aligned access and [off, off + size) are within stack limits
+ */
+@@ -587,15 +587,13 @@ static int check_stack_write(struct verifier_state *state, int off, int size,
+ }
+
+ /* save register state */
+- state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] =
+- state->regs[value_regno];
++ state->spilled_regs[spi] = state->regs[value_regno];
+
+ for (i = 0; i < BPF_REG_SIZE; i++)
+ state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_SPILL;
+ } else {
+ /* regular write of data into stack */
+- state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] =
+- (struct reg_state) {};
++ state->spilled_regs[spi] = (struct reg_state) {};
+
+ for (i = 0; i < size; i++)
+ state->stack_slot_type[MAX_BPF_STACK + off + i] = STACK_MISC;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-063-bpf-verifier-Pass-instruction-index-to-check_.patch b/patches.kernel.org/4.4.168-063-bpf-verifier-Pass-instruction-index-to-check_.patch
new file mode 100644
index 0000000000..32f72a735c
--- /dev/null
+++ b/patches.kernel.org/4.4.168-063-bpf-verifier-Pass-instruction-index-to-check_.patch
@@ -0,0 +1,97 @@
+From: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Date: Wed, 5 Dec 2018 22:41:36 +0000
+Subject: [PATCH] bpf/verifier: Pass instruction index to check_mem_access()
+ and check_xadd()
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 451624d47005aace4e314b488cb70ba3ee5dcce8
+
+Extracted from commit 31fd85816dbe "bpf: permits narrower load from
+bpf program context fields".
+
+Cc: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ kernel/bpf/verifier.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 4756b88c828e..060cb8cba56b 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -694,7 +694,7 @@ static bool is_ctx_reg(struct verifier_env *env, int regno)
+ * if t==write && value_regno==-1, some unknown value is stored into memory
+ * if t==read && value_regno==-1, don't care what we read from memory
+ */
+-static int check_mem_access(struct verifier_env *env, u32 regno, int off,
++static int check_mem_access(struct verifier_env *env, int insn_idx, u32 regno, int off,
+ int bpf_size, enum bpf_access_type t,
+ int value_regno)
+ {
+@@ -758,7 +758,7 @@ static int check_mem_access(struct verifier_env *env, u32 regno, int off,
+ return err;
+ }
+
+-static int check_xadd(struct verifier_env *env, struct bpf_insn *insn)
++static int check_xadd(struct verifier_env *env, int insn_idx, struct bpf_insn *insn)
+ {
+ struct reg_state *regs = env->cur_state.regs;
+ int err;
+@@ -791,13 +791,13 @@ static int check_xadd(struct verifier_env *env, struct bpf_insn *insn)
+ }
+
+ /* check whether atomic_add can read the memory */
+- err = check_mem_access(env, insn->dst_reg, insn->off,
++ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
+ BPF_SIZE(insn->code), BPF_READ, -1);
+ if (err)
+ return err;
+
+ /* check whether atomic_add can write into the same memory */
+- return check_mem_access(env, insn->dst_reg, insn->off,
++ return check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
+ BPF_SIZE(insn->code), BPF_WRITE, -1);
+ }
+
+@@ -1836,7 +1836,7 @@ static int do_check(struct verifier_env *env)
+ /* check that memory (src_reg + off) is readable,
+ * the state of dst_reg will be updated by this func
+ */
+- err = check_mem_access(env, insn->src_reg, insn->off,
++ err = check_mem_access(env, insn_idx, insn->src_reg, insn->off,
+ BPF_SIZE(insn->code), BPF_READ,
+ insn->dst_reg);
+ if (err)
+@@ -1875,7 +1875,7 @@ static int do_check(struct verifier_env *env)
+ enum bpf_reg_type *prev_dst_type, dst_reg_type;
+
+ if (BPF_MODE(insn->code) == BPF_XADD) {
+- err = check_xadd(env, insn);
++ err = check_xadd(env, insn_idx, insn);
+ if (err)
+ return err;
+ insn_idx++;
+@@ -1894,7 +1894,7 @@ static int do_check(struct verifier_env *env)
+ dst_reg_type = regs[insn->dst_reg].type;
+
+ /* check that memory (dst_reg + off) is writeable */
+- err = check_mem_access(env, insn->dst_reg, insn->off,
++ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
+ BPF_SIZE(insn->code), BPF_WRITE,
+ insn->src_reg);
+ if (err)
+@@ -1929,7 +1929,7 @@ static int do_check(struct verifier_env *env)
+ }
+
+ /* check that memory (dst_reg + off) is writeable */
+- err = check_mem_access(env, insn->dst_reg, insn->off,
++ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
+ BPF_SIZE(insn->code), BPF_WRITE,
+ -1);
+ if (err)
+--
+2.20.1
+
diff --git a/patches.suse/bpf-prevent-memory-disambiguation-attack.patch b/patches.kernel.org/4.4.168-064-bpf-Prevent-memory-disambiguation-attack.patch
index 307e64f341..e74f6aa0a7 100644
--- a/patches.suse/bpf-prevent-memory-disambiguation-attack.patch
+++ b/patches.kernel.org/4.4.168-064-bpf-Prevent-memory-disambiguation-attack.patch
@@ -1,10 +1,12 @@
From: Alexei Starovoitov <ast@kernel.org>
Date: Tue, 15 May 2018 09:27:05 -0700
-Subject: [PATCH] bpf: prevent memory disambiguation attack
-References: bsc#1087082 CVE-2018-3639
-Patch-mainline: v4.17-rc7
+Subject: [PATCH] bpf: Prevent memory disambiguation attack
+Patch-mainline: 4.4.168
+References: CVE-2018-3639 bnc#1012382 bsc#1087082
Git-commit: af86ca4e3088fe5eacf2f7e58c01fa68ca067672
+commit af86ca4e3088fe5eacf2f7e58c01fa68ca067672 upstream.
+
Detect code patterns where malicious 'speculative store bypass' can be used
and sanitize such patterns.
@@ -26,16 +28,26 @@ Above code after x86 JIT becomes:
ff: mov 0x0(%rbx),%rdi
103: movzbq 0x0(%rdi),%rsi
-[jkosina@suse.cz: adjustments needed for 4.4 port (insn_idx passing mostly)]
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+[bwh: Backported to 4.4:
+ - Add verifier_env parameter to check_stack_write()
+ - Look up stack slot_types with state->stack_slot_type[] rather than
+ state->stack[].slot_type[]
+ - Drop bpf_verifier_env argument to verbose()
+ - Adjust filename, context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- kernel/bpf/verifier.c | 79 ++++++++++++++++++++++++++++++++++++++++++--------
- 1 file changed, 67 insertions(+), 12 deletions(-)
+ kernel/bpf/verifier.c | 63 ++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 59 insertions(+), 4 deletions(-)
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 060cb8cba56b..c43ca9857479 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
-@@ -192,6 +192,7 @@ struct bpf_insn_aux_data {
+@@ -191,6 +191,7 @@ struct bpf_insn_aux_data {
enum bpf_reg_type ptr_type; /* pointer type for load/store insns */
struct bpf_map *map_ptr; /* pointer for call insn into lookup_elem */
};
@@ -43,24 +55,21 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
bool seen; /* this insn was processed by the verifier */
};
-@@ -585,10 +586,12 @@ static bool is_spillable_regtype(enum bp
+@@ -569,8 +570,9 @@ static bool is_spillable_regtype(enum bpf_reg_type type)
/* check_stack_read/write functions track spill/fill of registers,
* stack boundary and alignment are checked in check_mem_access()
*/
-static int check_stack_write(struct verifier_state *state, int off, int size,
- int value_regno)
+static int check_stack_write(struct verifier_env *env,
-+ struct verifier_state *state, int off, int size,
-+ int value_regno, int insn_idx)
++ struct verifier_state *state, int off,
++ int size, int value_regno, int insn_idx)
{
- int i;
-+ int slot = -off - 1, spi = slot / BPF_REG_SIZE;
+ int i, spi = (MAX_BPF_STACK + off) / BPF_REG_SIZE;
/* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0,
- * so it's aligned access and [off, off + size) are within stack limits
- */
-@@ -606,8 +609,32 @@ static int check_stack_write(struct veri
- state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] =
- state->regs[value_regno];
+@@ -589,8 +591,32 @@ static int check_stack_write(struct verifier_state *state, int off, int size,
+ /* save register state */
+ state->spilled_regs[spi] = state->regs[value_regno];
- for (i = 0; i < BPF_REG_SIZE; i++)
+ for (i = 0; i < BPF_REG_SIZE; i++) {
@@ -91,87 +100,18 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+ }
} else {
/* regular write of data into stack */
- state->spilled_regs[(MAX_BPF_STACK + off) / BPF_REG_SIZE] =
-@@ -712,7 +739,7 @@ static bool is_ctx_reg(struct verifier_e
- * if t==write && value_regno==-1, some unknown value is stored into memory
- * if t==read && value_regno==-1, don't care what we read from memory
- */
--static int check_mem_access(struct verifier_env *env, u32 regno, int off,
-+static int check_mem_access(struct verifier_env *env, int insn_idx, u32 regno, int off,
- int bpf_size, enum bpf_access_type t,
- int value_regno)
- {
-@@ -764,7 +791,7 @@ static int check_mem_access(struct verif
+ state->spilled_regs[spi] = (struct reg_state) {};
+@@ -746,7 +772,8 @@ static int check_mem_access(struct verifier_env *env, int insn_idx, u32 regno, i
verbose("attempt to corrupt spilled pointer on stack\n");
return -EACCES;
}
- err = check_stack_write(state, off, size, value_regno);
-+ err = check_stack_write(env, state, off, size, value_regno, insn_idx);
++ err = check_stack_write(env, state, off, size,
++ value_regno, insn_idx);
} else {
err = check_stack_read(state, off, size, value_regno);
}
-@@ -776,7 +803,7 @@ static int check_mem_access(struct verif
- return err;
- }
-
--static int check_xadd(struct verifier_env *env, struct bpf_insn *insn)
-+static int check_xadd(struct verifier_env *env, int insn_idx, struct bpf_insn *insn)
- {
- struct reg_state *regs = env->cur_state.regs;
- int err;
-@@ -809,13 +836,13 @@ static int check_xadd(struct verifier_en
- }
-
- /* check whether atomic_add can read the memory */
-- err = check_mem_access(env, insn->dst_reg, insn->off,
-+ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
- BPF_SIZE(insn->code), BPF_READ, -1);
- if (err)
- return err;
-
- /* check whether atomic_add can write into the same memory */
-- return check_mem_access(env, insn->dst_reg, insn->off,
-+ return check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
- BPF_SIZE(insn->code), BPF_WRITE, -1);
- }
-
-@@ -1870,7 +1897,7 @@ static int do_check(struct verifier_env
- /* check that memory (src_reg + off) is readable,
- * the state of dst_reg will be updated by this func
- */
-- err = check_mem_access(env, insn->src_reg, insn->off,
-+ err = check_mem_access(env, insn_idx, insn->src_reg, insn->off,
- BPF_SIZE(insn->code), BPF_READ,
- insn->dst_reg);
- if (err)
-@@ -1908,7 +1935,7 @@ static int do_check(struct verifier_env
- enum bpf_reg_type *prev_dst_type, dst_reg_type;
-
- if (BPF_MODE(insn->code) == BPF_XADD) {
-- err = check_xadd(env, insn);
-+ err = check_xadd(env, insn_idx, insn);
- if (err)
- return err;
- insn_idx++;
-@@ -1927,7 +1954,7 @@ static int do_check(struct verifier_env
- dst_reg_type = regs[insn->dst_reg].type;
-
- /* check that memory (dst_reg + off) is writeable */
-- err = check_mem_access(env, insn->dst_reg, insn->off,
-+ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
- BPF_SIZE(insn->code), BPF_WRITE,
- insn->src_reg);
- if (err)
-@@ -1962,7 +1989,7 @@ static int do_check(struct verifier_env
- }
-
- /* check that memory (dst_reg + off) is writeable */
-- err = check_mem_access(env, insn->dst_reg, insn->off,
-+ err = check_mem_access(env, insn_idx, insn->dst_reg, insn->off,
- BPF_SIZE(insn->code), BPF_WRITE,
- -1);
- if (err)
-@@ -2259,6 +2286,34 @@ static int convert_ctx_accesses(struct v
+@@ -2228,6 +2255,34 @@ static int convert_ctx_accesses(struct verifier_env *env)
else
continue;
@@ -206,3 +146,6 @@ Signed-off-by: Jiri Kosina <jkosina@suse.cz>
if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX)
continue;
+--
+2.20.1
+
diff --git a/patches.drivers/wil6210-missing-length-check-in-wmi_set_ie b/patches.kernel.org/4.4.168-065-wil6210-missing-length-check-in-wmi_set_ie.patch
index 50222ce66a..639a9c42d0 100644
--- a/patches.drivers/wil6210-missing-length-check-in-wmi_set_ie
+++ b/patches.kernel.org/4.4.168-065-wil6210-missing-length-check-in-wmi_set_ie.patch
@@ -1,10 +1,11 @@
-From b5a8ffcae4103a9d823ea3aa3a761f65779fbe2a Mon Sep 17 00:00:00 2001
From: Lior David <qca_liord@qca.qualcomm.com>
Date: Tue, 14 Nov 2017 15:25:39 +0200
Subject: [PATCH] wil6210: missing length check in wmi_set_ie
+Patch-mainline: 4.4.168
+References: CVE-2018-5848 bnc#1012382 bsc#1097356
Git-commit: b5a8ffcae4103a9d823ea3aa3a761f65779fbe2a
-Patch-mainline: v4.16-rc1
-References: CVE-2018-5848,bsc#1097356
+
+commit b5a8ffcae4103a9d823ea3aa3a761f65779fbe2a upstream.
Add a length check in wmi_set_ie to detect unsigned integer
overflow.
@@ -12,15 +13,18 @@ overflow.
Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-Acked-by: Takashi Iwai <tiwai@suse.de>
-
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- drivers/net/wireless/ath/wil6210/wmi.c | 8 +++++++-
+ drivers/net/wireless/ath/wil6210/wmi.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
+diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
+index 6ed26baca0e5..7af8479acb98 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
-@@ -1035,8 +1035,14 @@ int wmi_set_ie(struct wil6210_priv *wil,
+@@ -1035,8 +1035,14 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
};
int rc;
u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len;
@@ -36,3 +40,6 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
if (!cmd) {
rc = -ENOMEM;
goto out;
+--
+2.20.1
+
diff --git a/patches.fixes/posix-timers-Sanitize-overrun-handling.patch b/patches.kernel.org/4.4.168-066-posix-timers-Sanitize-overrun-handling.patch
index f415eb2193..e3acfd5588 100644
--- a/patches.fixes/posix-timers-Sanitize-overrun-handling.patch
+++ b/patches.kernel.org/4.4.168-066-posix-timers-Sanitize-overrun-handling.patch
@@ -1,10 +1,11 @@
-From 78c9c4dfbf8c04883941445a195276bb4bb92c76 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
-Date: Tue, 26 Jun 2018 15:21:32 +0200
+Date: Thu, 1 Nov 2018 13:02:38 -0700
Subject: [PATCH] posix-timers: Sanitize overrun handling
+Patch-mainline: 4.4.168
+References: CVE-2018-12896 bnc#1012382 bsc#1099922
Git-commit: 78c9c4dfbf8c04883941445a195276bb4bb92c76
-Patch-mainline: v4.19-rc1
-References: CVE-2018-12896,bsc#1099922
+
+commit 78c9c4dfbf8c04883941445a195276bb4bb92c76 upstream.
The posix timer overrun handling is broken because the forwarding functions
can return a huge number of overruns which does not fit in an int. As a
@@ -26,14 +27,21 @@ Acked-by: John Stultz <john.stultz@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Michael Kerrisk <mtk.manpages@gmail.com>
Link: https://lkml.kernel.org/r/20180626132705.018623573@linutronix.de
-Acked-by: Takashi Iwai <tiwai@suse.de>
-
+[florian: Make patch apply to v4.9.135]
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- include/linux/posix-timers.h | 4 ++--
- kernel/time/posix-cpu-timers.c | 8 ++++----
- kernel/time/posix-timers.c | 31 ++++++++++++++++++++-----------
- 3 files changed, 26 insertions(+), 17 deletions(-)
+ include/linux/posix-timers.h | 4 ++--
+ kernel/time/posix-cpu-timers.c | 2 +-
+ kernel/time/posix-timers.c | 29 +++++++++++++++++++----------
+ 3 files changed, 22 insertions(+), 13 deletions(-)
+diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
+index 907f3fd191ac..3e28a1a8d823 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -65,8 +65,8 @@ struct k_itimer {
@@ -47,9 +55,11 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
int it_requeue_pending; /* waiting to requeue this timer */
#define REQUEUE_PENDING 1
int it_sigev_notify; /* notify word of sigevent struct */
+diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
+index 80016b329d94..8fc68e60c795 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
-@@ -103,7 +103,7 @@ static void bump_cpu_timer(struct k_itim
+@@ -103,7 +103,7 @@ static void bump_cpu_timer(struct k_itimer *timer,
continue;
timer->it.cpu.expires += incr;
@@ -58,36 +68,11 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
delta -= incr;
}
}
-@@ -744,7 +744,7 @@ static int posix_cpu_timer_set(struct k_
- timer->it_requeue_pending = (timer->it_requeue_pending + 2) &
- ~REQUEUE_PENDING;
- timer->it_overrun_last = 0;
-- timer->it_overrun = -1;
-+ timer->it_overrun = -1LL;
-
- if (new_expires != 0 && !(val < new_expires)) {
- /*
-@@ -1100,7 +1100,7 @@ void posix_cpu_timer_schedule(struct k_i
- posix_cpu_timer_kick_nohz();
- out:
- timer->it_overrun_last = timer->it_overrun;
-- timer->it_overrun = -1;
-+ timer->it_overrun = -1LL;
- ++timer->it_requeue_pending;
- }
-
-@@ -1305,7 +1305,7 @@ static int do_cpu_nanosleep(const clocki
- memset(&timer, 0, sizeof timer);
- spin_lock_init(&timer.it_lock);
- timer.it_clock = which_clock;
-- timer.it_overrun = -1;
-+ timer.it_overrun = -1LL;
- error = posix_cpu_timer_create(&timer);
- timer.it_process = current;
- if (!error) {
+diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
+index fc7c37ad90a0..0e6ed2e7d066 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
-@@ -356,6 +356,17 @@ static __init int init_posix_timers(void
+@@ -355,6 +355,17 @@ static __init int init_posix_timers(void)
__initcall(init_posix_timers);
@@ -105,7 +90,7 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
static void schedule_next_timer(struct k_itimer *timr)
{
struct hrtimer *timer = &timr->it.real.timer;
-@@ -363,12 +374,11 @@ static void schedule_next_timer(struct k
+@@ -362,12 +373,11 @@ static void schedule_next_timer(struct k_itimer *timr)
if (timr->it.real.interval.tv64 == 0)
return;
@@ -121,7 +106,7 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
++timr->it_requeue_pending;
hrtimer_restart(timer);
}
-@@ -397,7 +407,7 @@ void do_schedule_next_timer(struct sigin
+@@ -396,7 +406,7 @@ void do_schedule_next_timer(struct siginfo *info)
else
schedule_next_timer(timr);
@@ -130,19 +115,17 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
}
if (timr)
-@@ -492,9 +502,8 @@ static enum hrtimer_restart posix_timer_
+@@ -491,8 +501,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer)
now = ktime_add(now, kj);
}
#endif
- timr->it_overrun += (unsigned int)
- hrtimer_forward(timer, now,
-- timr->it.real.interval);
+ timr->it_overrun += hrtimer_forward(timer, now,
-+ timr->it.real.interval);
+ timr->it.real.interval);
ret = HRTIMER_RESTART;
++timr->it_requeue_pending;
- }
-@@ -643,7 +652,7 @@ SYSCALL_DEFINE3(timer_create, const cloc
+@@ -633,7 +642,7 @@ SYSCALL_DEFINE3(timer_create, const clockid_t, which_clock,
it_id_set = IT_ID_SET;
new_timer->it_id = (timer_t) new_timer_id;
new_timer->it_clock = which_clock;
@@ -151,7 +134,7 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
if (timer_event_spec) {
if (copy_from_user(&event, timer_event_spec, sizeof (event))) {
-@@ -772,7 +781,7 @@ common_timer_get(struct k_itimer *timr,
+@@ -762,7 +771,7 @@ common_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
*/
if (iv.tv64 && (timr->it_requeue_pending & REQUEUE_PENDING ||
timr->it_sigev_notify == SIGEV_NONE))
@@ -160,7 +143,7 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
remaining = __hrtimer_expires_remaining_adjusted(timer, now);
/* Return 0 only, when the timer is expired and not pending */
-@@ -834,7 +843,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_
+@@ -824,7 +833,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_t, timer_id)
if (!timr)
return -EINVAL;
@@ -169,3 +152,6 @@ Acked-by: Takashi Iwai <tiwai@suse.de>
unlock_timer(timr, flags);
return overrun;
+--
+2.20.1
+
diff --git a/patches.fixes/mm-hugetlb.c-don-t-call-region_abort-if-region_chg-f.patch b/patches.kernel.org/4.4.168-067-mm-hugetlb.c-don-t-call-region_abort-if-regio.patch
index 722a824796..cb75a10fec 100644
--- a/patches.fixes/mm-hugetlb.c-don-t-call-region_abort-if-region_chg-f.patch
+++ b/patches.kernel.org/4.4.168-067-mm-hugetlb.c-don-t-call-region_abort-if-regio.patch
@@ -1,10 +1,11 @@
-From ff8c0c53c47530ffea82c22a0a6df6332b56c957 Mon Sep 17 00:00:00 2001
From: Mike Kravetz <mike.kravetz@oracle.com>
Date: Fri, 31 Mar 2017 15:12:07 -0700
Subject: [PATCH] mm/hugetlb.c: don't call region_abort if region_chg fails
+Patch-mainline: 4.4.168
+References: bnc#1012382 bnc#1084353
Git-commit: ff8c0c53c47530ffea82c22a0a6df6332b56c957
-Patch-mainline: v4.11-rc5
-References: bnc#1084353
+
+commit ff8c0c53c47530ffea82c22a0a6df6332b56c957 upstream.
Changes to hugetlbfs reservation maps is a two step process. The first
step is a call to region_chg to determine what needs to be changed, and
@@ -40,17 +41,18 @@ Reported-by: Dmitry Vyukov <dvyukov@google.com>
Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Reviewed-by: Michal Hocko <mhocko@suse.com>
-
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
mm/hugetlb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
-index f501f14f14ce..e5828875f7bb 100644
+index 6f99a0f906bb..591e297f0ace 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
-@@ -4403,7 +4403,9 @@ int hugetlb_reserve_pages(struct inode *inode,
+@@ -4142,7 +4142,9 @@ int hugetlb_reserve_pages(struct inode *inode,
return 0;
out_err:
if (!vma || vma->vm_flags & VM_MAYSHARE)
@@ -62,5 +64,5 @@ index f501f14f14ce..e5828875f7bb 100644
kref_put(&resv_map->refs, resv_map_release);
return ret;
--
-1.8.5.6
+2.20.1
diff --git a/patches.fixes/hugetlbfs-fix-offset-overflow-in-hugetlbfs-mmap.patch b/patches.kernel.org/4.4.168-068-hugetlbfs-fix-offset-overflow-in-hugetlbfs-mm.patch
index dff95aa5e6..b527ab0f80 100644
--- a/patches.fixes/hugetlbfs-fix-offset-overflow-in-hugetlbfs-mmap.patch
+++ b/patches.kernel.org/4.4.168-068-hugetlbfs-fix-offset-overflow-in-hugetlbfs-mm.patch
@@ -1,10 +1,11 @@
-From 045c7a3f53d9403b62d396b6d051c4be5044cdb4 Mon Sep 17 00:00:00 2001
From: Mike Kravetz <mike.kravetz@oracle.com>
Date: Thu, 13 Apr 2017 14:56:32 -0700
Subject: [PATCH] hugetlbfs: fix offset overflow in hugetlbfs mmap
+Patch-mainline: 4.4.168
+References: bnc#1012382 bnc#1084353
Git-commit: 045c7a3f53d9403b62d396b6d051c4be5044cdb4
-Patch-mainline: v4.11-rc7
-References: bnc#1084353
+
+commit 045c7a3f53d9403b62d396b6d051c4be5044cdb4 upstream.
If mmap() maps a file, it can be passed an offset into the file at which
the mapping is to start. Offset could be a negative value when
@@ -51,15 +52,18 @@ Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Reviewed-by: Michal Hocko <mhocko@suse.com>
-
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- fs/hugetlbfs/inode.c | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
+ fs/hugetlbfs/inode.c | 15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index a17da8b57fc6..95091797c4d1 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
-@@ -136,16 +136,26 @@ static int hugetlbfs_file_mmap(struct fi
+@@ -136,17 +136,26 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_flags |= VM_HUGETLB | VM_DONTEXPAND;
vma->vm_ops = &hugetlb_vm_ops;
@@ -84,10 +88,11 @@ Reviewed-by: Michal Hocko <mhocko@suse.com>
ret = -ENOMEM;
- len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
-
+-
if (hugetlb_reserve_pages(inode,
vma->vm_pgoff >> huge_page_order(h),
-@@ -155,7 +165,7 @@ static int hugetlbfs_file_mmap(struct fi
+ len >> huge_page_shift(h), vma,
+@@ -155,7 +164,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
ret = 0;
if (vma->vm_flags & VM_WRITE && inode->i_size < len)
@@ -96,3 +101,6 @@ Reviewed-by: Michal Hocko <mhocko@suse.com>
out:
mutex_unlock(&inode->i_mutex);
+--
+2.20.1
+
diff --git a/patches.fixes/hugetlbfs-check-for-pgoff-value-overflow.patch b/patches.kernel.org/4.4.168-069-hugetlbfs-check-for-pgoff-value-overflow.patch
index 2c5b7d76f6..2a00b13605 100644
--- a/patches.fixes/hugetlbfs-check-for-pgoff-value-overflow.patch
+++ b/patches.kernel.org/4.4.168-069-hugetlbfs-check-for-pgoff-value-overflow.patch
@@ -1,10 +1,11 @@
-From 63489f8e821144000e0bdca7e65a8d1cc23a7ee7 Mon Sep 17 00:00:00 2001
From: Mike Kravetz <mike.kravetz@oracle.com>
Date: Thu, 22 Mar 2018 16:17:13 -0700
Subject: [PATCH] hugetlbfs: check for pgoff value overflow
+Patch-mainline: 4.4.168
+References: CVE-2018-7740 bnc#1012382 bnc#1084353
Git-commit: 63489f8e821144000e0bdca7e65a8d1cc23a7ee7
-Patch-mainline: v4.16-rc7
-References: bnc#1084353, CVE-2018-7740
+
+commit 63489f8e821144000e0bdca7e65a8d1cc23a7ee7 upstream.
A vma with vm_pgoff large enough to overflow a loff_t type when
converted to a byte offset can be passed via the remap_file_pages system
@@ -50,15 +51,20 @@ Cc: Yisheng Xie <xieyisheng1@huawei.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-
+[bwh: Backported to 4.4: Use a conditional WARN() instead of VM_WARN()]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- fs/hugetlbfs/inode.c | 17 ++++++++++++++---
- mm/hugetlb.c | 7 +++++++
- 2 files changed, 21 insertions(+), 3 deletions(-)
+ fs/hugetlbfs/inode.c | 17 ++++++++++++++---
+ mm/hugetlb.c | 8 ++++++++
+ 2 files changed, 22 insertions(+), 3 deletions(-)
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index 95091797c4d1..fa8eb59b06a8 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
-@@ -118,6 +118,16 @@ static void huge_pagevec_release(struct
+@@ -118,6 +118,16 @@ static void huge_pagevec_release(struct pagevec *pvec)
pagevec_reinit(pvec);
}
@@ -75,7 +81,7 @@ Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
{
struct inode *inode = file_inode(file);
-@@ -137,12 +147,13 @@ static int hugetlbfs_file_mmap(struct fi
+@@ -137,12 +147,13 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
vma->vm_ops = &hugetlb_vm_ops;
/*
@@ -92,25 +98,25 @@ Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
return -EINVAL;
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 591e297f0ace..f1a45f5077fe 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
-@@ -19,6 +19,7 @@
- #include <linux/bootmem.h>
- #include <linux/sysfs.h>
- #include <linux/slab.h>
-+#include <linux/mmdebug.h>
- #include <linux/rmap.h>
- #include <linux/swap.h>
- #include <linux/swapops.h>
-@@ -4050,6 +4051,11 @@ int hugetlb_reserve_pages(struct inode *
+@@ -4053,6 +4053,14 @@ int hugetlb_reserve_pages(struct inode *inode,
struct resv_map *resv_map;
long gbl_reserve;
+ /* This should never happen */
+ if (from > to) {
++#ifdef CONFIG_DEBUG_VM
++ WARN(1, "%s called with a negative range\n", __func__);
++#endif
+ return -EINVAL;
+ }
+
/*
* Only apply hugepage reservation if asked. At fault time, an
* attempt will be made for VM_NORESERVE to allocate a page
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-070-hugetlbfs-fix-bug-in-pgoff-overflow-checking.patch b/patches.kernel.org/4.4.168-070-hugetlbfs-fix-bug-in-pgoff-overflow-checking.patch
new file mode 100644
index 0000000000..69dc105943
--- /dev/null
+++ b/patches.kernel.org/4.4.168-070-hugetlbfs-fix-bug-in-pgoff-overflow-checking.patch
@@ -0,0 +1,62 @@
+From: Mike Kravetz <mike.kravetz@oracle.com>
+Date: Thu, 5 Apr 2018 16:18:21 -0700
+Subject: [PATCH] hugetlbfs: fix bug in pgoff overflow checking
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 5df63c2a149ae65a9ec239e7c2af44efa6f79beb
+
+commit 5df63c2a149ae65a9ec239e7c2af44efa6f79beb upstream.
+
+This is a fix for a regression in 32 bit kernels caused by an invalid
+check for pgoff overflow in hugetlbfs mmap setup. The check incorrectly
+specified that the size of a loff_t was the same as the size of a long.
+The regression prevents mapping hugetlbfs files at offsets greater than
+4GB on 32 bit kernels.
+
+On 32 bit kernels conversion from a page based unsigned long can not
+overflow a loff_t byte offset. Therefore, skip this check if
+sizeof(unsigned long) != sizeof(loff_t).
+
+Link: http://lkml.kernel.org/r/20180330145402.5053-1-mike.kravetz@oracle.com
+Fixes: 63489f8e8211 ("hugetlbfs: check for pgoff value overflow")
+Reported-by: Dan Rue <dan.rue@linaro.org>
+Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
+Tested-by: Anders Roxell <anders.roxell@linaro.org>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: Yisheng Xie <xieyisheng1@huawei.com>
+Cc: "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>
+Cc: Nic Losby <blurbdust@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/hugetlbfs/inode.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index fa8eb59b06a8..ab34f613fa85 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -148,10 +148,14 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+
+ /*
+ * page based offset in vm_pgoff could be sufficiently large to
+- * overflow a (l)off_t when converted to byte offset.
++ * overflow a loff_t when converted to byte offset. This can
++ * only happen on architectures where sizeof(loff_t) ==
++ * sizeof(unsigned long). So, only check in those instances.
+ */
+- if (vma->vm_pgoff & PGOFF_LOFFT_MAX)
+- return -EINVAL;
++ if (sizeof(unsigned long) == sizeof(loff_t)) {
++ if (vma->vm_pgoff & PGOFF_LOFFT_MAX)
++ return -EINVAL;
++ }
+
+ /* must be huge page aligned */
+ if (vma->vm_pgoff & (~huge_page_mask(h) >> PAGE_SHIFT))
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-071-swiotlb-clean-up-reporting.patch b/patches.kernel.org/4.4.168-071-swiotlb-clean-up-reporting.patch
new file mode 100644
index 0000000000..0f0ee079c5
--- /dev/null
+++ b/patches.kernel.org/4.4.168-071-swiotlb-clean-up-reporting.patch
@@ -0,0 +1,94 @@
+From: Kees Cook <keescook@chromium.org>
+Date: Tue, 10 Jul 2018 16:22:22 -0700
+Subject: [PATCH] swiotlb: clean up reporting
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 7d63fb3af87aa67aa7d24466e792f9d7c57d8e79
+
+commit 7d63fb3af87aa67aa7d24466e792f9d7c57d8e79 upstream.
+
+This removes needless use of '%p', and refactors the printk calls to
+use pr_*() helpers instead.
+
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+[bwh: Backported to 4.4:
+ - Adjust filename
+ - Remove "swiotlb: " prefix from an additional log message]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ lib/swiotlb.c | 20 +++++++++-----------
+ 1 file changed, 9 insertions(+), 11 deletions(-)
+
+diff --git a/lib/swiotlb.c b/lib/swiotlb.c
+index 771234d050c7..6bc452b33b76 100644
+--- a/lib/swiotlb.c
++++ b/lib/swiotlb.c
+@@ -17,6 +17,8 @@
+ * 08/12/11 beckyb Add highmem support
+ */
+
++#define pr_fmt(fmt) "software IO TLB: " fmt
++
+ #include <linux/cache.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/mm.h>
+@@ -143,20 +145,16 @@ static bool no_iotlb_memory;
+ void swiotlb_print_info(void)
+ {
+ unsigned long bytes = io_tlb_nslabs << IO_TLB_SHIFT;
+- unsigned char *vstart, *vend;
+
+ if (no_iotlb_memory) {
+- pr_warn("software IO TLB: No low mem\n");
++ pr_warn("No low mem\n");
+ return;
+ }
+
+- vstart = phys_to_virt(io_tlb_start);
+- vend = phys_to_virt(io_tlb_end);
+-
+- printk(KERN_INFO "software IO TLB [mem %#010llx-%#010llx] (%luMB) mapped at [%p-%p]\n",
++ pr_info("mapped [mem %#010llx-%#010llx] (%luMB)\n",
+ (unsigned long long)io_tlb_start,
+ (unsigned long long)io_tlb_end,
+- bytes >> 20, vstart, vend - 1);
++ bytes >> 20);
+ }
+
+ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
+@@ -230,7 +228,7 @@ swiotlb_init(int verbose)
+ if (io_tlb_start)
+ memblock_free_early(io_tlb_start,
+ PAGE_ALIGN(io_tlb_nslabs << IO_TLB_SHIFT));
+- pr_warn("Cannot allocate SWIOTLB buffer");
++ pr_warn("Cannot allocate buffer");
+ no_iotlb_memory = true;
+ }
+
+@@ -272,8 +270,8 @@ swiotlb_late_init_with_default_size(size_t default_size)
+ return -ENOMEM;
+ }
+ if (order != get_order(bytes)) {
+- printk(KERN_WARNING "Warning: only able to allocate %ld MB "
+- "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
++ pr_warn("only able to allocate %ld MB\n",
++ (PAGE_SIZE << order) >> 20);
+ io_tlb_nslabs = SLABS_PER_PAGE << order;
+ }
+ rc = swiotlb_late_init_with_tbl(vstart, io_tlb_nslabs);
+@@ -680,7 +678,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
+ return ret;
+
+ err_warn:
+- pr_warn("swiotlb: coherent allocation failed for device %s size=%zu\n",
++ pr_warn("coherent allocation failed for device %s size=%zu\n",
+ dev_name(hwdev), size);
+ dump_stack();
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-072-sr-pass-down-correctly-sized-SCSI-sense-buffe.patch b/patches.kernel.org/4.4.168-072-sr-pass-down-correctly-sized-SCSI-sense-buffe.patch
new file mode 100644
index 0000000000..1e91198509
--- /dev/null
+++ b/patches.kernel.org/4.4.168-072-sr-pass-down-correctly-sized-SCSI-sense-buffe.patch
@@ -0,0 +1,90 @@
+From: Jens Axboe <axboe@kernel.dk>
+Date: Mon, 21 May 2018 12:21:14 -0600
+Subject: [PATCH] sr: pass down correctly sized SCSI sense buffer
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: f7068114d45ec55996b9040e98111afa56e010fe
+
+commit f7068114d45ec55996b9040e98111afa56e010fe upstream.
+
+We're casting the CDROM layer request_sense to the SCSI sense
+buffer, but the former is 64 bytes and the latter is 96 bytes.
+As we generally allocate these on the stack, we end up blowing
+up the stack.
+
+Fix this by wrapping the scsi_execute() call with a properly
+sized sense buffer, and copying back the bits for the CDROM
+layer.
+
+Reported-by: Piotr Gabriel Kosinski <pg.kosinski@gmail.com>
+Reported-by: Daniel Shapira <daniel@twistlock.com>
+Tested-by: Kees Cook <keescook@chromium.org>
+Fixes: 82ed4db499b8 ("block: split scsi_request out of struct request")
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+[bwh: Despite what the "Fixes" field says, a buffer overrun was already
+ possible if the sense data was really > 64 bytes long.
+ Backported to 4.4:
+ - We always need to allocate a sense buffer in order to call
+ scsi_normalize_sense()
+ - Remove the existing conditional heap-allocation of the sense buffer]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/scsi/sr_ioctl.c | 21 +++++++--------------
+ 1 file changed, 7 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c
+index 03054c0e7689..3c3e8115f73d 100644
+--- a/drivers/scsi/sr_ioctl.c
++++ b/drivers/scsi/sr_ioctl.c
+@@ -187,30 +187,25 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
+ struct scsi_device *SDev;
+ struct scsi_sense_hdr sshdr;
+ int result, err = 0, retries = 0;
+- struct request_sense *sense = cgc->sense;
++ unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];
+
+ SDev = cd->device;
+
+- if (!sense) {
+- sense = kmalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL);
+- if (!sense) {
+- err = -ENOMEM;
+- goto out;
+- }
+- }
+-
+ retry:
+ if (!scsi_block_when_processing_errors(SDev)) {
+ err = -ENODEV;
+ goto out;
+ }
+
+- memset(sense, 0, sizeof(*sense));
++ memset(sense_buffer, 0, sizeof(sense_buffer));
+ result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
+- cgc->buffer, cgc->buflen, (char *)sense,
++ cgc->buffer, cgc->buflen, sense_buffer,
+ cgc->timeout, IOCTL_RETRIES, 0, NULL);
+
+- scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr);
++ scsi_normalize_sense(sense_buffer, sizeof(sense_buffer), &sshdr);
++
++ if (cgc->sense)
++ memcpy(cgc->sense, sense_buffer, sizeof(*cgc->sense));
+
+ /* Minimal error checking. Ignore cases we know about, and report the rest. */
+ if (driver_byte(result) != 0) {
+@@ -261,8 +256,6 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
+
+ /* Wake up a process waiting for device */
+ out:
+- if (!cgc->sense)
+- kfree(sense);
+ cgc->stat = err;
+ return err;
+ }
+--
+2.20.1
+
diff --git a/patches.suse/0005-mm-remove-write-force-parameters-from-_get_user_pages_locked b/patches.kernel.org/4.4.168-073-mm-remove-write-force-parameters-from-__get_u.patch
index c3561b8a17..fbdcfb933c 100644
--- a/patches.suse/0005-mm-remove-write-force-parameters-from-_get_user_pages_locked
+++ b/patches.kernel.org/4.4.168-073-mm-remove-write-force-parameters-from-__get_u.patch
@@ -1,9 +1,12 @@
From: Lorenzo Stoakes <lstoakes@gmail.com>
Date: Thu, 13 Oct 2016 01:20:11 +0100
-Subject: mm: remove write/force parameters from __get_user_pages_locked()
+Subject: [PATCH] mm: remove write/force parameters from
+ __get_user_pages_locked()
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1027260
Git-commit: 859110d7497cdd0e6b21010d6f777049d676382c
-Patch-mainline: v4.9-rc2
-References: bsc#1027260
+
+commit 859110d7497cdd0e6b21010d6f777049d676382c upstream.
This removes the redundant 'write' and 'force' parameters from
__get_user_pages_locked() to make the use of FOLL_FORCE explicit in
@@ -14,14 +17,21 @@ Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Acked-by: Joerg Roedel <jroedel@suse.de>
+[bwh: Backported to 4.4:
+ - Drop change in get_user_pages_remote()
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- mm/gup.c | 47 +++++++++++++++++++++++++++++++++--------------
- 1 file changed, 33 insertions(+), 14 deletions(-)
+ mm/gup.c | 37 ++++++++++++++++++++++++++-----------
+ 1 file changed, 26 insertions(+), 11 deletions(-)
+diff --git a/mm/gup.c b/mm/gup.c
+index 018144c4b9ec..bed758f7bd63 100644
--- a/mm/gup.c
+++ b/mm/gup.c
-@@ -687,7 +687,6 @@ static __always_inline long __get_user_p
+@@ -627,7 +627,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
struct mm_struct *mm,
unsigned long start,
unsigned long nr_pages,
@@ -29,7 +39,7 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
struct page **pages,
struct vm_area_struct **vmas,
int *locked, bool notify_drop,
-@@ -705,10 +704,6 @@ static __always_inline long __get_user_p
+@@ -645,10 +644,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
if (pages)
flags |= FOLL_GET;
@@ -40,10 +50,12 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
pages_done = 0;
lock_dropped = false;
-@@ -804,9 +799,15 @@ long get_user_pages_locked(unsigned long
+@@ -745,8 +740,15 @@ long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm,
int write, int force, struct page **pages,
int *locked)
{
+- return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force,
+- pages, NULL, locked, true, FOLL_TOUCH);
+ unsigned int flags = FOLL_TOUCH;
+
+ if (write)
@@ -51,14 +63,12 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ if (force)
+ flags |= FOLL_FORCE;
+
- return __get_user_pages_locked(current, current->mm, start, nr_pages,
-- write, force, pages, NULL, locked, true,
-- FOLL_TOUCH);
++ return __get_user_pages_locked(tsk, mm, start, nr_pages,
+ pages, NULL, locked, true, flags);
}
EXPORT_SYMBOL(get_user_pages_locked);
-@@ -827,9 +828,15 @@ __always_inline long __get_user_pages_un
+@@ -767,9 +769,15 @@ __always_inline long __get_user_pages_unlocked(struct task_struct *tsk, struct m
{
long ret;
int locked = 1;
@@ -76,29 +86,12 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (locked)
up_read(&mm->mmap_sem);
return ret;
-@@ -921,9 +928,15 @@ long get_user_pages_remote(struct task_s
- int write, int force, struct page **pages,
- struct vm_area_struct **vmas)
+@@ -861,8 +869,15 @@ long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages, int write,
+ int force, struct page **pages, struct vm_area_struct **vmas)
{
- return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force,
-- pages, vmas, NULL, false,
-- FOLL_TOUCH | FOLL_REMOTE);
-+ unsigned int flags = FOLL_TOUCH | FOLL_REMOTE;
-+
-+ if (write)
-+ flags |= FOLL_WRITE;
-+ if (force)
-+ flags |= FOLL_FORCE;
-+
-+ return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas,
-+ NULL, false, flags);
- }
- EXPORT_SYMBOL(get_user_pages_remote);
-
-@@ -937,9 +950,15 @@ long get_user_pages(unsigned long start,
- int write, int force, struct page **pages,
- struct vm_area_struct **vmas)
- {
+- pages, vmas, NULL, false, FOLL_TOUCH);
+ unsigned int flags = FOLL_TOUCH;
+
+ if (write)
@@ -106,10 +99,11 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ if (force)
+ flags |= FOLL_FORCE;
+
- return __get_user_pages_locked(current, current->mm, start, nr_pages,
-- write, force, pages, vmas, NULL, false,
-- FOLL_TOUCH);
++ return __get_user_pages_locked(tsk, mm, start, nr_pages,
+ pages, vmas, NULL, false, flags);
}
EXPORT_SYMBOL(get_user_pages);
+--
+2.20.1
+
diff --git a/patches.suse/0006-mm-remove-write-force-parameters-from-_get_user_pages_unlocked b/patches.kernel.org/4.4.168-074-mm-remove-write-force-parameters-from-__get_u.patch
index 26ddfec417..3c6b46b60c 100644
--- a/patches.suse/0006-mm-remove-write-force-parameters-from-_get_user_pages_unlocked
+++ b/patches.kernel.org/4.4.168-074-mm-remove-write-force-parameters-from-__get_u.patch
@@ -1,9 +1,12 @@
From: Lorenzo Stoakes <lstoakes@gmail.com>
Date: Thu, 13 Oct 2016 01:20:12 +0100
-Subject: mm: remove write/force parameters from __get_user_pages_unlocked()
+Subject: [PATCH] mm: remove write/force parameters from
+ __get_user_pages_unlocked()
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1027260
Git-commit: d4944b0ecec0af882483fe44b66729316e575208
-Patch-mainline: v4.9-rc2
-References: bsc#1027260
+
+commit d4944b0ecec0af882483fe44b66729316e575208 upstream.
This removes the redundant 'write' and 'force' parameters from
__get_user_pages_unlocked() to make the use of FOLL_FORCE explicit in
@@ -15,31 +18,39 @@ Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-Acked-by: Joerg Roedel <jroedel@suse.de>
+[bwh: Backported to 4.4:
+ - Defer changes in process_vm_rw_single_vec() and async_pf_execute() since
+ they use get_user_pages_unlocked() here
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
- include/linux/mm.h | 3 +--
- mm/gup.c | 17 +++++++++--------
- mm/nommu.c | 12 +++++++++---
- mm/process_vm_access.c | 7 +++++--
- virt/kvm/async_pf.c | 3 ++-
- virt/kvm/kvm_main.c | 11 ++++++++---
- 6 files changed, 34 insertions(+), 19 deletions(-)
+ include/linux/mm.h | 3 +--
+ mm/gup.c | 19 ++++++++++---------
+ mm/nommu.c | 14 ++++++++++----
+ virt/kvm/kvm_main.c | 11 ++++++++---
+ 4 files changed, 29 insertions(+), 18 deletions(-)
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index d4e8077fca96..391ae8a3d5f9 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
-@@ -1268,8 +1268,7 @@ long get_user_pages_locked(unsigned long
- int write, int force, struct page **pages, int *locked);
+@@ -1207,8 +1207,7 @@ long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm,
+ int *locked);
long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
- int write, int force, struct page **pages,
- unsigned int gup_flags);
+ struct page **pages, unsigned int gup_flags);
- long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
+ long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
int write, int force, struct page **pages);
- int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+diff --git a/mm/gup.c b/mm/gup.c
+index bed758f7bd63..9aee6945f349 100644
--- a/mm/gup.c
+++ b/mm/gup.c
-@@ -823,17 +823,11 @@ EXPORT_SYMBOL(get_user_pages_locked);
+@@ -764,17 +764,11 @@ EXPORT_SYMBOL(get_user_pages_locked);
*/
__always_inline long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
@@ -58,10 +69,12 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
down_read(&mm->mmap_sem);
ret = __get_user_pages_locked(tsk, mm, start, nr_pages, pages, NULL,
&locked, false, gup_flags);
-@@ -863,8 +857,15 @@ EXPORT_SYMBOL(__get_user_pages_unlocked)
- long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
+@@ -805,8 +799,15 @@ long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
int write, int force, struct page **pages)
{
+- return __get_user_pages_unlocked(tsk, mm, start, nr_pages, write,
+- force, pages, FOLL_TOUCH);
+ unsigned int flags = FOLL_TOUCH;
+
+ if (write)
@@ -69,15 +82,16 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ if (force)
+ flags |= FOLL_FORCE;
+
- return __get_user_pages_unlocked(current, current->mm, start, nr_pages,
-- write, force, pages, FOLL_TOUCH);
++ return __get_user_pages_unlocked(tsk, mm, start, nr_pages,
+ pages, flags);
}
EXPORT_SYMBOL(get_user_pages_unlocked);
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 92be862c859b..5462ed88a548 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
-@@ -208,8 +208,7 @@ EXPORT_SYMBOL(get_user_pages_locked);
+@@ -211,8 +211,7 @@ EXPORT_SYMBOL(get_user_pages_locked);
long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
unsigned long start, unsigned long nr_pages,
@@ -87,10 +101,12 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
{
long ret;
down_read(&mm->mmap_sem);
-@@ -223,8 +222,15 @@ EXPORT_SYMBOL(__get_user_pages_unlocked)
- long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
+@@ -227,8 +226,15 @@ long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
int write, int force, struct page **pages)
{
+- return __get_user_pages_unlocked(tsk, mm, start, nr_pages, write,
+- force, pages, 0);
+ unsigned int flags = 0;
+
+ if (write)
@@ -98,58 +114,18 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
+ if (force)
+ flags |= FOLL_FORCE;
+
- return __get_user_pages_unlocked(current, current->mm, start, nr_pages,
-- write, force, pages, 0);
++ return __get_user_pages_unlocked(tsk, mm, start, nr_pages,
+ pages, flags);
}
EXPORT_SYMBOL(get_user_pages_unlocked);
---- a/mm/process_vm_access.c
-+++ b/mm/process_vm_access.c
-@@ -88,12 +88,16 @@ static int process_vm_rw_single_vec(unsi
- ssize_t rc = 0;
- unsigned long max_pages_per_loop = PVM_MAX_KMALLOC_PAGES
- / sizeof(struct pages *);
-+ unsigned int flags = FOLL_REMOTE;
-
- /* Work out address and page range required */
- if (len == 0)
- return 0;
- nr_pages = (addr + len - 1) / PAGE_SIZE - addr / PAGE_SIZE + 1;
-
-+ if (vm_write)
-+ flags |= FOLL_WRITE;
-+
- while (!rc && nr_pages && iov_iter_count(iter)) {
- int pages = min(nr_pages, max_pages_per_loop);
- size_t bytes;
-@@ -104,8 +108,7 @@ static int process_vm_rw_single_vec(unsi
- * current/current->mm
- */
- pages = __get_user_pages_unlocked(task, mm, pa, pages,
-- vm_write, 0, process_pages,
-- FOLL_REMOTE);
-+ process_pages, flags);
- if (pages <= 0)
- return -EFAULT;
-
---- a/virt/kvm/async_pf.c
-+++ b/virt/kvm/async_pf.c
-@@ -85,7 +85,8 @@ static void async_pf_execute(struct work
- * mm and might be done in another context, so we must
- * use FOLL_REMOTE.
- */
-- __get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL, FOLL_REMOTE);
-+ __get_user_pages_unlocked(NULL, mm, addr, 1, NULL,
-+ FOLL_WRITE | FOLL_REMOTE);
-
- kvm_async_page_present_sync(vcpu, apf);
-
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index b814ae6822b6..e4be695eb789 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
-@@ -1350,10 +1350,15 @@ static int hva_to_pfn_slow(unsigned long
- down_read(&current->mm->mmap_sem);
- npages = get_user_page_nowait(addr, write_fault, page);
+@@ -1352,10 +1352,15 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
+ npages = get_user_page_nowait(current, current->mm,
+ addr, write_fault, page);
up_read(&current->mm->mmap_sem);
- } else
+ } else {
@@ -166,3 +142,6 @@ Acked-by: Joerg Roedel <jroedel@suse.de>
if (npages != 1)
return npages;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-075-mm-nommu.c-Switch-__get_user_pages_unlocked-t.patch b/patches.kernel.org/4.4.168-075-mm-nommu.c-Switch-__get_user_pages_unlocked-t.patch
new file mode 100644
index 0000000000..fb87dbee8e
--- /dev/null
+++ b/patches.kernel.org/4.4.168-075-mm-nommu.c-Switch-__get_user_pages_unlocked-t.patch
@@ -0,0 +1,37 @@
+From: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Date: Sun, 16 Dec 2018 23:50:08 +0000
+Subject: [PATCH] mm/nommu.c: Switch __get_user_pages_unlocked() to use
+ __get_user_pages()
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: ff099ed77421a5dc8206bb61e5a598b28ab39ebb
+
+Extracted from commit cde70140fed8 "mm/gup: Overload get_user_pages()
+functions". This is needed before picking commit 768ae309a961
+"mm: replace get_user_pages() write/force parameters with gup_flags".
+
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ mm/nommu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 5462ed88a548..f5322195dbcd 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -215,8 +215,8 @@ long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ {
+ long ret;
+ down_read(&mm->mmap_sem);
+- ret = get_user_pages(tsk, mm, start, nr_pages, write, force,
+- pages, NULL);
++ ret = __get_user_pages(tsk, mm, start, nr_pages, gup_flags, pages,
++ NULL, NULL);
+ up_read(&mm->mmap_sem);
+ return ret;
+ }
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-076-mm-replace-get_user_pages_unlocked-write-forc.patch b/patches.kernel.org/4.4.168-076-mm-replace-get_user_pages_unlocked-write-forc.patch
new file mode 100644
index 0000000000..3413a11cdc
--- /dev/null
+++ b/patches.kernel.org/4.4.168-076-mm-replace-get_user_pages_unlocked-write-forc.patch
@@ -0,0 +1,318 @@
+From: Lorenzo Stoakes <lstoakes@gmail.com>
+Date: Thu, 13 Oct 2016 01:20:13 +0100
+Subject: [PATCH] mm: replace get_user_pages_unlocked() write/force parameters
+ with gup_flags
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1027260
+Git-commit: c164154f66f0c9b02673f07aa4f044f1d9c70274
+
+commit c164154f66f0c9b02673f07aa4f044f1d9c70274 upstream.
+
+This removes the 'write' and 'force' use from get_user_pages_unlocked()
+and replaces them with 'gup_flags' to make the use of FOLL_FORCE
+explicit in callers as use of this flag can result in surprising
+behaviour (and hence bugs) within the mm subsystem.
+
+Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 4.4:
+ - Also update calls from process_vm_rw_single_vec() and async_pf_execute()
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/mips/mm/gup.c | 2 +-
+ arch/s390/mm/gup.c | 2 +-
+ arch/sh/mm/gup.c | 3 ++-
+ arch/sparc/mm/gup.c | 3 ++-
+ arch/x86/mm/gup.c | 2 +-
+ drivers/media/pci/ivtv/ivtv-udma.c | 3 ++-
+ drivers/media/pci/ivtv/ivtv-yuv.c | 8 ++++----
+ drivers/scsi/st.c | 5 ++---
+ drivers/video/fbdev/pvr2fb.c | 2 +-
+ include/linux/mm.h | 2 +-
+ mm/gup.c | 14 ++++----------
+ mm/nommu.c | 11 ++---------
+ mm/process_vm_access.c | 6 +++++-
+ mm/util.c | 2 +-
+ net/ceph/pagevec.c | 2 +-
+ virt/kvm/async_pf.c | 2 +-
+ 16 files changed, 31 insertions(+), 38 deletions(-)
+
+diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
+index 349995d19c7f..e596e0a1cecc 100644
+--- a/arch/mips/mm/gup.c
++++ b/arch/mips/mm/gup.c
+@@ -303,7 +303,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+
+ ret = get_user_pages_unlocked(current, mm, start,
+ (end - start) >> PAGE_SHIFT,
+- write, 0, pages);
++ pages, write ? FOLL_WRITE : 0);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c
+index 12bbf0e8478f..7ad41be8b373 100644
+--- a/arch/s390/mm/gup.c
++++ b/arch/s390/mm/gup.c
+@@ -242,7 +242,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ start += nr << PAGE_SHIFT;
+ pages += nr;
+ ret = get_user_pages_unlocked(current, mm, start,
+- nr_pages - nr, write, 0, pages);
++ nr_pages - nr, pages, write ? FOLL_WRITE : 0);
+ /* Have to be a bit careful with return values */
+ if (nr > 0)
+ ret = (ret < 0) ? nr : ret + nr;
+diff --git a/arch/sh/mm/gup.c b/arch/sh/mm/gup.c
+index e7af6a65baab..8c51a0e94854 100644
+--- a/arch/sh/mm/gup.c
++++ b/arch/sh/mm/gup.c
+@@ -258,7 +258,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ pages += nr;
+
+ ret = get_user_pages_unlocked(current, mm, start,
+- (end - start) >> PAGE_SHIFT, write, 0, pages);
++ (end - start) >> PAGE_SHIFT, pages,
++ write ? FOLL_WRITE : 0);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c
+index 2e5c4fc2daa9..150f48303fb0 100644
+--- a/arch/sparc/mm/gup.c
++++ b/arch/sparc/mm/gup.c
+@@ -250,7 +250,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ pages += nr;
+
+ ret = get_user_pages_unlocked(current, mm, start,
+- (end - start) >> PAGE_SHIFT, write, 0, pages);
++ (end - start) >> PAGE_SHIFT, pages,
++ write ? FOLL_WRITE : 0);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c
+index ae9a37bf1371..7d2542ad346a 100644
+--- a/arch/x86/mm/gup.c
++++ b/arch/x86/mm/gup.c
+@@ -388,7 +388,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+
+ ret = get_user_pages_unlocked(current, mm, start,
+ (end - start) >> PAGE_SHIFT,
+- write, 0, pages);
++ pages, write ? FOLL_WRITE : 0);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+diff --git a/drivers/media/pci/ivtv/ivtv-udma.c b/drivers/media/pci/ivtv/ivtv-udma.c
+index 24152accc66c..8729fdebef8f 100644
+--- a/drivers/media/pci/ivtv/ivtv-udma.c
++++ b/drivers/media/pci/ivtv/ivtv-udma.c
+@@ -125,7 +125,8 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
+
+ /* Get user pages for DMA Xfer */
+ err = get_user_pages_unlocked(current, current->mm,
+- user_dma.uaddr, user_dma.page_count, 0, 1, dma->map);
++ user_dma.uaddr, user_dma.page_count, dma->map,
++ FOLL_FORCE);
+
+ if (user_dma.page_count != err) {
+ IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
+diff --git a/drivers/media/pci/ivtv/ivtv-yuv.c b/drivers/media/pci/ivtv/ivtv-yuv.c
+index 2b8e7b2f2b86..9cd995f418e0 100644
+--- a/drivers/media/pci/ivtv/ivtv-yuv.c
++++ b/drivers/media/pci/ivtv/ivtv-yuv.c
+@@ -76,13 +76,13 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
+
+ /* Get user pages for DMA Xfer */
+ y_pages = get_user_pages_unlocked(current, current->mm,
+- y_dma.uaddr, y_dma.page_count, 0, 1,
+- &dma->map[0]);
++ y_dma.uaddr, y_dma.page_count,
++ &dma->map[0], FOLL_FORCE);
+ uv_pages = 0; /* silence gcc. value is set and consumed only if: */
+ if (y_pages == y_dma.page_count) {
+ uv_pages = get_user_pages_unlocked(current, current->mm,
+- uv_dma.uaddr, uv_dma.page_count, 0, 1,
+- &dma->map[y_pages]);
++ uv_dma.uaddr, uv_dma.page_count,
++ &dma->map[y_pages], FOLL_FORCE);
+ }
+
+ if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
+diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
+index 2e522951b619..088a68ab4246 100644
+--- a/drivers/scsi/st.c
++++ b/drivers/scsi/st.c
+@@ -4821,9 +4821,8 @@ static int sgl_map_user_pages(struct st_buffer *STbp,
+ current->mm,
+ uaddr,
+ nr_pages,
+- rw == READ,
+- 0, /* don't force */
+- pages);
++ pages,
++ rw == READ ? FOLL_WRITE : 0); /* don't force */
+
+ /* Errors and no page mapped should return here */
+ if (res < nr_pages)
+diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
+index 0e24eb9c219c..750a384bf191 100644
+--- a/drivers/video/fbdev/pvr2fb.c
++++ b/drivers/video/fbdev/pvr2fb.c
+@@ -687,7 +687,7 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
+ return -ENOMEM;
+
+ ret = get_user_pages_unlocked(current, current->mm, (unsigned long)buf,
+- nr_pages, WRITE, 0, pages);
++ nr_pages, pages, FOLL_WRITE);
+
+ if (ret < nr_pages) {
+ nr_pages = ret;
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 391ae8a3d5f9..c043c936a4a5 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1210,7 +1210,7 @@ long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ struct page **pages, unsigned int gup_flags);
+ long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages);
++ struct page **pages, unsigned int gup_flags);
+ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ struct page **pages);
+
+diff --git a/mm/gup.c b/mm/gup.c
+index 9aee6945f349..6bbec1b694ea 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -797,17 +797,10 @@ EXPORT_SYMBOL(__get_user_pages_unlocked);
+ */
+ long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages)
++ struct page **pages, unsigned int gup_flags)
+ {
+- unsigned int flags = FOLL_TOUCH;
+-
+- if (write)
+- flags |= FOLL_WRITE;
+- if (force)
+- flags |= FOLL_FORCE;
+-
+ return __get_user_pages_unlocked(tsk, mm, start, nr_pages,
+- pages, flags);
++ pages, gup_flags | FOLL_TOUCH);
+ }
+ EXPORT_SYMBOL(get_user_pages_unlocked);
+
+@@ -1427,7 +1420,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ pages += nr;
+
+ ret = get_user_pages_unlocked(current, mm, start,
+- nr_pages - nr, write, 0, pages);
++ nr_pages - nr, pages,
++ write ? FOLL_WRITE : 0);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+diff --git a/mm/nommu.c b/mm/nommu.c
+index f5322195dbcd..e249e06579fb 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -224,17 +224,10 @@ EXPORT_SYMBOL(__get_user_pages_unlocked);
+
+ long get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages)
++ struct page **pages, unsigned int gup_flags)
+ {
+- unsigned int flags = 0;
+-
+- if (write)
+- flags |= FOLL_WRITE;
+- if (force)
+- flags |= FOLL_FORCE;
+-
+ return __get_user_pages_unlocked(tsk, mm, start, nr_pages,
+- pages, flags);
++ pages, gup_flags);
+ }
+ EXPORT_SYMBOL(get_user_pages_unlocked);
+
+diff --git a/mm/process_vm_access.c b/mm/process_vm_access.c
+index 5d453e58ddbf..1b5a6104c5fc 100644
+--- a/mm/process_vm_access.c
++++ b/mm/process_vm_access.c
+@@ -88,19 +88,23 @@ static int process_vm_rw_single_vec(unsigned long addr,
+ ssize_t rc = 0;
+ unsigned long max_pages_per_loop = PVM_MAX_KMALLOC_PAGES
+ / sizeof(struct pages *);
++ unsigned int flags = 0;
+
+ /* Work out address and page range required */
+ if (len == 0)
+ return 0;
+ nr_pages = (addr + len - 1) / PAGE_SIZE - addr / PAGE_SIZE + 1;
+
++ if (vm_write)
++ flags |= FOLL_WRITE;
++
+ while (!rc && nr_pages && iov_iter_count(iter)) {
+ int pages = min(nr_pages, max_pages_per_loop);
+ size_t bytes;
+
+ /* Get the pages we're interested in */
+ pages = get_user_pages_unlocked(task, mm, pa, pages,
+- vm_write, 0, process_pages);
++ process_pages, flags);
+ if (pages <= 0)
+ return -EFAULT;
+
+diff --git a/mm/util.c b/mm/util.c
+index 5fae5b9c2885..db39235970c6 100644
+--- a/mm/util.c
++++ b/mm/util.c
+@@ -278,7 +278,7 @@ int __weak get_user_pages_fast(unsigned long start,
+ {
+ struct mm_struct *mm = current->mm;
+ return get_user_pages_unlocked(current, mm, start, nr_pages,
+- write, 0, pages);
++ pages, write ? FOLL_WRITE : 0);
+ }
+ EXPORT_SYMBOL_GPL(get_user_pages_fast);
+
+diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c
+index d4f5f220a8e5..28453d698d86 100644
+--- a/net/ceph/pagevec.c
++++ b/net/ceph/pagevec.c
+@@ -26,7 +26,7 @@ struct page **ceph_get_direct_page_vector(const void __user *data,
+ while (got < num_pages) {
+ rc = get_user_pages_unlocked(current, current->mm,
+ (unsigned long)data + ((unsigned long)got * PAGE_SIZE),
+- num_pages - got, write_page, 0, pages + got);
++ num_pages - got, pages + got, write_page ? FOLL_WRITE : 0);
+ if (rc < 0)
+ break;
+ BUG_ON(rc == 0);
+diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c
+index 4f70d12e392d..eddce59986ee 100644
+--- a/virt/kvm/async_pf.c
++++ b/virt/kvm/async_pf.c
+@@ -80,7 +80,7 @@ static void async_pf_execute(struct work_struct *work)
+
+ might_sleep();
+
+- get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL);
++ get_user_pages_unlocked(NULL, mm, addr, 1, NULL, FOLL_WRITE);
+ kvm_async_page_present_sync(vcpu, apf);
+
+ spin_lock(&vcpu->async_pf.lock);
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-077-mm-replace-get_user_pages_locked-write-force-.patch b/patches.kernel.org/4.4.168-077-mm-replace-get_user_pages_locked-write-force-.patch
new file mode 100644
index 0000000000..8c6120fab4
--- /dev/null
+++ b/patches.kernel.org/4.4.168-077-mm-replace-get_user_pages_locked-write-force-.patch
@@ -0,0 +1,121 @@
+From: Lorenzo Stoakes <lstoakes@gmail.com>
+Date: Thu, 13 Oct 2016 01:20:14 +0100
+Subject: [PATCH] mm: replace get_user_pages_locked() write/force parameters
+ with gup_flags
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1027260
+Git-commit: 3b913179c3fa89dd0e304193fa0c746fc0481447
+
+commit 3b913179c3fa89dd0e304193fa0c746fc0481447 upstream.
+
+This removes the 'write' and 'force' use from get_user_pages_locked()
+and replaces them with 'gup_flags' to make the use of FOLL_FORCE
+explicit in callers as use of this flag can result in surprising
+behaviour (and hence bugs) within the mm subsystem.
+
+Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 4.4: adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ include/linux/mm.h | 3 +--
+ mm/frame_vector.c | 8 +++++++-
+ mm/gup.c | 12 +++---------
+ mm/nommu.c | 5 ++++-
+ 4 files changed, 15 insertions(+), 13 deletions(-)
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index c043c936a4a5..cbb9bd8b910a 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1203,8 +1203,7 @@ long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ struct vm_area_struct **vmas);
+ long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages,
+- int *locked);
++ unsigned int gup_flags, struct page **pages, int *locked);
+ long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+ struct page **pages, unsigned int gup_flags);
+diff --git a/mm/frame_vector.c b/mm/frame_vector.c
+index 7cf2b7163222..40e3116b5666 100644
+--- a/mm/frame_vector.c
++++ b/mm/frame_vector.c
+@@ -41,10 +41,16 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
+ int ret = 0;
+ int err;
+ int locked;
++ unsigned int gup_flags = 0;
+
+ if (nr_frames == 0)
+ return 0;
+
++ if (write)
++ gup_flags |= FOLL_WRITE;
++ if (force)
++ gup_flags |= FOLL_FORCE;
++
+ if (WARN_ON_ONCE(nr_frames > vec->nr_allocated))
+ nr_frames = vec->nr_allocated;
+
+@@ -59,7 +65,7 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
+ vec->got_ref = true;
+ vec->is_pfns = false;
+ ret = get_user_pages_locked(current, mm, start, nr_frames,
+- write, force, (struct page **)(vec->ptrs), &locked);
++ gup_flags, (struct page **)(vec->ptrs), &locked);
+ goto out;
+ }
+
+diff --git a/mm/gup.c b/mm/gup.c
+index 6bbec1b694ea..bcdefb977269 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -737,18 +737,12 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
+ */
+ long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages,
++ unsigned int gup_flags, struct page **pages,
+ int *locked)
+ {
+- unsigned int flags = FOLL_TOUCH;
+-
+- if (write)
+- flags |= FOLL_WRITE;
+- if (force)
+- flags |= FOLL_FORCE;
+-
+ return __get_user_pages_locked(tsk, mm, start, nr_pages,
+- pages, NULL, locked, true, flags);
++ pages, NULL, locked, true,
++ gup_flags | FOLL_TOUCH);
+ }
+ EXPORT_SYMBOL(get_user_pages_locked);
+
+diff --git a/mm/nommu.c b/mm/nommu.c
+index e249e06579fb..6cbb985238c4 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -201,9 +201,12 @@ EXPORT_SYMBOL(get_user_pages);
+
+ long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages,
++ unsigned int gup_flags, struct page **pages,
+ int *locked)
+ {
++ int write = gup_flags & FOLL_WRITE;
++ int force = gup_flags & FOLL_FORCE;
++
+ return get_user_pages(tsk, mm, start, nr_pages, write, force,
+ pages, NULL);
+ }
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-078-mm-replace-get_vaddr_frames-write-force-param.patch b/patches.kernel.org/4.4.168-078-mm-replace-get_vaddr_frames-write-force-param.patch
new file mode 100644
index 0000000000..49acb14fb6
--- /dev/null
+++ b/patches.kernel.org/4.4.168-078-mm-replace-get_vaddr_frames-write-force-param.patch
@@ -0,0 +1,138 @@
+From: Lorenzo Stoakes <lstoakes@gmail.com>
+Date: Thu, 13 Oct 2016 01:20:15 +0100
+Subject: [PATCH] mm: replace get_vaddr_frames() write/force parameters with
+ gup_flags
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 7f23b3504a0df63b724180262c5f3f117f21bcae
+
+commit 7f23b3504a0df63b724180262c5f3f117f21bcae upstream.
+
+This removes the 'write' and 'force' from get_vaddr_frames() and
+replaces them with 'gup_flags' to make the use of FOLL_FORCE explicit in
+callers as use of this flag can result in surprising behaviour (and
+hence bugs) within the mm subsystem.
+
+Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/gpu/drm/exynos/exynos_drm_g2d.c | 3 ++-
+ drivers/media/platform/omap/omap_vout.c | 2 +-
+ drivers/media/v4l2-core/videobuf2-memops.c | 6 +++++-
+ include/linux/mm.h | 2 +-
+ mm/frame_vector.c | 13 ++-----------
+ 5 files changed, 11 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+index c17efdb238a6..639ea28808e2 100644
+--- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c
++++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c
+@@ -471,7 +471,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
+ goto err_free;
+ }
+
+- ret = get_vaddr_frames(start, npages, true, true, g2d_userptr->vec);
++ ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE,
++ g2d_userptr->vec);
+ if (ret != npages) {
+ DRM_ERROR("failed to get user pages from userptr.\n");
+ if (ret < 0)
+diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
+index 70c28d19ea04..596359576109 100644
+--- a/drivers/media/platform/omap/omap_vout.c
++++ b/drivers/media/platform/omap/omap_vout.c
+@@ -214,7 +214,7 @@ static int omap_vout_get_userptr(struct videobuf_buffer *vb, u32 virtp,
+ if (!vec)
+ return -ENOMEM;
+
+- ret = get_vaddr_frames(virtp, 1, true, false, vec);
++ ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec);
+ if (ret != 1) {
+ frame_vector_destroy(vec);
+ return -EINVAL;
+diff --git a/drivers/media/v4l2-core/videobuf2-memops.c b/drivers/media/v4l2-core/videobuf2-memops.c
+index 3c3b517f1d1c..1cd322e939c7 100644
+--- a/drivers/media/v4l2-core/videobuf2-memops.c
++++ b/drivers/media/v4l2-core/videobuf2-memops.c
+@@ -42,6 +42,10 @@ struct frame_vector *vb2_create_framevec(unsigned long start,
+ unsigned long first, last;
+ unsigned long nr;
+ struct frame_vector *vec;
++ unsigned int flags = FOLL_FORCE;
++
++ if (write)
++ flags |= FOLL_WRITE;
+
+ first = start >> PAGE_SHIFT;
+ last = (start + length - 1) >> PAGE_SHIFT;
+@@ -49,7 +53,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start,
+ vec = frame_vector_create(nr);
+ if (!vec)
+ return ERR_PTR(-ENOMEM);
+- ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec);
++ ret = get_vaddr_frames(start & PAGE_MASK, nr, flags, vec);
+ if (ret < 0)
+ goto out_destroy;
+ /* We accept only complete set of PFNs */
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index cbb9bd8b910a..5c18cd9c72d2 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1227,7 +1227,7 @@ struct frame_vector {
+ struct frame_vector *frame_vector_create(unsigned int nr_frames);
+ void frame_vector_destroy(struct frame_vector *vec);
+ int get_vaddr_frames(unsigned long start, unsigned int nr_pfns,
+- bool write, bool force, struct frame_vector *vec);
++ unsigned int gup_flags, struct frame_vector *vec);
+ void put_vaddr_frames(struct frame_vector *vec);
+ int frame_vector_to_pages(struct frame_vector *vec);
+ void frame_vector_to_pfns(struct frame_vector *vec);
+diff --git a/mm/frame_vector.c b/mm/frame_vector.c
+index 40e3116b5666..c1e7926a41c4 100644
+--- a/mm/frame_vector.c
++++ b/mm/frame_vector.c
+@@ -11,10 +11,7 @@
+ * get_vaddr_frames() - map virtual addresses to pfns
+ * @start: starting user address
+ * @nr_frames: number of pages / pfns from start to map
+- * @write: whether pages will be written to by the caller
+- * @force: whether to force write access even if user mapping is
+- * readonly. See description of the same argument of
+- get_user_pages().
++ * @gup_flags: flags modifying lookup behaviour
+ * @vec: structure which receives pages / pfns of the addresses mapped.
+ * It should have space for at least nr_frames entries.
+ *
+@@ -34,23 +31,17 @@
+ * This function takes care of grabbing mmap_sem as necessary.
+ */
+ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
+- bool write, bool force, struct frame_vector *vec)
++ unsigned int gup_flags, struct frame_vector *vec)
+ {
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ int ret = 0;
+ int err;
+ int locked;
+- unsigned int gup_flags = 0;
+
+ if (nr_frames == 0)
+ return 0;
+
+- if (write)
+- gup_flags |= FOLL_WRITE;
+- if (force)
+- gup_flags |= FOLL_FORCE;
+-
+ if (WARN_ON_ONCE(nr_frames > vec->nr_allocated))
+ nr_frames = vec->nr_allocated;
+
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-079-mm-replace-get_user_pages-write-force-paramet.patch b/patches.kernel.org/4.4.168-079-mm-replace-get_user_pages-write-force-paramet.patch
new file mode 100644
index 0000000000..e3a54cd245
--- /dev/null
+++ b/patches.kernel.org/4.4.168-079-mm-replace-get_user_pages-write-force-paramet.patch
@@ -0,0 +1,596 @@
+From: Lorenzo Stoakes <lstoakes@gmail.com>
+Date: Thu, 13 Oct 2016 01:20:16 +0100
+Subject: [PATCH] mm: replace get_user_pages() write/force parameters with
+ gup_flags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Patch-mainline: 4.4.168
+References: bnc#1012382 bsc#1027260
+Git-commit: 768ae309a96103ed02eb1e111e838c87854d8b51
+
+commit 768ae309a96103ed02eb1e111e838c87854d8b51 upstream.
+
+This removes the 'write' and 'force' from get_user_pages() and replaces
+them with 'gup_flags' to make the use of FOLL_FORCE explicit in callers
+as use of this flag can result in surprising behaviour (and hence bugs)
+within the mm subsystem.
+
+Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Acked-by: Christian König <christian.koenig@amd.com>
+Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 4.4:
+ - Drop changes in rapidio, vchiq, goldfish
+ - Keep the "write" variable in amdgpu_ttm_tt_pin_userptr() as it's still
+ needed
+ - Also update calls from various other places that now use
+ get_user_pages_remote() upstream, which were updated there by commit
+ 9beae1ea8930 "mm: replace get_user_pages_remote() write/force ..."
+ - Also update calls from hfi1 and ipath
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ arch/cris/arch-v32/drivers/cryptocop.c | 4 +---
+ arch/ia64/kernel/err_inject.c | 2 +-
+ arch/x86/mm/mpx.c | 3 +--
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 6 +++++-
+ drivers/gpu/drm/i915/i915_gem_userptr.c | 6 +++++-
+ drivers/gpu/drm/radeon/radeon_ttm.c | 2 +-
+ drivers/gpu/drm/via/via_dmablit.c | 4 ++--
+ drivers/infiniband/core/umem.c | 6 +++++-
+ drivers/infiniband/core/umem_odp.c | 7 +++++--
+ drivers/infiniband/hw/mthca/mthca_memfree.c | 4 ++--
+ drivers/infiniband/hw/qib/qib_user_pages.c | 3 ++-
+ drivers/infiniband/hw/usnic/usnic_uiom.c | 5 ++++-
+ drivers/media/v4l2-core/videobuf-dma-sg.c | 7 +++++--
+ drivers/misc/mic/scif/scif_rma.c | 3 +--
+ drivers/misc/sgi-gru/grufault.c | 2 +-
+ drivers/staging/rdma/hfi1/user_pages.c | 2 +-
+ drivers/staging/rdma/ipath/ipath_user_pages.c | 2 +-
+ drivers/virt/fsl_hypervisor.c | 4 ++--
+ fs/exec.c | 9 +++++++--
+ include/linux/mm.h | 2 +-
+ kernel/events/uprobes.c | 4 ++--
+ mm/gup.c | 15 +++++----------
+ mm/memory.c | 6 +++++-
+ mm/mempolicy.c | 2 +-
+ mm/nommu.c | 18 ++++--------------
+ security/tomoyo/domain.c | 3 ++-
+ 26 files changed, 72 insertions(+), 59 deletions(-)
+
+diff --git a/arch/cris/arch-v32/drivers/cryptocop.c b/arch/cris/arch-v32/drivers/cryptocop.c
+index 877da1908234..98e2a5dbcfda 100644
+--- a/arch/cris/arch-v32/drivers/cryptocop.c
++++ b/arch/cris/arch-v32/drivers/cryptocop.c
+@@ -2724,7 +2724,6 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
+ (unsigned long int)(oper.indata + prev_ix),
+ noinpages,
+ 0, /* read access only for in data */
+- 0, /* no force */
+ inpages,
+ NULL);
+
+@@ -2740,8 +2739,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
+ current->mm,
+ (unsigned long int)oper.cipher_outdata,
+ nooutpages,
+- 1, /* write access for out data */
+- 0, /* no force */
++ FOLL_WRITE, /* write access for out data */
+ outpages,
+ NULL);
+ up_read(&current->mm->mmap_sem);
+diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c
+index 0c161ed6d18e..8205b456de7a 100644
+--- a/arch/ia64/kernel/err_inject.c
++++ b/arch/ia64/kernel/err_inject.c
+@@ -143,7 +143,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr,
+ int ret;
+
+ ret = get_user_pages(current, current->mm, virt_addr,
+- 1, VM_READ, 0, NULL, NULL);
++ 1, FOLL_WRITE, NULL, NULL);
+ if (ret<=0) {
+ #ifdef ERR_INJ_DEBUG
+ printk("Virtual address %lx is not existing.\n",virt_addr);
+diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
+index 7ed47b1e6f42..7e94fc6f608a 100644
+--- a/arch/x86/mm/mpx.c
++++ b/arch/x86/mm/mpx.c
+@@ -536,10 +536,9 @@ static int mpx_resolve_fault(long __user *addr, int write)
+ {
+ long gup_ret;
+ int nr_pages = 1;
+- int force = 0;
+
+ gup_ret = get_user_pages(current, current->mm, (unsigned long)addr,
+- nr_pages, write, force, NULL, NULL);
++ nr_pages, write ? FOLL_WRITE : 0, NULL, NULL);
+ /*
+ * get_user_pages() returns number of pages gotten.
+ * 0 means we failed to fault in and get anything,
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index e40a6d8b0b92..062c23125b2a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -496,9 +496,13 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
+ int r;
+
+ int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
++ unsigned int flags = 0;
+ enum dma_data_direction direction = write ?
+ DMA_BIDIRECTIONAL : DMA_TO_DEVICE;
+
++ if (write)
++ flags |= FOLL_WRITE;
++
+ if (current->mm != gtt->usermm)
+ return -EPERM;
+
+@@ -519,7 +523,7 @@ static int amdgpu_ttm_tt_pin_userptr(struct ttm_tt *ttm)
+ struct page **pages = ttm->pages + pinned;
+
+ r = get_user_pages(current, current->mm, userptr, num_pages,
+- write, 0, pages, NULL);
++ flags, pages, NULL);
+ if (r < 0)
+ goto release_pages;
+
+diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c
+index 359fe2b8bb8a..b02113b57d51 100644
+--- a/drivers/gpu/drm/i915/i915_gem_userptr.c
++++ b/drivers/gpu/drm/i915/i915_gem_userptr.c
+@@ -581,13 +581,17 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
+ pvec = drm_malloc_ab(npages, sizeof(struct page *));
+ if (pvec != NULL) {
+ struct mm_struct *mm = obj->userptr.mm->mm;
++ unsigned int flags = 0;
++
++ if (!obj->userptr.read_only)
++ flags |= FOLL_WRITE;
+
+ down_read(&mm->mmap_sem);
+ while (pinned < npages) {
+ ret = get_user_pages(work->task, mm,
+ obj->userptr.ptr + pinned * PAGE_SIZE,
+ npages - pinned,
+- !obj->userptr.read_only, 0,
++ flags,
+ pvec + pinned, NULL);
+ if (ret < 0)
+ break;
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
+index d684e2b79d2b..0c380fe77382 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -557,7 +557,7 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
+ struct page **pages = ttm->pages + pinned;
+
+ r = get_user_pages(current, current->mm, userptr, num_pages,
+- write, 0, pages, NULL);
++ write ? FOLL_WRITE : 0, pages, NULL);
+ if (r < 0)
+ goto release_pages;
+
+diff --git a/drivers/gpu/drm/via/via_dmablit.c b/drivers/gpu/drm/via/via_dmablit.c
+index d0cbd5ecd7f0..4459cb32d1fe 100644
+--- a/drivers/gpu/drm/via/via_dmablit.c
++++ b/drivers/gpu/drm/via/via_dmablit.c
+@@ -242,8 +242,8 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
+ ret = get_user_pages(current, current->mm,
+ (unsigned long)xfer->mem_addr,
+ vsg->num_pages,
+- (vsg->direction == DMA_FROM_DEVICE),
+- 0, vsg->pages, NULL);
++ (vsg->direction == DMA_FROM_DEVICE) ? FOLL_WRITE : 0,
++ vsg->pages, NULL);
+
+ up_read(&current->mm->mmap_sem);
+ if (ret != vsg->num_pages) {
+diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
+index 98fd9a594841..8762eac47570 100644
+--- a/drivers/infiniband/core/umem.c
++++ b/drivers/infiniband/core/umem.c
+@@ -95,6 +95,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
+ DEFINE_DMA_ATTRS(attrs);
+ struct scatterlist *sg, *sg_list_start;
+ int need_release = 0;
++ unsigned int gup_flags = FOLL_WRITE;
+
+ if (dmasync)
+ dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs);
+@@ -177,6 +178,9 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
+ if (ret)
+ goto out;
+
++ if (!umem->writable)
++ gup_flags |= FOLL_FORCE;
++
+ need_release = 1;
+ sg_list_start = umem->sg_head.sgl;
+
+@@ -184,7 +188,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
+ ret = get_user_pages(current, current->mm, cur_base,
+ min_t(unsigned long, npages,
+ PAGE_SIZE / sizeof (struct page *)),
+- 1, !umem->writable, page_list, vma_list);
++ gup_flags, page_list, vma_list);
+
+ if (ret < 0)
+ goto out;
+diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c
+index 40becdb3196e..738ccfee7cae 100644
+--- a/drivers/infiniband/core/umem_odp.c
++++ b/drivers/infiniband/core/umem_odp.c
+@@ -527,6 +527,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
+ u64 off;
+ int j, k, ret = 0, start_idx, npages = 0;
+ u64 base_virt_addr;
++ unsigned int flags = 0;
+
+ if (access_mask == 0)
+ return -EINVAL;
+@@ -556,6 +557,9 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
+ goto out_put_task;
+ }
+
++ if (access_mask & ODP_WRITE_ALLOWED_BIT)
++ flags |= FOLL_WRITE;
++
+ start_idx = (user_virt - ib_umem_start(umem)) >> PAGE_SHIFT;
+ k = start_idx;
+
+@@ -574,8 +578,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
+ */
+ npages = get_user_pages(owning_process, owning_mm, user_virt,
+ gup_num_pages,
+- access_mask & ODP_WRITE_ALLOWED_BIT, 0,
+- local_page_list, NULL);
++ flags, local_page_list, NULL);
+ up_read(&owning_mm->mmap_sem);
+
+ if (npages < 0)
+diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
+index 7d2e42dd6926..8676685dbf3d 100644
+--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
++++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
+@@ -472,8 +472,8 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
+ goto out;
+ }
+
+- ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1, 1, 0,
+- pages, NULL);
++ ret = get_user_pages(current, current->mm, uaddr & PAGE_MASK, 1,
++ FOLL_WRITE, pages, NULL);
+ if (ret < 0)
+ goto out;
+
+diff --git a/drivers/infiniband/hw/qib/qib_user_pages.c b/drivers/infiniband/hw/qib/qib_user_pages.c
+index ab1588ae1c85..75c3f0dffe63 100644
+--- a/drivers/infiniband/hw/qib/qib_user_pages.c
++++ b/drivers/infiniband/hw/qib/qib_user_pages.c
+@@ -68,7 +68,8 @@ static int __qib_get_user_pages(unsigned long start_page, size_t num_pages,
+ for (got = 0; got < num_pages; got += ret) {
+ ret = get_user_pages(current, current->mm,
+ start_page + got * PAGE_SIZE,
+- num_pages - got, 1, 1,
++ num_pages - got,
++ FOLL_WRITE | FOLL_FORCE,
+ p + got, NULL);
+ if (ret < 0)
+ goto bail_release;
+diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c
+index 645a5f6e6c88..7f0d75e29441 100644
+--- a/drivers/infiniband/hw/usnic/usnic_uiom.c
++++ b/drivers/infiniband/hw/usnic/usnic_uiom.c
+@@ -113,6 +113,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
+ int flags;
+ dma_addr_t pa;
+ DEFINE_DMA_ATTRS(attrs);
++ unsigned int gup_flags;
+
+ if (dmasync)
+ dma_set_attr(DMA_ATTR_WRITE_BARRIER, &attrs);
+@@ -140,6 +141,8 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
+
+ flags = IOMMU_READ | IOMMU_CACHE;
+ flags |= (writable) ? IOMMU_WRITE : 0;
++ gup_flags = FOLL_WRITE;
++ gup_flags |= (writable) ? 0 : FOLL_FORCE;
+ cur_base = addr & PAGE_MASK;
+ ret = 0;
+
+@@ -147,7 +150,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
+ ret = get_user_pages(current, current->mm, cur_base,
+ min_t(unsigned long, npages,
+ PAGE_SIZE / sizeof(struct page *)),
+- 1, !writable, page_list, NULL);
++ gup_flags, page_list, NULL);
+
+ if (ret < 0)
+ goto out;
+diff --git a/drivers/media/v4l2-core/videobuf-dma-sg.c b/drivers/media/v4l2-core/videobuf-dma-sg.c
+index f669cedca8bd..f74a74d91b9e 100644
+--- a/drivers/media/v4l2-core/videobuf-dma-sg.c
++++ b/drivers/media/v4l2-core/videobuf-dma-sg.c
+@@ -156,6 +156,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
+ {
+ unsigned long first, last;
+ int err, rw = 0;
++ unsigned int flags = FOLL_FORCE;
+
+ dma->direction = direction;
+ switch (dma->direction) {
+@@ -178,13 +179,15 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
+ if (NULL == dma->pages)
+ return -ENOMEM;
+
++ if (rw == READ)
++ flags |= FOLL_WRITE;
++
+ dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
+ data, size, dma->nr_pages);
+
+ err = get_user_pages(current, current->mm,
+ data & PAGE_MASK, dma->nr_pages,
+- rw == READ, 1, /* force */
+- dma->pages, NULL);
++ flags, dma->pages, NULL);
+
+ if (err != dma->nr_pages) {
+ dma->nr_pages = (err >= 0) ? err : 0;
+diff --git a/drivers/misc/mic/scif/scif_rma.c b/drivers/misc/mic/scif/scif_rma.c
+index 8bd63128d536..71c69e1c4ac0 100644
+--- a/drivers/misc/mic/scif/scif_rma.c
++++ b/drivers/misc/mic/scif/scif_rma.c
+@@ -1398,8 +1398,7 @@ int __scif_pin_pages(void *addr, size_t len, int *out_prot,
+ mm,
+ (u64)addr,
+ nr_pages,
+- !!(prot & SCIF_PROT_WRITE),
+- 0,
++ (prot & SCIF_PROT_WRITE) ? FOLL_WRITE : 0,
+ pinned_pages->pages,
+ NULL);
+ up_write(&mm->mmap_sem);
+diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
+index f74fc0ca2ef9..e6b723c6a2af 100644
+--- a/drivers/misc/sgi-gru/grufault.c
++++ b/drivers/misc/sgi-gru/grufault.c
+@@ -199,7 +199,7 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma,
+ *pageshift = PAGE_SHIFT;
+ #endif
+ if (get_user_pages
+- (current, current->mm, vaddr, 1, write, 0, &page, NULL) <= 0)
++ (current, current->mm, vaddr, 1, write ? FOLL_WRITE : 0, &page, NULL) <= 0)
+ return -EFAULT;
+ *paddr = page_to_phys(page);
+ put_page(page);
+diff --git a/drivers/staging/rdma/hfi1/user_pages.c b/drivers/staging/rdma/hfi1/user_pages.c
+index 9071afbd7bf4..b776b74d3d14 100644
+--- a/drivers/staging/rdma/hfi1/user_pages.c
++++ b/drivers/staging/rdma/hfi1/user_pages.c
+@@ -85,7 +85,7 @@ static int __hfi1_get_user_pages(unsigned long start_page, size_t num_pages,
+ for (got = 0; got < num_pages; got += ret) {
+ ret = get_user_pages(current, current->mm,
+ start_page + got * PAGE_SIZE,
+- num_pages - got, 1, 1,
++ num_pages - got, FOLL_WRITE | FOLL_FORCE,
+ p + got, NULL);
+ if (ret < 0)
+ goto bail_release;
+diff --git a/drivers/staging/rdma/ipath/ipath_user_pages.c b/drivers/staging/rdma/ipath/ipath_user_pages.c
+index d29b4daf61f8..f69ec728e0de 100644
+--- a/drivers/staging/rdma/ipath/ipath_user_pages.c
++++ b/drivers/staging/rdma/ipath/ipath_user_pages.c
+@@ -72,7 +72,7 @@ static int __ipath_get_user_pages(unsigned long start_page, size_t num_pages,
+ for (got = 0; got < num_pages; got += ret) {
+ ret = get_user_pages(current, current->mm,
+ start_page + got * PAGE_SIZE,
+- num_pages - got, 1, 1,
++ num_pages - got, FOLL_WRITE | FOLL_FORCE,
+ p + got, NULL);
+ if (ret < 0)
+ goto bail_release;
+diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c
+index 32c8fc5f7a5c..590a0f51a249 100644
+--- a/drivers/virt/fsl_hypervisor.c
++++ b/drivers/virt/fsl_hypervisor.c
+@@ -246,8 +246,8 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p)
+ down_read(&current->mm->mmap_sem);
+ num_pinned = get_user_pages(current, current->mm,
+ param.local_vaddr - lb_offset, num_pages,
+- (param.source == -1) ? READ : WRITE,
+- 0, pages, NULL);
++ (param.source == -1) ? 0 : FOLL_WRITE,
++ pages, NULL);
+ up_read(&current->mm->mmap_sem);
+
+ if (num_pinned != num_pages) {
+diff --git a/fs/exec.c b/fs/exec.c
+index 910fc70c4542..3dad755b7048 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -191,6 +191,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+ {
+ struct page *page;
+ int ret;
++ unsigned int gup_flags = FOLL_FORCE;
+
+ #ifdef CONFIG_STACK_GROWSUP
+ if (write) {
+@@ -199,8 +200,12 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
+ return NULL;
+ }
+ #endif
+- ret = get_user_pages(current, bprm->mm, pos,
+- 1, write, 1, &page, NULL);
++
++ if (write)
++ gup_flags |= FOLL_WRITE;
++
++ ret = get_user_pages(current, bprm->mm, pos, 1, gup_flags,
++ &page, NULL);
+ if (ret <= 0)
+ return NULL;
+
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 5c18cd9c72d2..d1cfd3657cce 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1199,7 +1199,7 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ struct vm_area_struct **vmas, int *nonblocking);
+ long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages,
++ unsigned int gup_flags, struct page **pages,
+ struct vm_area_struct **vmas);
+ long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
+index 7108097fa2f2..aad43c88a668 100644
+--- a/kernel/events/uprobes.c
++++ b/kernel/events/uprobes.c
+@@ -299,7 +299,7 @@ int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr,
+
+ retry:
+ /* Read the page with vaddr into memory */
+- ret = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
++ ret = get_user_pages(NULL, mm, vaddr, 1, FOLL_FORCE, &old_page, &vma);
+ if (ret <= 0)
+ return ret;
+
+@@ -1700,7 +1700,7 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
+ if (likely(result == 0))
+ goto out;
+
+- result = get_user_pages(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
++ result = get_user_pages(NULL, mm, vaddr, 1, FOLL_FORCE, &page, NULL);
+ if (result < 0)
+ return result;
+
+diff --git a/mm/gup.c b/mm/gup.c
+index bcdefb977269..2370e2417d61 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -854,18 +854,13 @@ EXPORT_SYMBOL(get_user_pages_unlocked);
+ * FAULT_FLAG_ALLOW_RETRY to handle_mm_fault.
+ */
+ long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+- unsigned long start, unsigned long nr_pages, int write,
+- int force, struct page **pages, struct vm_area_struct **vmas)
++ unsigned long start, unsigned long nr_pages,
++ unsigned int gup_flags, struct page **pages,
++ struct vm_area_struct **vmas)
+ {
+- unsigned int flags = FOLL_TOUCH;
+-
+- if (write)
+- flags |= FOLL_WRITE;
+- if (force)
+- flags |= FOLL_FORCE;
+-
+ return __get_user_pages_locked(tsk, mm, start, nr_pages,
+- pages, vmas, NULL, false, flags);
++ pages, vmas, NULL, false,
++ gup_flags | FOLL_TOUCH);
+ }
+ EXPORT_SYMBOL(get_user_pages);
+
+diff --git a/mm/memory.c b/mm/memory.c
+index 5aee9ec8b8c6..13142accda4f 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -3715,6 +3715,10 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ {
+ struct vm_area_struct *vma;
+ void *old_buf = buf;
++ unsigned int flags = FOLL_FORCE;
++
++ if (write)
++ flags |= FOLL_WRITE;
+
+ down_read(&mm->mmap_sem);
+ /* ignore errors, just check how much was successfully transferred */
+@@ -3724,7 +3728,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ struct page *page = NULL;
+
+ ret = get_user_pages(tsk, mm, addr, 1,
+- write, 1, &page, &vma);
++ flags, &page, &vma);
+ if (ret <= 0) {
+ #ifndef CONFIG_HAVE_IOREMAP_PROT
+ break;
+diff --git a/mm/mempolicy.c b/mm/mempolicy.c
+index be9840bf11d1..44134ba6fb53 100644
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -818,7 +818,7 @@ static int lookup_node(struct mm_struct *mm, unsigned long addr)
+ struct page *p;
+ int err;
+
+- err = get_user_pages(current, mm, addr & PAGE_MASK, 1, 0, 0, &p, NULL);
++ err = get_user_pages(current, mm, addr & PAGE_MASK, 1, 0, &p, NULL);
+ if (err >= 0) {
+ err = page_to_nid(p);
+ put_page(p);
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 6cbb985238c4..073ea36abc21 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -184,18 +184,11 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ */
+ long get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+- int write, int force, struct page **pages,
++ unsigned int gup_flags, struct page **pages,
+ struct vm_area_struct **vmas)
+ {
+- int flags = 0;
+-
+- if (write)
+- flags |= FOLL_WRITE;
+- if (force)
+- flags |= FOLL_FORCE;
+-
+- return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas,
+- NULL);
++ return __get_user_pages(tsk, mm, start, nr_pages,
++ gup_flags, pages, vmas, NULL);
+ }
+ EXPORT_SYMBOL(get_user_pages);
+
+@@ -204,10 +197,7 @@ long get_user_pages_locked(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned int gup_flags, struct page **pages,
+ int *locked)
+ {
+- int write = gup_flags & FOLL_WRITE;
+- int force = gup_flags & FOLL_FORCE;
+-
+- return get_user_pages(tsk, mm, start, nr_pages, write, force,
++ return get_user_pages(tsk, mm, start, nr_pages, gup_flags,
+ pages, NULL);
+ }
+ EXPORT_SYMBOL(get_user_pages_locked);
+diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c
+index 38651454ed08..6f388e77999c 100644
+--- a/security/tomoyo/domain.c
++++ b/security/tomoyo/domain.c
+@@ -874,7 +874,8 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
+ }
+ /* Same with get_arg_page(bprm, pos, 0) in fs/exec.c */
+ #ifdef CONFIG_MMU
+- if (get_user_pages(current, bprm->mm, pos, 1, 0, 1, &page, NULL) <= 0)
++ if (get_user_pages(current, bprm->mm, pos, 1,
++ FOLL_FORCE, &page, NULL) <= 0)
+ return false;
+ #else
+ page = bprm->page[pos / PAGE_SIZE];
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-080-mm-replace-__access_remote_vm-write-parameter.patch b/patches.kernel.org/4.4.168-080-mm-replace-__access_remote_vm-write-parameter.patch
new file mode 100644
index 0000000000..b241275964
--- /dev/null
+++ b/patches.kernel.org/4.4.168-080-mm-replace-__access_remote_vm-write-parameter.patch
@@ -0,0 +1,131 @@
+From: Lorenzo Stoakes <lstoakes@gmail.com>
+Date: Thu, 13 Oct 2016 01:20:18 +0100
+Subject: [PATCH] mm: replace __access_remote_vm() write parameter with
+ gup_flags
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 442486ec1096781c50227b73f721a63974b0fdda
+
+commit 442486ec1096781c50227b73f721a63974b0fdda upstream.
+
+This removes the 'write' argument from __access_remote_vm() and replaces
+it with 'gup_flags' as use of this function previously silently implied
+FOLL_FORCE, whereas after this patch callers explicitly pass this flag.
+
+We make this explicit as use of FOLL_FORCE can result in surprising
+behaviour (and hence bugs) within the mm subsystem.
+
+Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 4.4: adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ mm/memory.c | 23 +++++++++++++++--------
+ mm/nommu.c | 9 ++++++---
+ 2 files changed, 21 insertions(+), 11 deletions(-)
+
+diff --git a/mm/memory.c b/mm/memory.c
+index 13142accda4f..1a0d727687d0 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -3711,14 +3711,11 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
+ * given task for page fault accounting.
+ */
+ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+- unsigned long addr, void *buf, int len, int write)
++ unsigned long addr, void *buf, int len, unsigned int gup_flags)
+ {
+ struct vm_area_struct *vma;
+ void *old_buf = buf;
+- unsigned int flags = FOLL_FORCE;
+-
+- if (write)
+- flags |= FOLL_WRITE;
++ int write = gup_flags & FOLL_WRITE;
+
+ down_read(&mm->mmap_sem);
+ /* ignore errors, just check how much was successfully transferred */
+@@ -3728,7 +3725,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ struct page *page = NULL;
+
+ ret = get_user_pages(tsk, mm, addr, 1,
+- flags, &page, &vma);
++ gup_flags, &page, &vma);
+ if (ret <= 0) {
+ #ifndef CONFIG_HAVE_IOREMAP_PROT
+ break;
+@@ -3787,7 +3784,12 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+ void *buf, int len, int write)
+ {
+- return __access_remote_vm(NULL, mm, addr, buf, len, write);
++ unsigned int flags = FOLL_FORCE;
++
++ if (write)
++ flags |= FOLL_WRITE;
++
++ return __access_remote_vm(NULL, mm, addr, buf, len, flags);
+ }
+
+ /*
+@@ -3800,12 +3802,17 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr,
+ {
+ struct mm_struct *mm;
+ int ret;
++ unsigned int flags = FOLL_FORCE;
+
+ mm = get_task_mm(tsk);
+ if (!mm)
+ return 0;
+
+- ret = __access_remote_vm(tsk, mm, addr, buf, len, write);
++ if (write)
++ flags |= FOLL_WRITE;
++
++ ret = __access_remote_vm(tsk, mm, addr, buf, len, flags);
++
+ mmput(mm);
+
+ return ret;
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 073ea36abc21..6ffc6be4344f 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -1929,9 +1929,10 @@ void filemap_map_pages(struct vm_area_struct *vma, struct vm_fault *vmf)
+ EXPORT_SYMBOL(filemap_map_pages);
+
+ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+- unsigned long addr, void *buf, int len, int write)
++ unsigned long addr, void *buf, int len, unsigned int gup_flags)
+ {
+ struct vm_area_struct *vma;
++ int write = gup_flags & FOLL_WRITE;
+
+ down_read(&mm->mmap_sem);
+
+@@ -1973,7 +1974,8 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+ void *buf, int len, int write)
+ {
+- return __access_remote_vm(NULL, mm, addr, buf, len, write);
++ return __access_remote_vm(NULL, mm, addr, buf, len,
++ write ? FOLL_WRITE : 0);
+ }
+
+ /*
+@@ -1991,7 +1993,8 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
+ if (!mm)
+ return 0;
+
+- len = __access_remote_vm(tsk, mm, addr, buf, len, write);
++ len = __access_remote_vm(tsk, mm, addr, buf, len,
++ write ? FOLL_WRITE : 0);
+
+ mmput(mm);
+ return len;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-081-mm-replace-access_remote_vm-write-parameter-w.patch b/patches.kernel.org/4.4.168-081-mm-replace-access_remote_vm-write-parameter-w.patch
new file mode 100644
index 0000000000..0a5e9419f6
--- /dev/null
+++ b/patches.kernel.org/4.4.168-081-mm-replace-access_remote_vm-write-parameter-w.patch
@@ -0,0 +1,174 @@
+From: Lorenzo Stoakes <lstoakes@gmail.com>
+Date: Thu, 13 Oct 2016 01:20:19 +0100
+Subject: [PATCH] mm: replace access_remote_vm() write parameter with gup_flags
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 6347e8d5bcce33fc36e651901efefbe2c93a43ef
+
+commit 6347e8d5bcce33fc36e651901efefbe2c93a43ef upstream.
+
+This removes the 'write' argument from access_remote_vm() and replaces
+it with 'gup_flags' as use of this function previously silently implied
+FOLL_FORCE, whereas after this patch callers explicitly pass this flag.
+
+We make this explicit as use of FOLL_FORCE can result in surprising
+behaviour (and hence bugs) within the mm subsystem.
+
+Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/proc/base.c | 19 +++++++++++++------
+ include/linux/mm.h | 2 +-
+ mm/memory.c | 11 +++--------
+ mm/nommu.c | 7 +++----
+ 4 files changed, 20 insertions(+), 19 deletions(-)
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 4beed301e224..445c42b2ec61 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -254,7 +254,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ * Inherently racy -- command line shares address space
+ * with code and data.
+ */
+- rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0);
++ rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_FORCE);
+ if (rv <= 0)
+ goto out_free_page;
+
+@@ -272,7 +272,8 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ int nr_read;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count, 0);
++ nr_read = access_remote_vm(mm, p, page, _count,
++ FOLL_FORCE);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -307,7 +308,8 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ bool final;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count, 0);
++ nr_read = access_remote_vm(mm, p, page, _count,
++ FOLL_FORCE);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -356,7 +358,8 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ bool final;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count, 0);
++ nr_read = access_remote_vm(mm, p, page, _count,
++ FOLL_FORCE);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -868,6 +871,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
+ unsigned long addr = *ppos;
+ ssize_t copied;
+ char *page;
++ unsigned int flags = FOLL_FORCE;
+
+ if (!mm)
+ return 0;
+@@ -880,6 +884,9 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
+ if (!atomic_inc_not_zero(&mm->mm_users))
+ goto free;
+
++ if (write)
++ flags |= FOLL_WRITE;
++
+ while (count > 0) {
+ int this_len = min_t(int, count, PAGE_SIZE);
+
+@@ -888,7 +895,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
+ break;
+ }
+
+- this_len = access_remote_vm(mm, addr, page, this_len, write);
++ this_len = access_remote_vm(mm, addr, page, this_len, flags);
+ if (!this_len) {
+ if (!copied)
+ copied = -EIO;
+@@ -1001,7 +1008,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+ this_len = min(max_len, this_len);
+
+ retval = access_remote_vm(mm, (env_start + src),
+- page, this_len, 0);
++ page, this_len, FOLL_FORCE);
+
+ if (retval <= 0) {
+ ret = retval;
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index d1cfd3657cce..9a0716e900b5 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1191,7 +1191,7 @@ static inline int fixup_user_fault(struct task_struct *tsk,
+
+ extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+ extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+- void *buf, int len, int write);
++ void *buf, int len, unsigned int gup_flags);
+
+ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long start, unsigned long nr_pages,
+diff --git a/mm/memory.c b/mm/memory.c
+index 1a0d727687d0..fa752df6dc85 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -3777,19 +3777,14 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ * @addr: start address to access
+ * @buf: source or destination buffer
+ * @len: number of bytes to transfer
+- * @write: whether the access is a write
++ * @gup_flags: flags modifying lookup behaviour
+ *
+ * The caller must hold a reference on @mm.
+ */
+ int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+- void *buf, int len, int write)
++ void *buf, int len, unsigned int gup_flags)
+ {
+- unsigned int flags = FOLL_FORCE;
+-
+- if (write)
+- flags |= FOLL_WRITE;
+-
+- return __access_remote_vm(NULL, mm, addr, buf, len, flags);
++ return __access_remote_vm(NULL, mm, addr, buf, len, gup_flags);
+ }
+
+ /*
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 6ffc6be4344f..2360546db065 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -1967,15 +1967,14 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ * @addr: start address to access
+ * @buf: source or destination buffer
+ * @len: number of bytes to transfer
+- * @write: whether the access is a write
++ * @gup_flags: flags modifying lookup behaviour
+ *
+ * The caller must hold a reference on @mm.
+ */
+ int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+- void *buf, int len, int write)
++ void *buf, int len, unsigned int gup_flags)
+ {
+- return __access_remote_vm(NULL, mm, addr, buf, len,
+- write ? FOLL_WRITE : 0);
++ return __access_remote_vm(NULL, mm, addr, buf, len, gup_flags);
+ }
+
+ /*
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-082-proc-don-t-use-FOLL_FORCE-for-reading-cmdline.patch b/patches.kernel.org/4.4.168-082-proc-don-t-use-FOLL_FORCE-for-reading-cmdline.patch
new file mode 100644
index 0000000000..4f9a392555
--- /dev/null
+++ b/patches.kernel.org/4.4.168-082-proc-don-t-use-FOLL_FORCE-for-reading-cmdline.patch
@@ -0,0 +1,106 @@
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Mon, 24 Oct 2016 19:00:44 -0700
+Subject: [PATCH] proc: don't use FOLL_FORCE for reading cmdline and
+ environment
+References: bnc#1012382 CVE-2018-1120 bnc#1093158
+Patch-mainline: 4.4.168
+Git-commit: 272ddc8b37354c3fe111ab26d25e792629148eee
+
+commit 272ddc8b37354c3fe111ab26d25e792629148eee upstream.
+
+Now that Lorenzo cleaned things up and made the FOLL_FORCE users
+explicit, it becomes obvious how some of them don't really need
+FOLL_FORCE at all.
+
+So remove FOLL_FORCE from the proc code that reads the command line and
+arguments from user space.
+
+The mem_rw() function actually does want FOLL_FORCE, because gdd (and
+possibly many other debuggers) use it as a much more convenient version
+of PTRACE_PEEKDATA, but we should consider making the FOLL_FORCE part
+conditional on actually being a ptracer. This does not actually do
+that, just moves adds a comment to that effect and moves the gup_flags
+settings next to each other.
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/proc/base.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 445c42b2ec61..5b8d840cf2b4 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -254,7 +254,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ * Inherently racy -- command line shares address space
+ * with code and data.
+ */
+- rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_FORCE);
++ rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0);
+ if (rv <= 0)
+ goto out_free_page;
+
+@@ -272,8 +272,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ int nr_read;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count,
+- FOLL_FORCE);
++ nr_read = access_remote_vm(mm, p, page, _count, 0);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -308,8 +307,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ bool final;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count,
+- FOLL_FORCE);
++ nr_read = access_remote_vm(mm, p, page, _count, 0);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -358,8 +356,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ bool final;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count,
+- FOLL_FORCE);
++ nr_read = access_remote_vm(mm, p, page, _count, 0);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -871,7 +868,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
+ unsigned long addr = *ppos;
+ ssize_t copied;
+ char *page;
+- unsigned int flags = FOLL_FORCE;
++ unsigned int flags;
+
+ if (!mm)
+ return 0;
+@@ -884,6 +881,8 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
+ if (!atomic_inc_not_zero(&mm->mm_users))
+ goto free;
+
++ /* Maybe we should limit FOLL_FORCE to actual ptrace users? */
++ flags = FOLL_FORCE;
+ if (write)
+ flags |= FOLL_WRITE;
+
+@@ -1007,8 +1006,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+ max_len = min_t(size_t, PAGE_SIZE, count);
+ this_len = min(max_len, this_len);
+
+- retval = access_remote_vm(mm, (env_start + src),
+- page, this_len, FOLL_FORCE);
++ retval = access_remote_vm(mm, (env_start + src), page, this_len, 0);
+
+ if (retval <= 0) {
+ ret = retval;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-083-proc-do-not-access-cmdline-nor-environ-from-f.patch b/patches.kernel.org/4.4.168-083-proc-do-not-access-cmdline-nor-environ-from-f.patch
new file mode 100644
index 0000000000..e98ac6368a
--- /dev/null
+++ b/patches.kernel.org/4.4.168-083-proc-do-not-access-cmdline-nor-environ-from-f.patch
@@ -0,0 +1,124 @@
+From: Willy Tarreau <w@1wt.eu>
+Date: Fri, 11 May 2018 08:11:44 +0200
+Subject: [PATCH] proc: do not access cmdline nor environ from file-backed
+ areas
+References: bnc#1012382 CVE-2018-1120 bnc#1093158
+Patch-mainline: 4.4.168
+Git-commit: 7f7ccc2ccc2e70c6054685f5e3522efa81556830
+
+commit 7f7ccc2ccc2e70c6054685f5e3522efa81556830 upstream.
+
+proc_pid_cmdline_read() and environ_read() directly access the target
+process' VM to retrieve the command line and environment. If this
+process remaps these areas onto a file via mmap(), the requesting
+process may experience various issues such as extra delays if the
+underlying device is slow to respond.
+
+Let's simply refuse to access file-backed areas in these functions.
+For this we add a new FOLL_ANON gup flag that is passed to all calls
+to access_remote_vm(). The code already takes care of such failures
+(including unmapped areas). Accesses via /proc/pid/mem were not
+changed though.
+
+This was assigned CVE-2018-1120.
+
+Note for stable backports: the patch may apply to kernels prior to 4.11
+but silently miss one location; it must be checked that no call to
+access_remote_vm() keeps zero as the last argument.
+
+Reported-by: Qualys Security Advisory <qsa@qualys.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Oleg Nesterov <oleg@redhat.com>
+Signed-off-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[bwh: Backported to 4.4:
+ - Update the extra call to access_remote_vm() from proc_pid_cmdline_read()
+ - Adjust context]
+Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ fs/proc/base.c | 10 +++++-----
+ include/linux/mm.h | 1 +
+ mm/gup.c | 3 +++
+ 3 files changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index 5b8d840cf2b4..bd8c26a409a7 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -254,7 +254,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ * Inherently racy -- command line shares address space
+ * with code and data.
+ */
+- rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0);
++ rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_ANON);
+ if (rv <= 0)
+ goto out_free_page;
+
+@@ -272,7 +272,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ int nr_read;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count, 0);
++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -307,7 +307,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ bool final;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count, 0);
++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -356,7 +356,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
+ bool final;
+
+ _count = min3(count, len, PAGE_SIZE);
+- nr_read = access_remote_vm(mm, p, page, _count, 0);
++ nr_read = access_remote_vm(mm, p, page, _count, FOLL_ANON);
+ if (nr_read < 0)
+ rv = nr_read;
+ if (nr_read <= 0)
+@@ -1006,7 +1006,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
+ max_len = min_t(size_t, PAGE_SIZE, count);
+ this_len = min(max_len, this_len);
+
+- retval = access_remote_vm(mm, (env_start + src), page, this_len, 0);
++ retval = access_remote_vm(mm, (env_start + src), page, this_len, FOLL_ANON);
+
+ if (retval <= 0) {
+ ret = retval;
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 9a0716e900b5..251adf4d8a71 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2120,6 +2120,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma,
+ #define FOLL_TRIED 0x800 /* a retry, previous pass started an IO */
+ #define FOLL_MLOCK 0x1000 /* lock present pages */
+ #define FOLL_COW 0x4000 /* internal GUP flag */
++#define FOLL_ANON 0x8000 /* don't do file mappings */
+
+ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
+ void *data);
+diff --git a/mm/gup.c b/mm/gup.c
+index 2370e2417d61..2cd3b31e3666 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -368,6 +368,9 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags)
+ if (vm_flags & (VM_IO | VM_PFNMAP))
+ return -EFAULT;
+
++ if (gup_flags & FOLL_ANON && !vma_is_anonymous(vma))
++ return -EFAULT;
++
+ if (gup_flags & FOLL_WRITE) {
+ if (!(vm_flags & VM_WRITE)) {
+ if (!(gup_flags & FOLL_FORCE))
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-084-media-dvb-frontends-fix-i2c-access-helpers-fo.patch b/patches.kernel.org/4.4.168-084-media-dvb-frontends-fix-i2c-access-helpers-fo.patch
new file mode 100644
index 0000000000..1ad324002f
--- /dev/null
+++ b/patches.kernel.org/4.4.168-084-media-dvb-frontends-fix-i2c-access-helpers-fo.patch
@@ -0,0 +1,218 @@
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Thu, 30 Nov 2017 11:55:46 -0500
+Subject: [PATCH] media: dvb-frontends: fix i2c access helpers for KASAN
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 3cd890dbe2a4f14cc44c85bb6cf37e5e22d4dd0e
+
+commit 3cd890dbe2a4f14cc44c85bb6cf37e5e22d4dd0e upstream.
+
+A typical code fragment was copied across many dvb-frontend drivers and
+causes large stack frames when built with with CONFIG_KASAN on gcc-5/6/7:
+
+drivers/media/dvb-frontends/cxd2841er.c:3225:1: error: the frame size of 3992 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
+drivers/media/dvb-frontends/cxd2841er.c:3404:1: error: the frame size of 3136 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
+drivers/media/dvb-frontends/stv0367.c:3143:1: error: the frame size of 4016 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
+drivers/media/dvb-frontends/stv090x.c:3430:1: error: the frame size of 5312 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
+drivers/media/dvb-frontends/stv090x.c:4248:1: error: the frame size of 4872 bytes is larger than 3072 bytes [-Werror=frame-larger-than=]
+
+gcc-8 now solves this by consolidating the stack slots for the argument
+variables, but on older compilers we can get the same behavior by taking
+the pointer of a local variable rather than the inline function argument.
+
+Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/media/dvb-frontends/ascot2e.c | 4 +++-
+ drivers/media/dvb-frontends/cxd2841er.c | 4 +++-
+ drivers/media/dvb-frontends/horus3a.c | 4 +++-
+ drivers/media/dvb-frontends/itd1000.c | 5 +++--
+ drivers/media/dvb-frontends/mt312.c | 5 ++++-
+ drivers/media/dvb-frontends/stb0899_drv.c | 3 ++-
+ drivers/media/dvb-frontends/stb6100.c | 6 ++++--
+ drivers/media/dvb-frontends/stv0367.c | 4 +++-
+ drivers/media/dvb-frontends/stv090x.c | 4 +++-
+ drivers/media/dvb-frontends/stv6110x.c | 4 +++-
+ drivers/media/dvb-frontends/zl10039.c | 4 +++-
+ 11 files changed, 34 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c
+index f770f6a2c987..3ea9edc8cdbe 100644
+--- a/drivers/media/dvb-frontends/ascot2e.c
++++ b/drivers/media/dvb-frontends/ascot2e.c
+@@ -155,7 +155,9 @@ static int ascot2e_write_regs(struct ascot2e_priv *priv,
+
+ static int ascot2e_write_reg(struct ascot2e_priv *priv, u8 reg, u8 val)
+ {
+- return ascot2e_write_regs(priv, reg, &val, 1);
++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++ return ascot2e_write_regs(priv, reg, &tmp, 1);
+ }
+
+ static int ascot2e_read_regs(struct ascot2e_priv *priv,
+diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c
+index 107853b0fddd..bde77671a37c 100644
+--- a/drivers/media/dvb-frontends/cxd2841er.c
++++ b/drivers/media/dvb-frontends/cxd2841er.c
+@@ -241,7 +241,9 @@ static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
+ static int cxd2841er_write_reg(struct cxd2841er_priv *priv,
+ u8 addr, u8 reg, u8 val)
+ {
+- return cxd2841er_write_regs(priv, addr, reg, &val, 1);
++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++ return cxd2841er_write_regs(priv, addr, reg, &tmp, 1);
+ }
+
+ static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
+diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c
+index 000606af70f7..f770ab72a8e3 100644
+--- a/drivers/media/dvb-frontends/horus3a.c
++++ b/drivers/media/dvb-frontends/horus3a.c
+@@ -89,7 +89,9 @@ static int horus3a_write_regs(struct horus3a_priv *priv,
+
+ static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
+ {
+- return horus3a_write_regs(priv, reg, &val, 1);
++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++ return horus3a_write_regs(priv, reg, &tmp, 1);
+ }
+
+ static int horus3a_enter_power_save(struct horus3a_priv *priv)
+diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c
+index cadcae4cff89..ac9d2591bb6f 100644
+--- a/drivers/media/dvb-frontends/itd1000.c
++++ b/drivers/media/dvb-frontends/itd1000.c
+@@ -99,8 +99,9 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
+
+ static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
+ {
+- int ret = itd1000_write_regs(state, r, &v, 1);
+- state->shadow[r] = v;
++ u8 tmp = v; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++ int ret = itd1000_write_regs(state, r, &tmp, 1);
++ state->shadow[r] = tmp;
+ return ret;
+ }
+
+diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c
+index c36e6764eead..c44188271028 100644
+--- a/drivers/media/dvb-frontends/mt312.c
++++ b/drivers/media/dvb-frontends/mt312.c
+@@ -142,7 +142,10 @@ static inline int mt312_readreg(struct mt312_state *state,
+ static inline int mt312_writereg(struct mt312_state *state,
+ const enum mt312_reg_addr reg, const u8 val)
+ {
+- return mt312_write(state, reg, &val, 1);
++ u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++
++ return mt312_write(state, reg, &tmp, 1);
+ }
+
+ static inline u32 mt312_div(u32 a, u32 b)
+diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c
+index 756650f154ab..ad9b7d4f8d95 100644
+--- a/drivers/media/dvb-frontends/stb0899_drv.c
++++ b/drivers/media/dvb-frontends/stb0899_drv.c
+@@ -552,7 +552,8 @@ int stb0899_write_regs(struct stb0899_state *state, unsigned int reg, u8 *data,
+
+ int stb0899_write_reg(struct stb0899_state *state, unsigned int reg, u8 data)
+ {
+- return stb0899_write_regs(state, reg, &data, 1);
++ u8 tmp = data;
++ return stb0899_write_regs(state, reg, &tmp, 1);
+ }
+
+ /*
+diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c
+index 4ef8a5c7003e..44fac2570034 100644
+--- a/drivers/media/dvb-frontends/stb6100.c
++++ b/drivers/media/dvb-frontends/stb6100.c
+@@ -226,12 +226,14 @@ static int stb6100_write_reg_range(struct stb6100_state *state, u8 buf[], int st
+
+ static int stb6100_write_reg(struct stb6100_state *state, u8 reg, u8 data)
+ {
++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
+ if (unlikely(reg >= STB6100_NUMREGS)) {
+ dprintk(verbose, FE_ERROR, 1, "Invalid register offset 0x%x", reg);
+ return -EREMOTEIO;
+ }
+- data = (data & stb6100_template[reg].mask) | stb6100_template[reg].set;
+- return stb6100_write_reg_range(state, &data, reg, 1);
++ tmp = (tmp & stb6100_template[reg].mask) | stb6100_template[reg].set;
++ return stb6100_write_reg_range(state, &tmp, reg, 1);
+ }
+
+
+diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c
+index 44cb73f68af6..ddd0d778ad6e 100644
+--- a/drivers/media/dvb-frontends/stv0367.c
++++ b/drivers/media/dvb-frontends/stv0367.c
+@@ -804,7 +804,9 @@ int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
+
+ static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
+ {
+- return stv0367_writeregs(state, reg, &data, 1);
++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++ return stv0367_writeregs(state, reg, &tmp, 1);
+ }
+
+ static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
+diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c
+index 25bdf6e0f963..f0377e2b341b 100644
+--- a/drivers/media/dvb-frontends/stv090x.c
++++ b/drivers/media/dvb-frontends/stv090x.c
+@@ -761,7 +761,9 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
+
+ static int stv090x_write_reg(struct stv090x_state *state, unsigned int reg, u8 data)
+ {
+- return stv090x_write_regs(state, reg, &data, 1);
++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++ return stv090x_write_regs(state, reg, &tmp, 1);
+ }
+
+ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
+diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c
+index e66154e5c1d7..45d14869e7b8 100644
+--- a/drivers/media/dvb-frontends/stv6110x.c
++++ b/drivers/media/dvb-frontends/stv6110x.c
+@@ -97,7 +97,9 @@ static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 da
+
+ static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
+ {
+- return stv6110x_write_regs(stv6110x, reg, &data, 1);
++ u8 tmp = data; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++ return stv6110x_write_regs(stv6110x, reg, &tmp, 1);
+ }
+
+ static int stv6110x_init(struct dvb_frontend *fe)
+diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c
+index ee09ec26c553..b273e4fd8024 100644
+--- a/drivers/media/dvb-frontends/zl10039.c
++++ b/drivers/media/dvb-frontends/zl10039.c
+@@ -138,7 +138,9 @@ static inline int zl10039_writereg(struct zl10039_state *state,
+ const enum zl10039_reg_addr reg,
+ const u8 val)
+ {
+- return zl10039_write(state, reg, &val, 1);
++ const u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
++
++ return zl10039_write(state, reg, &tmp, 1);
+ }
+
+ static int zl10039_init(struct dvb_frontend *fe)
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-085-matroxfb-fix-size-of-memcpy.patch b/patches.kernel.org/4.4.168-085-matroxfb-fix-size-of-memcpy.patch
new file mode 100644
index 0000000000..86eb9ff599
--- /dev/null
+++ b/patches.kernel.org/4.4.168-085-matroxfb-fix-size-of-memcpy.patch
@@ -0,0 +1,37 @@
+From: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
+Date: Thu, 25 Aug 2016 23:14:12 +0530
+Subject: [PATCH] matroxfb: fix size of memcpy
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 59921b239056fb6389a865083284e00ce0518db6
+
+commit 59921b239056fb6389a865083284e00ce0518db6 upstream.
+
+hw->DACreg has a size of 80 bytes and MGADACbpp32 has 21. So when
+memcpy copies MGADACbpp32 to hw->DACreg it copies 80 bytes but
+only 21 bytes are valid.
+
+Signed-off-by: Sudip Mukherjee <sudip.mukherjee@codethink.co.uk>
+Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/video/fbdev/matrox/matroxfb_Ti3026.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/video/fbdev/matrox/matroxfb_Ti3026.c b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
+index 195ad7cac1ba..68fa037d8cbc 100644
+--- a/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
++++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
+@@ -372,7 +372,7 @@ static int Ti3026_init(struct matrox_fb_info *minfo, struct my_timming *m)
+
+ DBG(__func__)
+
+- memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg));
++ memcpy(hw->DACreg, MGADACbpp32, sizeof(MGADACbpp32));
+ switch (minfo->fbcon.var.bits_per_pixel) {
+ case 4: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1; /* or _8_1, they are same */
+ hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-086-staging-speakup-Replace-strncpy-with-memcpy.patch b/patches.kernel.org/4.4.168-086-staging-speakup-Replace-strncpy-with-memcpy.patch
new file mode 100644
index 0000000000..693bb168ac
--- /dev/null
+++ b/patches.kernel.org/4.4.168-086-staging-speakup-Replace-strncpy-with-memcpy.patch
@@ -0,0 +1,61 @@
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Sun, 1 Jul 2018 13:57:24 -0700
+Subject: [PATCH] staging: speakup: Replace strncpy with memcpy
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: fd29edc7232bc19f969e8f463138afc5472b3d5f
+
+commit fd29edc7232bc19f969e8f463138afc5472b3d5f upstream.
+
+gcc 8.1.0 generates the following warnings.
+
+drivers/staging/speakup/kobjects.c: In function 'punc_store':
+drivers/staging/speakup/kobjects.c:522:2: warning:
+ 'strncpy' output truncated before terminating nul
+ copying as many bytes from a string as its length
+drivers/staging/speakup/kobjects.c:504:6: note: length computed here
+
+drivers/staging/speakup/kobjects.c: In function 'synth_store':
+drivers/staging/speakup/kobjects.c:391:2: warning:
+ 'strncpy' output truncated before terminating nul
+ copying as many bytes from a string as its length
+drivers/staging/speakup/kobjects.c:388:8: note: length computed here
+
+Using strncpy() is indeed less than perfect since the length of data to
+be copied has already been determined with strlen(). Replace strncpy()
+with memcpy() to address the warning and optimize the code a little.
+
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/staging/speakup/kobjects.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/staging/speakup/kobjects.c b/drivers/staging/speakup/kobjects.c
+index 06ef26872462..52aed7cfeb24 100644
+--- a/drivers/staging/speakup/kobjects.c
++++ b/drivers/staging/speakup/kobjects.c
+@@ -387,7 +387,7 @@ static ssize_t synth_store(struct kobject *kobj, struct kobj_attribute *attr,
+ len = strlen(buf);
+ if (len < 2 || len > 9)
+ return -EINVAL;
+- strncpy(new_synth_name, buf, len);
++ memcpy(new_synth_name, buf, len);
+ if (new_synth_name[len - 1] == '\n')
+ len--;
+ new_synth_name[len] = '\0';
+@@ -514,7 +514,7 @@ static ssize_t punc_store(struct kobject *kobj, struct kobj_attribute *attr,
+ return -EINVAL;
+ }
+
+- strncpy(punc_buf, buf, x);
++ memcpy(punc_buf, buf, x);
+
+ while (x && punc_buf[x - 1] == '\n')
+ x--;
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-087-rocker-fix-rocker_tlv_put_-functions-for-KASA.patch b/patches.kernel.org/4.4.168-087-rocker-fix-rocker_tlv_put_-functions-for-KASA.patch
new file mode 100644
index 0000000000..bc5a32f2ac
--- /dev/null
+++ b/patches.kernel.org/4.4.168-087-rocker-fix-rocker_tlv_put_-functions-for-KASA.patch
@@ -0,0 +1,93 @@
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Fri, 22 Sep 2017 23:29:18 +0200
+Subject: [PATCH] rocker: fix rocker_tlv_put_* functions for KASAN
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 6098d7ddd62f532f80ee2a4b01aca500a8e4e9e4
+
+commit 6098d7ddd62f532f80ee2a4b01aca500a8e4e9e4 upstream.
+
+Inlining these functions creates lots of stack variables that each take
+64 bytes when KASAN is enabled, leading to this warning about potential
+stack overflow:
+
+drivers/net/ethernet/rocker/rocker_ofdpa.c: In function 'ofdpa_cmd_flow_tbl_add':
+drivers/net/ethernet/rocker/rocker_ofdpa.c:621:1: error: the frame size of 2752 bytes is larger than 1536 bytes [-Werror=frame-larger-than=]
+
+gcc-8 can now consolidate the stack slots itself, but on older versions
+we get the same behavior by using a temporary variable that holds a
+copy of the inline function argument.
+
+Cc: stable@vger.kernel.org
+Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81715
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ drivers/net/ethernet/rocker/rocker.c | 24 ++++++++++++++++++------
+ 1 file changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
+index 3920c3eb6006..df6063faad2e 100644
+--- a/drivers/net/ethernet/rocker/rocker.c
++++ b/drivers/net/ethernet/rocker/rocker.c
+@@ -821,37 +821,49 @@ static int rocker_tlv_put(struct rocker_desc_info *desc_info,
+ static int rocker_tlv_put_u8(struct rocker_desc_info *desc_info,
+ int attrtype, u8 value)
+ {
+- return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &value);
++ u8 tmp = value; /* work around GCC PR81715 */
++
++ return rocker_tlv_put(desc_info, attrtype, sizeof(u8), &tmp);
+ }
+
+ static int rocker_tlv_put_u16(struct rocker_desc_info *desc_info,
+ int attrtype, u16 value)
+ {
+- return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &value);
++ u16 tmp = value;
++
++ return rocker_tlv_put(desc_info, attrtype, sizeof(u16), &tmp);
+ }
+
+ static int rocker_tlv_put_be16(struct rocker_desc_info *desc_info,
+ int attrtype, __be16 value)
+ {
+- return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &value);
++ __be16 tmp = value;
++
++ return rocker_tlv_put(desc_info, attrtype, sizeof(__be16), &tmp);
+ }
+
+ static int rocker_tlv_put_u32(struct rocker_desc_info *desc_info,
+ int attrtype, u32 value)
+ {
+- return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &value);
++ u32 tmp = value;
++
++ return rocker_tlv_put(desc_info, attrtype, sizeof(u32), &tmp);
+ }
+
+ static int rocker_tlv_put_be32(struct rocker_desc_info *desc_info,
+ int attrtype, __be32 value)
+ {
+- return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &value);
++ __be32 tmp = value;
++
++ return rocker_tlv_put(desc_info, attrtype, sizeof(__be32), &tmp);
+ }
+
+ static int rocker_tlv_put_u64(struct rocker_desc_info *desc_info,
+ int attrtype, u64 value)
+ {
+- return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &value);
++ u64 tmp = value;
++
++ return rocker_tlv_put(desc_info, attrtype, sizeof(u64), &tmp);
+ }
+
+ static struct rocker_tlv *
+--
+2.20.1
+
diff --git a/patches.kernel.org/4.4.168-088-selftests-Move-networking-timestamping-from-D.patch b/patches.kernel.org/4.4.168-088-selftests-Move-networking-timestamping-from-D.patch
new file mode 100644
index 0000000000..dac0024ff7
--- /dev/null
+++ b/patches.kernel.org/4.4.168-088-selftests-Move-networking-timestamping-from-D.patch
@@ -0,0 +1,2578 @@
+From: Shuah Khan <shuahkh@osg.samsung.com>
+Date: Thu, 15 Sep 2016 08:36:07 -0600
+Subject: [PATCH] selftests: Move networking/timestamping from Documentation
+References: bnc#1012382
+Patch-mainline: 4.4.168
+Git-commit: 3d2c86e3057995270e08693231039d9d942871f0
+
+commit 3d2c86e3057995270e08693231039d9d942871f0 upstream.
+
+Remove networking from Documentation Makefile to move the test to
+selftests. Update networking/timestamping Makefile to work under
+selftests. These tests will not be run as part of selftests suite
+and will not be included in install targets. They can be built and
+run separately for now.
+
+This is part of the effort to move runnable code from Documentation.
+
+Acked-by: Jonathan Corbet <corbet@lwn.net>
+Signed-off-by: Shuah Khan <shuahkh@osg.samsung.com>
+[ added to 4.4.y stable to remove a build warning - gregkh]
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Jiri Slaby <jslaby@suse.cz>
+---
+ Documentation/Makefile | 3 +-
+ Documentation/networking/Makefile | 1 -
+ .../networking/timestamping/.gitignore | 3 -
+ .../networking/timestamping/Makefile | 14 -
+ .../networking/timestamping/hwtstamp_config.c | 134 -----
+ .../networking/timestamping/timestamping.c | 528 -----------------
+ .../networking/timestamping/txtimestamp.c | 549 ------------------
+ .../networking/timestamping/.gitignore | 3 +
+ .../networking/timestamping/Makefile | 8 +
+ .../networking/timestamping/hwtstamp_config.c | 134 +++++
+ .../networking/timestamping/timestamping.c | 528 +++++++++++++++++
+ .../networking/timestamping/txtimestamp.c | 549 ++++++++++++++++++
+ 12 files changed, 1223 insertions(+), 1231 deletions(-)
+ delete mode 100644 Documentation/networking/Makefile
+ delete mode 100644 Documentation/networking/timestamping/.gitignore
+ delete mode 100644 Documentation/networking/timestamping/Makefile
+ delete mode 100644 Documentation/networking/timestamping/hwtstamp_config.c
+ delete mode 100644 Documentation/networking/timestamping/timestamping.c
+ delete mode 100644 Documentation/networking/timestamping/txtimestamp.c
+ create mode 100644 tools/testing/selftests/networking/timestamping/.gitignore
+ create mode 100644 tools/testing/selftests/networking/timestamping/Makefile
+ create mode 100644 tools/testing/selftests/networking/timestamping/hwtstamp_config.c
+ create mode 100644 tools/testing/selftests/networking/timestamping/timestamping.c
+ create mode 100644 tools/testing/selftests/networking/timestamping/txtimestamp.c
+
+diff --git a/Documentation/Makefile b/Documentation/Makefile
+index fc759598c4c9..59d516b7afcb 100644
+--- a/Documentation/Makefile
++++ b/Documentation/Makefile
+@@ -1,4 +1,3 @@
+ subdir-y := accounting auxdisplay blackfin connector \
+ filesystems filesystems ia64 laptops misc-devices \
+- networking pcmcia prctl ptp spi timers vDSO video4linux \
+- watchdog
++ pcmcia prctl ptp spi timers vDSO video4linux watchdog
+diff --git a/Documentation/networking/Makefile b/Documentation/networking/Makefile
+deleted file mode 100644
+index 4c5d7c485439..000000000000
+--- a/Documentation/networking/Makefile
++++ /dev/null
+@@ -1 +0,0 @@
+-subdir-y := timestamping
+diff --git a/Documentation/networking/timestamping/.gitignore b/Documentation/networking/timestamping/.gitignore
+deleted file mode 100644
+index 9e69e982fb38..000000000000
+--- a/Documentation/networking/timestamping/.gitignore
++++ /dev/null
+@@ -1,3 +0,0 @@
+-timestamping
+-txtimestamp
+-hwtstamp_config
+diff --git a/Documentation/networking/timestamping/Makefile b/Documentation/networking/timestamping/Makefile
+deleted file mode 100644
+index 8c20dfaa4d6e..000000000000
+--- a/Documentation/networking/timestamping/Makefile
++++ /dev/null
+@@ -1,14 +0,0 @@
+-# To compile, from the source root
+-#
+-# make headers_install
+-# make M=documentation
+-
+-# List of programs to build
+-hostprogs-y := hwtstamp_config timestamping txtimestamp
+-
+-# Tell kbuild to always build the programs
+-always := $(hostprogs-y)
+-
+-HOSTCFLAGS_timestamping.o += -I$(objtree)/usr/include
+-HOSTCFLAGS_txtimestamp.o += -I$(objtree)/usr/include
+-HOSTCFLAGS_hwtstamp_config.o += -I$(objtree)/usr/include
+diff --git a/Documentation/networking/timestamping/hwtstamp_config.c b/Documentation/networking/timestamping/hwtstamp_config.c
+deleted file mode 100644
+index e8b685a7f15f..000000000000
+--- a/Documentation/networking/timestamping/hwtstamp_config.c
++++ /dev/null
+@@ -1,134 +0,0 @@
+-/* Test program for SIOC{G,S}HWTSTAMP
+- * Copyright 2013 Solarflare Communications
+- * Author: Ben Hutchings
+- */
+-
+-#include <errno.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-
+-#include <sys/socket.h>
+-#include <sys/ioctl.h>
+-
+-#include <linux/if.h>
+-#include <linux/net_tstamp.h>
+-#include <linux/sockios.h>
+-
+-static int
+-lookup_value(const char **names, int size, const char *name)
+-{
+- int value;
+-
+- for (value = 0; value < size; value++)
+- if (names[value] && strcasecmp(names[value], name) == 0)
+- return value;
+-
+- return -1;
+-}
+-
+-static const char *
+-lookup_name(const char **names, int size, int value)
+-{
+- return (value >= 0 && value < size) ? names[value] : NULL;
+-}
+-
+-static void list_names(FILE *f, const char **names, int size)
+-{
+- int value;
+-
+- for (value = 0; value < size; value++)
+- if (names[value])
+- fprintf(f, " %s\n", names[value]);
+-}
+-
+-static const char *tx_types[] = {
+-#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name
+- TX_TYPE(OFF),
+- TX_TYPE(ON),
+- TX_TYPE(ONESTEP_SYNC)
+-#undef TX_TYPE
+-};
+-#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0])))
+-
+-static const char *rx_filters[] = {
+-#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name
+- RX_FILTER(NONE),
+- RX_FILTER(ALL),
+- RX_FILTER(SOME),
+- RX_FILTER(PTP_V1_L4_EVENT),
+- RX_FILTER(PTP_V1_L4_SYNC),
+- RX_FILTER(PTP_V1_L4_DELAY_REQ),
+- RX_FILTER(PTP_V2_L4_EVENT),
+- RX_FILTER(PTP_V2_L4_SYNC),
+- RX_FILTER(PTP_V2_L4_DELAY_REQ),
+- RX_FILTER(PTP_V2_L2_EVENT),
+- RX_FILTER(PTP_V2_L2_SYNC),
+- RX_FILTER(PTP_V2_L2_DELAY_REQ),
+- RX_FILTER(PTP_V2_EVENT),
+- RX_FILTER(PTP_V2_SYNC),
+- RX_FILTER(PTP_V2_DELAY_REQ),
+-#undef RX_FILTER
+-};
+-#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
+-
+-static void usage(void)
+-{
+- fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n"
+- "tx_type is any of (case-insensitive):\n",
+- stderr);
+- list_names(stderr, tx_types, N_TX_TYPES);
+- fputs("rx_filter is any of (case-insensitive):\n", stderr);
+- list_names(stderr, rx_filters, N_RX_FILTERS);
+-}
+-
+-int main(int argc, char **argv)
+-{
+- struct ifreq ifr;
+- struct hwtstamp_config config;
+- const char *name;
+- int sock;
+-
+- if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) {
+- usage();
+- return 2;
+- }
+-
+- if (argc == 4) {
+- config.flags = 0;
+- config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]);
+- config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]);
+- if (config.tx_type < 0 || config.rx_filter < 0) {
+- usage();
+- return 2;
+- }
+- }
+-
+- sock = socket(AF_INET, SOCK_DGRAM, 0);
+- if (sock < 0) {
+- perror("socket");
+- return 1;
+- }
+-
+- strcpy(ifr.ifr_name, argv[1]);
+- ifr.ifr_data = (caddr_t)&config;
+-
+- if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) {
+- perror("ioctl");
+- return 1;
+- }
+-
+- printf("flags = %#x\n", config.flags);
+- name = lookup_name(tx_types, N_TX_TYPES, config.tx_type);
+- if (name)
+- printf("tx_type = %s\n", name);
+- else
+- printf("tx_type = %d\n", config.tx_type);
+- name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter);
+- if (name)
+- printf("rx_filter = %s\n", name);
+- else
+- printf("rx_filter = %d\n", config.rx_filter);
+-
+- return 0;
+-}
+diff --git a/Documentation/networking/timestamping/timestamping.c b/Documentation/networking/timestamping/timestamping.c
+deleted file mode 100644
+index 5cdfd743447b..000000000000
+--- a/Documentation/networking/timestamping/timestamping.c
++++ /dev/null
+@@ -1,528 +0,0 @@
+-/*
+- * This program demonstrates how the various time stamping features in
+- * the Linux kernel work. It emulates the behavior of a PTP
+- * implementation in stand-alone master mode by sending PTPv1 Sync
+- * multicasts once every second. It looks for similar packets, but
+- * beyond that doesn't actually implement PTP.
+- *
+- * Outgoing packets are time stamped with SO_TIMESTAMPING with or
+- * without hardware support.
+- *
+- * Incoming packets are time stamped with SO_TIMESTAMPING with or
+- * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
+- * SO_TIMESTAMP[NS].
+- *
+- * Copyright (C) 2009 Intel Corporation.
+- * Author: Patrick Ohly <patrick.ohly@intel.com>
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms and conditions of the GNU General Public License,
+- * version 2, as published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+- */
+-
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <errno.h>
+-#include <string.h>
+-
+-#include <sys/time.h>
+-#include <sys/socket.h>
+-#include <sys/select.h>
+-#include <sys/ioctl.h>
+-#include <arpa/inet.h>
+-#include <net/if.h>
+-
+-#include <asm/types.h>
+-#include <linux/net_tstamp.h>
+-#include <linux/errqueue.h>
+-
+-#ifndef SO_TIMESTAMPING
+-# define SO_TIMESTAMPING 37
+-# define SCM_TIMESTAMPING SO_TIMESTAMPING
+-#endif
+-
+-#ifndef SO_TIMESTAMPNS
+-# define SO_TIMESTAMPNS 35
+-#endif
+-
+-#ifndef SIOCGSTAMPNS
+-# define SIOCGSTAMPNS 0x8907
+-#endif
+-
+-#ifndef SIOCSHWTSTAMP
+-# define SIOCSHWTSTAMP 0x89b0
+-#endif
+-
+-static void usage(const char *error)
+-{
+- if (error)
+- printf("invalid option: %s\n", error);
+- printf("timestamping interface option*\n\n"
+- "Options:\n"
+- " IP_MULTICAST_LOOP - looping outgoing multicasts\n"
+- " SO_TIMESTAMP - normal software time stamping, ms resolution\n"
+- " SO_TIMESTAMPNS - more accurate software time stamping\n"
+- " SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
+- " SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
+- " SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
+- " SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
+- " SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
+- " SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
+- " SIOCGSTAMP - check last socket time stamp\n"
+- " SIOCGSTAMPNS - more accurate socket time stamp\n");
+- exit(1);
+-}
+-
+-static void bail(const char *error)
+-{
+- printf("%s: %s\n", error, strerror(errno));
+- exit(1);
+-}
+-
+-static const unsigned char sync[] = {
+- 0x00, 0x01, 0x00, 0x01,
+- 0x5f, 0x44, 0x46, 0x4c,
+- 0x54, 0x00, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x00,
+- 0x01, 0x01,
+-
+- /* fake uuid */
+- 0x00, 0x01,
+- 0x02, 0x03, 0x04, 0x05,
+-
+- 0x00, 0x01, 0x00, 0x37,
+- 0x00, 0x00, 0x00, 0x08,
+- 0x00, 0x00, 0x00, 0x00,
+- 0x49, 0x05, 0xcd, 0x01,
+- 0x29, 0xb1, 0x8d, 0xb0,
+- 0x00, 0x00, 0x00, 0x00,
+- 0x00, 0x01,
+-
+- /* fake uuid */
+- 0x00, 0x01,
+- 0x02, 0x03, 0x04, 0x05,
+-
+- 0x00, 0x00, 0x00, 0x37,
+- 0x00, 0x00, 0x00, 0x04,
+- 0x44, 0x46, 0x4c, 0x54,
+- 0x00, 0x00, 0xf0, 0x60,
+- 0x00, 0x01, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x01,
+- 0x00, 0x00, 0xf0, 0x60,
+- 0x00, 0x00, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x04,
+- 0x44, 0x46, 0x4c, 0x54,
+- 0x00, 0x01,
+-
+- /* fake uuid */
+- 0x00, 0x01,
+- 0x02, 0x03, 0x04, 0x05,
+-
+- 0x00, 0x00, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x00,
+- 0x00, 0x00, 0x00, 0x00
+-};
+-
+-static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
+-{
+- struct timeval now;
+- int res;
+-
+- res = sendto(sock, sync, sizeof(sync), 0,
+- addr, addr_len);
+- gettimeofday(&now, 0);
+- if (res < 0)
+- printf("%s: %s\n", "send", strerror(errno));
+- else
+- printf("%ld.%06ld: sent %d bytes\n",
+- (long)now.tv_sec, (long)now.tv_usec,
+- res);
+-}
+-
+-static void printpacket(struct msghdr *msg, int res,
+- char *data,
+- int sock, int recvmsg_flags,
+- int siocgstamp, int siocgstampns)
+-{
+- struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
+- struct cmsghdr *cmsg;
+- struct timeval tv;
+- struct timespec ts;
+- struct timeval now;
+-
+- gettimeofday(&now, 0);
+-
+- printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
+- (long)now.tv_sec, (long)now.tv_usec,
+- (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+- res,
+- inet_ntoa(from_addr->sin_addr),
+- msg->msg_controllen);
+- for (cmsg = CMSG_FIRSTHDR(msg);
+- cmsg;
+- cmsg = CMSG_NXTHDR(msg, cmsg)) {
+- printf(" cmsg len %zu: ", cmsg->cmsg_len);
+- switch (cmsg->cmsg_level) {
+- case SOL_SOCKET:
+- printf("SOL_SOCKET ");
+- switch (cmsg->cmsg_type) {
+- case SO_TIMESTAMP: {
+- struct timeval *stamp =
+- (struct timeval *)CMSG_DATA(cmsg);
+- printf("SO_TIMESTAMP %ld.%06ld",
+- (long)stamp->tv_sec,
+- (long)stamp->tv_usec);
+- break;
+- }
+- case SO_TIMESTAMPNS: {
+- struct timespec *stamp =
+- (struct timespec *)CMSG_DATA(cmsg);
+- printf("SO_TIMESTAMPNS %ld.%09ld",
+- (long)stamp->tv_sec,
+- (long)stamp->tv_nsec);
+- break;
+- }
+- case SO_TIMESTAMPING: {
+- struct timespec *stamp =
+- (struct timespec *)CMSG_DATA(cmsg);
+- printf("SO_TIMESTAMPING ");
+- printf("SW %ld.%09ld ",
+- (long)stamp->tv_sec,
+- (long)stamp->tv_nsec);
+- stamp++;
+- /* skip deprecated HW transformed */
+- stamp++;
+- printf("HW raw %ld.%09ld",
+- (long)stamp->tv_sec,
+- (long)stamp->tv_nsec);
+- break;
+- }
+- default:
+- printf("type %d", cmsg->cmsg_type);
+- break;
+- }
+- break;
+- case IPPROTO_IP:
+- printf("IPPROTO_IP ");
+- switch (cmsg->cmsg_type) {
+- case IP_RECVERR: {
+- struct sock_extended_err *err =
+- (struct sock_extended_err *)CMSG_DATA(cmsg);
+- printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
+- strerror(err->ee_errno),
+- err->ee_origin,
+-#ifdef SO_EE_ORIGIN_TIMESTAMPING
+- err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
+- "bounced packet" : "unexpected origin"
+-#else
+- "probably SO_EE_ORIGIN_TIMESTAMPING"
+-#endif
+- );
+- if (res < sizeof(sync))
+- printf(" => truncated data?!");
+- else if (!memcmp(sync, data + res - sizeof(sync),
+- sizeof(sync)))
+- printf(" => GOT OUR DATA BACK (HURRAY!)");
+- break;
+- }
+- case IP_PKTINFO: {
+- struct in_pktinfo *pktinfo =
+- (struct in_pktinfo *)CMSG_DATA(cmsg);
+- printf("IP_PKTINFO interface index %u",
+- pktinfo->ipi_ifindex);
+- break;
+- }
+- default:
+- printf("type %d", cmsg->cmsg_type);
+- break;
+- }
+- break;
+- default:
+- printf("level %d type %d",
+- cmsg->cmsg_level,
+- cmsg->cmsg_type);
+- break;
+- }
+- printf("\n");
+- }
+-
+- if (siocgstamp) {
+- if (ioctl(sock, SIOCGSTAMP, &tv))
+- printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno));
+- else
+- printf("SIOCGSTAMP %ld.%06ld\n",
+- (long)tv.tv_sec,
+- (long)tv.tv_usec);
+- }
+- if (siocgstampns) {
+- if (ioctl(sock, SIOCGSTAMPNS, &ts))
+- printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
+- else
+- printf("SIOCGSTAMPNS %ld.%09ld\n",
+- (long)ts.tv_sec,
+- (long)ts.tv_nsec);
+- }
+-}
+-
+-static void recvpacket(int sock, int recvmsg_flags,
+- int siocgstamp, int siocgstampns)
+-{
+- char data[256];
+- struct msghdr msg;
+- struct iovec entry;
+- struct sockaddr_in from_addr;
+- struct {
+- struct cmsghdr cm;
+- char control[512];
+- } control;
+- int res;
+-
+- memset(&msg, 0, sizeof(msg));
+- msg.msg_iov = &entry;
+- msg.msg_iovlen = 1;
+- entry.iov_base = data;
+- entry.iov_len = sizeof(data);
+- msg.msg_name = (caddr_t)&from_addr;
+- msg.msg_namelen = sizeof(from_addr);
+- msg.msg_control = &control;
+- msg.msg_controllen = sizeof(control);
+-
+- res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
+- if (res < 0) {
+- printf("%s %s: %s\n",
+- "recvmsg",
+- (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
+- strerror(errno));
+- } else {
+- printpacket(&msg, res, data,
+- sock, recvmsg_flags,
+- siocgstamp, siocgstampns);
+- }
+-}
+-
+-int main(int argc, char **argv)
+-{
+- int so_timestamping_flags = 0;
+- int so_timestamp = 0;
+- int so_timestampns = 0;
+- int siocgstamp = 0;
+- int siocgstampns = 0;
+- int ip_multicast_loop = 0;
+- char *interface;
+- int i;
+- int enabled = 1;
+- int sock;
+- struct ifreq device;
+- struct ifreq hwtstamp;
+- struct hwtstamp_config hwconfig, hwconfig_requested;
+- struct sockaddr_in addr;
+- struct ip_mreq imr;
+- struct in_addr iaddr;
+- int val;
+- socklen_t len;
+- struct timeval next;
+-
+- if (argc < 2)
+- usage(0);
+- interface = argv[1];
+-
+- for (i = 2; i < argc; i++) {
+- if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
+- so_timestamp = 1;
+- else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
+- so_timestampns = 1;
+- else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
+- siocgstamp = 1;
+- else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
+- siocgstampns = 1;
+- else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
+- ip_multicast_loop = 1;
+- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
+- so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
+- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
+- so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
+- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
+- so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
+- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
+- so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
+- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
+- so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
+- else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
+- so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
+- else
+- usage(argv[i]);
+- }
+-
+- sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+- if (sock < 0)
+- bail("socket");
+-
+- memset(&device, 0, sizeof(device));
+- strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
+- if (ioctl(sock, SIOCGIFADDR, &device) < 0)
+- bail("getting interface IP address");
+-
+- memset(&hwtstamp, 0, sizeof(hwtstamp));
+- strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
+- hwtstamp.ifr_data = (void *)&hwconfig;
+- memset(&hwconfig, 0, sizeof(hwconfig));
+- hwconfig.tx_type =
+- (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
+- HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
+- hwconfig.rx_filter =
+- (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
+- HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
+- hwconfig_requested = hwconfig;
+- if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
+- if ((errno == EINVAL || errno == ENOTSUP) &&
+- hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
+- hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
+- printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
+- else
+- bail("SIOCSHWTSTAMP");
+- }
+- printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
+- hwconfig_requested.tx_type, hwconfig.tx_type,
+- hwconfig_requested.rx_filter, hwconfig.rx_filter);
+-
+- /* bind to PTP port */
+- addr.sin_family = AF_INET;
+- addr.sin_addr.s_addr = htonl(INADDR_ANY);
+- addr.sin_port = htons(319 /* PTP event port */);
+- if (bind(sock,
+- (struct sockaddr *)&addr,
+- sizeof(struct sockaddr_in)) < 0)
+- bail("bind");
+-
+- /* set multicast group for outgoing packets */
+- inet_aton("224.0.1.130", &iaddr); /* alternate PTP domain 1 */
+- addr.sin_addr = iaddr;
+- imr.imr_multiaddr.s_addr = iaddr.s_addr;
+- imr.imr_interface.s_addr =
+- ((struct sockaddr_in *)&device.ifr_addr)->sin_addr.s_addr;
+- if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF,
+- &imr.imr_interface.s_addr, sizeof(struct in_addr)) < 0)
+- bail("set multicast");
+-
+- /* join multicast group, loop our own packet */
+- if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+- &imr, sizeof(struct ip_mreq)) < 0)
+- bail("join multicast group");
+-
+- if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP,
+- &ip_multicast_loop, sizeof(enabled)) < 0) {
+- bail("loop multicast");
+- }
+-
+- /* set socket options for time stamping */
+- if (so_timestamp &&
+- setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP,
+- &enabled, sizeof(enabled)) < 0)
+- bail("setsockopt SO_TIMESTAMP");
+-
+- if (so_timestampns &&
+- setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS,
+- &enabled, sizeof(enabled)) < 0)
+- bail("setsockopt SO_TIMESTAMPNS");
+-
+- if (so_timestamping_flags &&
+- setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING,
+- &so_timestamping_flags,
+- sizeof(so_timestamping_flags)) < 0)
+- bail("setsockopt SO_TIMESTAMPING");
+-
+- /* request IP_PKTINFO for debugging purposes */
+- if (setsockopt(sock, SOL_IP, IP_PKTINFO,
+- &enabled, sizeof(enabled)) < 0)
+- printf("%s: %s\n", "setsockopt IP_PKTINFO", strerror(errno));
+-
+- /* verify socket options */
+- len = sizeof(val);
+- if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, &len) < 0)
+- printf("%s: %s\n", "getsockopt SO_TIMESTAMP", strerror(errno));
+- else
+- printf("SO_TIMESTAMP %d\n", val);
+-
+- if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPNS, &val, &len) < 0)
+- printf("%s: %s\n", "getsockopt SO_TIMESTAMPNS",
+- strerror(errno));
+- else
+- printf("SO_TIMESTAMPNS %d\n", val);
+-
+- if (getsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, &len) < 0) {
+- printf("%s: %s\n", "getsockopt SO_TIMESTAMPING",
+- strerror(errno));
+- } else {
+- printf("SO_TIMESTAMPING %d\n", val);
+- if (val != so_timestamping_flags)
+- printf(" not the expected value %d\n",
+- so_timestamping_flags);
+- }
+-
+- /* send packets forever every five seconds */
+- gettimeofday(&next, 0);
+- next.tv_sec = (next.tv_sec + 1) / 5 * 5;
+- next.tv_usec = 0;
+- while (1) {
+- struct timeval now;
+- struct timeval delta;
+- long delta_us;
+- int res;
+- fd_set readfs, errorfs;
+-
+- gettimeofday(&now, 0);
+- delta_us = (long)(next.tv_sec - now.tv_sec) * 1000000 +
+- (long)(next.tv_usec - now.tv_usec);
+- if (delta_us > 0) {
+- /* continue waiting for timeout or data */
+- delta.tv_sec = delta_us / 1000000;
+- delta.tv_usec = delta_us % 1000000;
+-
+- FD_ZERO(&readfs);
+- FD_ZERO(&errorfs);
+- FD_SET(sock, &readfs);
+- FD_SET(sock, &errorfs);
+- printf("%ld.%06ld: select %ldus\n",
+- (long)now.tv_sec, (long)now.tv_usec,
+- delta_us);
+- res = select(sock + 1, &readfs, 0, &errorfs, &delta);
+- gettimeofday(&now, 0);
+- printf("%ld.%06ld: select returned: %d, %s\n",
+- (long)now.tv_sec, (long)now.tv_usec,
+- res,
+- res < 0 ? strerror(errno) : "success");
+- if (res > 0) {
+- if (FD_ISSET(sock, &readfs))
+- printf("ready for reading\n");
+- if (FD_ISSET(sock, &errorfs))
+- printf("has error\n");
+- recvpacket(sock, 0,
+- siocgstamp,
+- siocgstampns);
+- recvpacket(sock, MSG_ERRQUEUE,
+- siocgstamp,
+- siocgstampns);
+- }
+- } else {
+- /* write one packet */
+- sendpacket(sock,
+- (struct sockaddr *)&addr,
+- sizeof(addr));
+- next.tv_sec += 5;
+- continue;
+- }
+- }
+-
+- return 0;
+-}
+diff --git a/Documentation/networking/timestamping/txtimestamp.c b/Documentation/networking/timestamping/txtimestamp.c
+deleted file mode 100644
+index 5df07047ca86..000000000000
+--- a/Documentation/networking/timestamping/txtimestamp.c
++++ /dev/null
+@@ -1,549 +0,0 @@
+-/*
+- * Copyright 2014 Google Inc.
+- * Author: willemb@google.com (Willem de Bruijn)
+- *
+- * Test software tx timestamping, including
+- *
+- * - SCHED, SND and ACK timestamps
+- * - RAW, UDP and TCP
+- * - IPv4 and IPv6
+- * - various packet sizes (to test GSO and TSO)
+- *
+- * Consult the command line arguments for help on running
+- * the various testcases.
+- *
+- * This test requires a dummy TCP server.
+- * A simple `nc6 [-u] -l -p $DESTPORT` will do
+- *
+- *
+- * This program is free software; you can redistribute it and/or modify it
+- * under the terms and conditions of the GNU General Public License,
+- * version 2, as published by the Free Software Foundation.
+- *
+- * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+- */
+-
+-#define _GNU_SOURCE
+-
+-#include <arpa/inet.h>
+-#include <asm/types.h>
+-#include <error.h>
+-#include <errno.h>
+-#include <inttypes.h>
+-#include <linux/errqueue.h>
+-#include <linux/if_ether.h>
+-#include <linux/net_tstamp.h>
+-#include <netdb.h>
+-#include <net/if.h>
+-#include <netinet/in.h>
+-#include <netinet/ip.h>
+-#include <netinet/udp.h>
+-#include <netinet/tcp.h>
+-#include <netpacket/packet.h>
+-#include <poll.h>
+-#include <stdarg.h>
+-#include <stdbool.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <sys/ioctl.h>
+-#include <sys/select.h>
+-#include <sys/socket.h>
+-#include <sys/time.h>
+-#include <sys/types.h>
+-#include <time.h>
+-#include <unistd.h>
+-
+-/* command line parameters */
+-static int cfg_proto = SOCK_STREAM;
+-static int cfg_ipproto = IPPROTO_TCP;
+-static int cfg_num_pkts = 4;
+-static int do_ipv4 = 1;
+-static int do_ipv6 = 1;
+-static int cfg_payload_len = 10;
+-static bool cfg_show_payload;
+-static bool cfg_do_pktinfo;
+-static bool cfg_loop_nodata;
+-static uint16_t dest_port = 9000;
+-
+-static struct sockaddr_in daddr;
+-static struct sockaddr_in6 daddr6;
+-static struct timespec ts_prev;
+-
+-static void __print_timestamp(const char *name, struct timespec *cur,
+- uint32_t key, int payload_len)
+-{
+- if (!(cur->tv_sec | cur->tv_nsec))
+- return;
+-
+- fprintf(stderr, " %s: %lu s %lu us (seq=%u, len=%u)",
+- name, cur->tv_sec, cur->tv_nsec / 1000,
+- key, payload_len);
+-
+- if ((ts_prev.tv_sec | ts_prev.tv_nsec)) {
+- int64_t cur_ms, prev_ms;
+-
+- cur_ms = (long) cur->tv_sec * 1000 * 1000;
+- cur_ms += cur->tv_nsec / 1000;
+-
+- prev_ms = (long) ts_prev.tv_sec * 1000 * 1000;
+- prev_ms += ts_prev.tv_nsec / 1000;
+-
+- fprintf(stderr, " (%+" PRId64 " us)", cur_ms - prev_ms);
+- }
+-
+- ts_prev = *cur;
+- fprintf(stderr, "\n");
+-}
+-
+-static void print_timestamp_usr(void)
+-{
+- struct timespec ts;
+- struct timeval tv; /* avoid dependency on -lrt */
+-
+- gettimeofday(&tv, NULL);
+- ts.tv_sec = tv.tv_sec;
+- ts.tv_nsec = tv.tv_usec * 1000;
+-
+- __print_timestamp(" USR", &ts, 0, 0);
+-}
+-
+-static void print_timestamp(struct scm_timestamping *tss, int tstype,
+- int tskey, int payload_len)
+-{
+- const char *tsname;
+-
+- switch (tstype) {
+- case SCM_TSTAMP_SCHED:
+- tsname = " ENQ";
+- break;
+- case SCM_TSTAMP_SND:
+- tsname = " SND";
+- break;
+- case SCM_TSTAMP_ACK:
+- tsname = " ACK";
+- break;
+- default:
+- error(1, 0, "unknown timestamp type: %u",
+- tstype);
+- }
+- __print_timestamp(tsname, &tss->ts[0], tskey, payload_len);
+-}
+-
+-/* TODO: convert to check_and_print payload once API is stable */
+-static void print_payload(char *data, int len)
+-{
+- int i;
+-
+- if (!len)
+- return;
+-
+- if (len > 70)
+- len = 70;
+-
+- fprintf(stderr, "payload: ");
+- for (i = 0; i < len; i++)
+- fprintf(stderr, "%02hhx ", data[i]);
+- fprintf(stderr, "\n");
+-}
+-
+-static void print_pktinfo(int family, int ifindex, void *saddr, void *daddr)
+-{
+- char sa[INET6_ADDRSTRLEN], da[INET6_ADDRSTRLEN];
+-
+- fprintf(stderr, " pktinfo: ifindex=%u src=%s dst=%s\n",
+- ifindex,
+- saddr ? inet_ntop(family, saddr, sa, sizeof(sa)) : "unknown",
+- daddr ? inet_ntop(family, daddr, da, sizeof(da)) : "unknown");
+-}
+-
+-static void __poll(int fd)
+-{
+- struct pollfd pollfd;
+- int ret;
+-
+- memset(&pollfd, 0, sizeof(pollfd));
+- pollfd.fd = fd;
+- ret = poll(&pollfd, 1, 100);
+- if (ret != 1)
+- error(1, errno, "poll");
+-}
+-
+-static void __recv_errmsg_cmsg(struct msghdr *msg, int payload_len)
+-{
+- struct sock_extended_err *serr = NULL;
+- struct scm_timestamping *tss = NULL;
+- struct cmsghdr *cm;
+- int batch = 0;
+-
+- for (cm = CMSG_FIRSTHDR(msg);
+- cm && cm->cmsg_len;
+- cm = CMSG_NXTHDR(msg, cm)) {
+- if (cm->cmsg_level == SOL_SOCKET &&
+- cm->cmsg_type == SCM_TIMESTAMPING) {
+- tss = (void *) CMSG_DATA(cm);
+- } else if ((cm->cmsg_level == SOL_IP &&
+- cm->cmsg_type == IP_RECVERR) ||
+- (cm->cmsg_level == SOL_IPV6 &&
+- cm->cmsg_type == IPV6_RECVERR)) {
+- serr = (void *) CMSG_DATA(cm);
+- if (serr->ee_errno != ENOMSG ||
+- serr->ee_origin != SO_EE_ORIGIN_TIMESTAMPING) {
+- fprintf(stderr, "unknown ip error %d %d\n",
+- serr->ee_errno,
+- serr->ee_origin);
+- serr = NULL;
+- }
+- } else if (cm->cmsg_level == SOL_IP &&
+- cm->cmsg_type == IP_PKTINFO) {
+- struct in_pktinfo *info = (void *) CMSG_DATA(cm);
+- print_pktinfo(AF_INET, info->ipi_ifindex,
+- &info->ipi_spec_dst, &info->ipi_addr);
+- } else if (cm->cmsg_level == SOL_IPV6 &&
+- cm->cmsg_type == IPV6_PKTINFO) {
+- struct in6_pktinfo *info6 = (void *) CMSG_DATA(cm);
+- print_pktinfo(AF_INET6, info6->ipi6_ifindex,
+- NULL, &info6->ipi6_addr);
+- } else
+- fprintf(stderr, "unknown cmsg %d,%d\n",
+- cm->cmsg_level, cm->cmsg_type);
+-
+- if (serr && tss) {
+- print_timestamp(tss, serr->ee_info, serr->ee_data,
+- payload_len);
+- serr = NULL;
+- tss = NULL;
+- batch++;
+- }
+- }
+-
+- if (batch > 1)
+- fprintf(stderr, "batched %d timestamps\n", batch);
+-}
+-
+-static int recv_errmsg(int fd)
+-{
+- static char ctrl[1024 /* overprovision*/];
+- static struct msghdr msg;
+- struct iovec entry;
+- static char *data;
+- int ret = 0;
+-
+- data = malloc(cfg_payload_len);
+- if (!data)
+- error(1, 0, "malloc");
+-
+- memset(&msg, 0, sizeof(msg));
+- memset(&entry, 0, sizeof(entry));
+- memset(ctrl, 0, sizeof(ctrl));
+-
+- entry.iov_base = data;
+- entry.iov_len = cfg_payload_len;
+- msg.msg_iov = &entry;
+- msg.msg_iovlen = 1;
+- msg.msg_name = NULL;
+- msg.msg_namelen = 0;
+- msg.msg_control = ctrl;
+- msg.msg_controllen = sizeof(ctrl);
+-
+- ret = recvmsg(fd, &msg, MSG_ERRQUEUE);
+- if (ret == -1 && errno != EAGAIN)
+- error(1, errno, "recvmsg");
+-
+- if (ret >= 0) {
+- __recv_errmsg_cmsg(&msg, ret);
+- if (cfg_show_payload)
+- print_payload(data, cfg_payload_len);
+- }
+-
+- free(data);
+- return ret == -1;
+-}
+-
+-static void do_test(int family, unsigned int opt)
+-{
+- char *buf;
+- int fd, i, val = 1, total_len;
+-
+- if (family == AF_INET6 && cfg_proto != SOCK_STREAM) {
+- /* due to lack of checksum generation code */
+- fprintf(stderr, "test: skipping datagram over IPv6\n");
+- return;
+- }
+-
+- total_len = cfg_payload_len;
+- if (cfg_proto == SOCK_RAW) {
+- total_len += sizeof(struct udphdr);
+- if (cfg_ipproto == IPPROTO_RAW)
+- total_len += sizeof(struct iphdr);
+- }
+-
+- buf = malloc(total_len);
+- if (!buf)
+- error(1, 0, "malloc");
+-
+- fd = socket(family, cfg_proto, cfg_ipproto);
+- if (fd < 0)
+- error(1, errno, "socket");
+-
+- if (cfg_proto == SOCK_STREAM) {
+- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
+- (char*) &val, sizeof(val)))
+- error(1, 0, "setsockopt no nagle");
+-
+- if (family == PF_INET) {
+- if (connect(fd, (void *) &daddr, sizeof(daddr)))
+- error(1, errno, "connect ipv4");
+- } else {
+- if (connect(fd, (void *) &daddr6, sizeof(daddr6)))
+- error(1, errno, "connect ipv6");
+- }
+- }
+-
+- if (cfg_do_pktinfo) {
+- if (family == AF_INET6) {
+- if (setsockopt(fd, SOL_IPV6, IPV6_RECVPKTINFO,
+- &val, sizeof(val)))
+- error(1, errno, "setsockopt pktinfo ipv6");
+- } else {
+- if (setsockopt(fd, SOL_IP, IP_PKTINFO,
+- &val, sizeof(val)))
+- error(1, errno, "setsockopt pktinfo ipv4");
+- }
+- }
+-
+- opt |= SOF_TIMESTAMPING_SOFTWARE |
+- SOF_TIMESTAMPING_OPT_CMSG |
+- SOF_TIMESTAMPING_OPT_ID;
+- if (cfg_loop_nodata)
+- opt |= SOF_TIMESTAMPING_OPT_TSONLY;
+-
+- if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING,
+- (char *) &opt, sizeof(opt)))
+- error(1, 0, "setsockopt timestamping");
+-
+- for (i = 0; i < cfg_num_pkts; i++) {
+- memset(&ts_prev, 0, sizeof(ts_prev));
+- memset(buf, 'a' + i, total_len);
+-
+- if (cfg_proto == SOCK_RAW) {
+- struct udphdr *udph;
+- int off = 0;
+-
+- if (cfg_ipproto == IPPROTO_RAW) {
+- struct iphdr *iph = (void *) buf;
+-
+- memset(iph, 0, sizeof(*iph));
+- iph->ihl = 5;
+- iph->version = 4;
+- iph->ttl = 2;
+- iph->daddr = daddr.sin_addr.s_addr;
+- iph->protocol = IPPROTO_UDP;
+- /* kernel writes saddr, csum, len */
+-
+- off = sizeof(*iph);
+- }
+-
+- udph = (void *) buf + off;
+- udph->source = ntohs(9000); /* random spoof */
+- udph->dest = ntohs(dest_port);
+- udph->len = ntohs(sizeof(*udph) + cfg_payload_len);
+- udph->check = 0; /* not allowed for IPv6 */
+- }
+-
+- print_timestamp_usr();
+- if (cfg_proto != SOCK_STREAM) {
+- if (family == PF_INET)
+- val = sendto(fd, buf, total_len, 0, (void *) &daddr, sizeof(daddr));
+- else
+- val = sendto(fd, buf, total_len, 0, (void *) &daddr6, sizeof(daddr6));
+- } else {
+- val = send(fd, buf, cfg_payload_len, 0);
+- }
+- if (val != total_len)
+- error(1, errno, "send");
+-
+- /* wait for all errors to be queued, else ACKs arrive OOO */
+- usleep(50 * 1000);
+-
+- __poll(fd);
+-
+- while (!recv_errmsg(fd)) {}
+- }
+-
+- if (close(fd))
+- error(1, errno, "close");
+-
+- free(buf);
+- usleep(400 * 1000);
+-}
+-
+-static void __attribute__((noreturn)) usage(const char *filepath)
+-{
+- fprintf(stderr, "\nUsage: %s [options] hostname\n"
+- "\nwhere options are:\n"
+- " -4: only IPv4\n"
+- " -6: only IPv6\n"
+- " -h: show this message\n"
+- " -I: request PKTINFO\n"
+- " -l N: send N bytes at a time\n"
+- " -n: set no-payload option\n"
+- " -r: use raw\n"
+- " -R: use raw (IP_HDRINCL)\n"
+- " -p N: connect to port N\n"
+- " -u: use udp\n"
+- " -x: show payload (up to 70 bytes)\n",
+- filepath);
+- exit(1);
+-}
+-
+-static void parse_opt(int argc, char **argv)
+-{
+- int proto_count = 0;
+- char c;
+-
+- while ((c = getopt(argc, argv, "46hIl:np:rRux")) != -1) {
+- switch (c) {
+- case '4':
+- do_ipv6 = 0;
+- break;
+- case '6':
+- do_ipv4 = 0;
+- break;
+- case 'I':
+- cfg_do_pktinfo = true;
+- break;
+- case 'n':
+- cfg_loop_nodata = true;
+- break;
+- case 'r':
+- proto_count++;
+- cfg_proto = SOCK_RAW;
+- cfg_ipproto = IPPROTO_UDP;
+- break;
+- case 'R':
+- proto_count++;
+- cfg_proto = SOCK_RAW;
+- cfg_ipproto = IPPROTO_RAW;
+- break;
+- case 'u':
+- proto_count++;
+- cfg_proto = SOCK_DGRAM;
+- cfg_ipproto = IPPROTO_UDP;
+- break;
+- case 'l':
+- cfg_payload_len = strtoul(optarg, NULL, 10);
+- break;
+- case 'p':
+- dest_port = strtoul(optarg, NULL, 10);
+- break;
+- case 'x':
+- cfg_show_payload = true;
+- break;
+- case 'h':
+- default:
+- usage(argv[0]);
+- }
+- }
+-
+- if (!cfg_payload_len)
+- error(1, 0, "payload may not be nonzero");
+- if (cfg_proto != SOCK_STREAM && cfg_payload_len > 1472)
+- error(1, 0, "udp packet might exceed expected MTU");
+- if (!do_ipv4 && !do_ipv6)
+- error(1, 0, "pass -4 or -6, not both");
+- if (proto_count > 1)
+- error(1, 0, "pass -r, -R or -u, not multiple");
+-
+- if (optind != argc - 1)
+- error(1, 0, "missing required hostname argument");
+-}
+-
+-static void resolve_hostname(const char *hostname)
+-{
+- struct addrinfo *addrs, *cur;
+- int have_ipv4 = 0, have_ipv6 = 0;
+-
+- if (getaddrinfo(hostname, NULL, NULL, &addrs))
+- error(1, errno, "getaddrinfo");
+-
+- cur = addrs;
+- while (cur && !have_ipv4 && !have_ipv6) {
+- if (!have_ipv4 && cur->ai_family == AF_INET) {
+- memcpy(&daddr, cur->ai_addr, sizeof(daddr));
+- daddr.sin_port = htons(dest_port);
+- have_ipv4 = 1;
+- }
+- else if (!have_ipv6 && cur->ai_family == AF_INET6) {
+- memcpy(&daddr6, cur->ai_addr, sizeof(daddr6));
+- daddr6.sin6_port = htons(dest_port);
+- have_ipv6 = 1;
+- }
+- cur = cur->ai_next;
+- }
+- if (addrs)
+- freeaddrinfo(addrs);
+-
+- do_ipv4 &= have_ipv4;
+- do_ipv6 &= have_ipv6;
+-}
+-
+-static void do_main(int family)
+-{
+- fprintf(stderr, "family: %s\n",
+- family == PF_INET ? "INET" : "INET6");
+-
+- fprintf(stderr, "test SND\n");
+- do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE);
+-
+- fprintf(stderr, "test ENQ\n");
+- do_test(family, SOF_TIMESTAMPING_TX_SCHED);
+-
+- fprintf(stderr, "test ENQ + SND\n");
+- do_test(family, SOF_TIMESTAMPING_TX_SCHED |
+- SOF_TIMESTAMPING_TX_SOFTWARE);
+-
+- if (cfg_proto == SOCK_STREAM) {
+- fprintf(stderr, "\ntest ACK\n");
+- do_test(family, SOF_TIMESTAMPING_TX_ACK);
+-
+- fprintf(stderr, "\ntest SND + ACK\n");
+- do_test(family, SOF_TIMESTAMPING_TX_SOFTWARE |
+- SOF_TIMESTAMPING_TX_ACK);
+-
+- fprintf(stderr, "\ntest ENQ + SND + ACK\n");
+- do_test(family, SOF_TIMESTAMPING_TX_SCHED |
+- SOF_TIMESTAMPING_TX_SOFTWARE |
+- SOF_TIMESTAMPING_TX_ACK);
+- }
+-}
+-
+-const char *sock_names[] = { NULL, "TCP", "UDP", "RAW" };
+-
+-int main(int argc, char **argv)
+-{
+- if (argc == 1)
+- usage(argv[0]);
+-
+- parse_opt(argc, argv);
+- resolve_hostname(argv[argc - 1]);
+-
+- fprintf(stderr, "protocol: %s\n", sock_names[cfg_proto]);
+- fprintf(stderr, "payload: %u\n", cfg_payload_len);
+- fprintf(stderr, "server port: %u\n", dest_port);
+- fprintf(stderr, "\n");
+-
+- if (do_ipv4)
+- do_main(PF_INET);
+- if (do_ipv6)
+- do_main(PF_INET6);
+-
+- return 0;
+-}
+diff --git a/tools/testing/selftests/networking/timestamping/.gitignore b/tools/testing/selftests/networking/timestamping/.gitignore
+new file mode 100644
+index 000000000000..9e69e982fb38
+--- /dev/null
++++ b/tools/testing/selftests/networking/timestamping/.gitignore
+@@ -0,0 +1,3 @@
++timestamping
++txtimestamp
++hwtstamp_config
+diff --git a/tools/testing/selftests/networking/timestamping/Makefile b/tools/testing/selftests/networking/timestamping/Makefile
+new file mode 100644
+index 000000000000..ccbb9edbbbb9
+--- /dev/null
++++ b/tools/testing/selftests/networking/timestamping/Makefile
+@@ -0,0 +1,8 @@
++TEST_PROGS := hwtstamp_config timestamping txtimestamp
++
++all: $(TEST_PROGS)
++
++include ../../lib.mk
++
++clean:
++ rm -fr $(TEST_PROGS)
+diff --git a/tools/testing/selftests/networking/timestamping/hwtstamp_config.c b/tools/testing/selftests/networking/timestamping/hwtstamp_config.c
+new file mode 100644
+index 000000000000..e8b685a7f15f
+--- /dev/null
++++ b/tools/testing/selftests/networking/timestamping/hwtstamp_config.c
+@@ -0,0 +1,134 @@
++/* Test program for SIOC{G,S}HWTSTAMP
++ * Copyright 2013 Solarflare Communications
++ * Author: Ben Hutchings
++ */
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include <sys/socket.h>
++#include <sys/ioctl.h>
++
++#include <linux/if.h>
++#include <linux/net_tstamp.h>
++#include <linux/sockios.h>
++
++static int
++lookup_value(const char **names, int size, const char *name)
++{
++ int value;
++
++ for (value = 0; value < size; value++)
++ if (names[value] && strcasecmp(names[value], name) == 0)
++ return value;
++
++ return -1;
++}
++
++static const char *
++lookup_name(const char **names, int size, int value)
++{
++ return (value >= 0 && value < size) ? names[value] : NULL;
++}
++
++static void list_names(FILE *f, const char **names, int size)
++{
++ int value;
++
++ for (value = 0; value < size; value++)
++ if (names[value])
++ fprintf(f, " %s\n", names[value]);
++}
++
++static const char *tx_types[] = {
++#define TX_TYPE(name) [HWTSTAMP_TX_ ## name] = #name
++ TX_TYPE(OFF),
++ TX_TYPE(ON),
++ TX_TYPE(ONESTEP_SYNC)
++#undef TX_TYPE
++};
++#define N_TX_TYPES ((int)(sizeof(tx_types) / sizeof(tx_types[0])))
++
++static const char *rx_filters[] = {
++#define RX_FILTER(name) [HWTSTAMP_FILTER_ ## name] = #name
++ RX_FILTER(NONE),
++ RX_FILTER(ALL),
++ RX_FILTER(SOME),
++ RX_FILTER(PTP_V1_L4_EVENT),
++ RX_FILTER(PTP_V1_L4_SYNC),
++ RX_FILTER(PTP_V1_L4_DELAY_REQ),
++ RX_FILTER(PTP_V2_L4_EVENT),
++ RX_FILTER(PTP_V2_L4_SYNC),
++ RX_FILTER(PTP_V2_L4_DELAY_REQ),
++ RX_FILTER(PTP_V2_L2_EVENT),
++ RX_FILTER(PTP_V2_L2_SYNC),
++ RX_FILTER(PTP_V2_L2_DELAY_REQ),
++ RX_FILTER(PTP_V2_EVENT),
++ RX_FILTER(PTP_V2_SYNC),
++ RX_FILTER(PTP_V2_DELAY_REQ),
++#undef RX_FILTER
++};
++#define N_RX_FILTERS ((int)(sizeof(rx_filters) / sizeof(rx_filters[0])))
++
++static void usage(void)
++{
++ fputs("Usage: hwtstamp_config if_name [tx_type rx_filter]\n"
++ "tx_type is any of (case-insensitive):\n",
++ stderr);
++ list_names(stderr, tx_types, N_TX_TYPES);
++ fputs("rx_filter is any of (case-insensitive):\n", stderr);
++ list_names(stderr, rx_filters, N_RX_FILTERS);
++}
++
++int main(int argc, char **argv)
++{
++ struct ifreq ifr;
++ struct hwtstamp_config config;
++ const char *name;
++ int sock;
++
++ if ((argc != 2 && argc != 4) || (strlen(argv[1]) >= IFNAMSIZ)) {
++ usage();
++ return 2;
++ }
++
++ if (argc == 4) {
++ config.flags = 0;
++ config.tx_type = lookup_value(tx_types, N_TX_TYPES, argv[2]);
++ config.rx_filter = lookup_value(rx_filters, N_RX_FILTERS, argv[3]);
++ if (config.tx_type < 0 || config.rx_filter < 0) {
++ usage();
++ return 2;
++ }
++ }
++
++ sock = socket(AF_INET, SOCK_DGRAM, 0);
++ if (sock < 0) {
++ perror("socket");
++ return 1;
++ }
++
++ strcpy(ifr.ifr_name, argv[1]);
++ ifr.ifr_data = (caddr_t)&config;
++
++ if (ioctl(sock, (argc == 2) ? SIOCGHWTSTAMP : SIOCSHWTSTAMP, &ifr)) {
++ perror("ioctl");
++ return 1;
++ }
++
++ printf("flags = %#x\n", config.flags);
++ name = lookup_name(tx_types, N_TX_TYPES, config.tx_type);
++ if (name)
++ printf("tx_type = %s\n", name);
++ else
++ printf("tx_type = %d\n", config.tx_type);
++ name = lookup_name(rx_filters, N_RX_FILTERS, config.rx_filter);
++ if (name)
++ printf("rx_filter = %s\n", name);
++ else
++ printf("rx_filter = %d\n", config.rx_filter);
++
++ return 0;
++}
+diff --git a/tools/testing/selftests/networking/timestamping/timestamping.c b/tools/testing/selftests/networking/timestamping/timestamping.c
+new file mode 100644
+index 000000000000..5cdfd743447b
+--- /dev/null
++++ b/tools/testing/selftests/networking/timestamping/timestamping.c
+@@ -0,0 +1,528 @@
++/*
++ * This program demonstrates how the various time stamping features in
++ * the Linux kernel work. It emulates the behavior of a PTP
++ * implementation in stand-alone master mode by sending PTPv1 Sync
++ * multicasts once every second. It looks for similar packets, but
++ * beyond that doesn't actually implement PTP.
++ *
++ * Outgoing packets are time stamped with SO_TIMESTAMPING with or
++ * without hardware support.
++ *
++ * Incoming packets are time stamped with SO_TIMESTAMPING with or
++ * without hardware support, SIOCGSTAMP[NS] (per-socket time stamp) and
++ * SO_TIMESTAMP[NS].
++ *
++ * Copyright (C) 2009 Intel Corporation.
++ * Author: Patrick Ohly <patrick.ohly@intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms and conditions of the GNU General Public License,
++ * version 2, as published by the Free Software Foundation.
++ *
++ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
++ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <string.h>
++
++#include <sys/time.h>
++#include <sys/socket.h>
++#include <sys/select.h>
++#include <sys/ioctl.h>
++#include <arpa/inet.h>
++#include <net/if.h>
++
++#include <asm/types.h>
++#include <linux/net_tstamp.h>
++#include <linux/errqueue.h>
++
++#ifndef SO_TIMESTAMPING
++# define SO_TIMESTAMPING 37
++# define SCM_TIMESTAMPING SO_TIMESTAMPING
++#endif
++
++#ifndef SO_TIMESTAMPNS
++# define SO_TIMESTAMPNS 35
++#endif
++
++#ifndef SIOCGSTAMPNS
++# define SIOCGSTAMPNS 0x8907
++#endif
++
++#ifndef SIOCSHWTSTAMP
++# define SIOCSHWTSTAMP 0x89b0
++#endif
++
++static void usage(const char *error)
++{
++ if (error)
++ printf("invalid option: %s\n", error);
++ printf("timestamping interface option*\n\n"
++ "Options:\n"
++ " IP_MULTICAST_LOOP - looping outgoing multicasts\n"
++ " SO_TIMESTAMP - normal software time stamping, ms resolution\n"
++ " SO_TIMESTAMPNS - more accurate software time stamping\n"
++ " SOF_TIMESTAMPING_TX_HARDWARE - hardware time stamping of outgoing packets\n"
++ " SOF_TIMESTAMPING_TX_SOFTWARE - software fallback for outgoing packets\n"
++ " SOF_TIMESTAMPING_RX_HARDWARE - hardware time stamping of incoming packets\n"
++ " SOF_TIMESTAMPING_RX_SOFTWARE - software fallback for incoming packets\n"
++ " SOF_TIMESTAMPING_SOFTWARE - request reporting of software time stamps\n"
++ " SOF_TIMESTAMPING_RAW_HARDWARE - request reporting of raw HW time stamps\n"
++ " SIOCGSTAMP - check last socket time stamp\n"
++ " SIOCGSTAMPNS - more accurate socket time stamp\n");
++ exit(1);
++}
++
++static void bail(const char *error)
++{
++ printf("%s: %s\n", error, strerror(errno));
++ exit(1);
++}
++
++static const unsigned char sync[] = {
++ 0x00, 0x01, 0x00, 0x01,
++ 0x5f, 0x44, 0x46, 0x4c,
++ 0x54, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x01, 0x01,
++
++ /* fake uuid */
++ 0x00, 0x01,
++ 0x02, 0x03, 0x04, 0x05,
++
++ 0x00, 0x01, 0x00, 0x37,
++ 0x00, 0x00, 0x00, 0x08,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x49, 0x05, 0xcd, 0x01,
++ 0x29, 0xb1, 0x8d, 0xb0,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x01,
++
++ /* fake uuid */
++ 0x00, 0x01,
++ 0x02, 0x03, 0x04, 0x05,
++
++ 0x00, 0x00, 0x00, 0x37,
++ 0x00, 0x00, 0x00, 0x04,
++ 0x44, 0x46, 0x4c, 0x54,
++ 0x00, 0x00, 0xf0, 0x60,
++ 0x00, 0x01, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x01,
++ 0x00, 0x00, 0xf0, 0x60,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x04,
++ 0x44, 0x46, 0x4c, 0x54,
++ 0x00, 0x01,
++
++ /* fake uuid */
++ 0x00, 0x01,
++ 0x02, 0x03, 0x04, 0x05,
++
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00
++};
++
++static void sendpacket(int sock, struct sockaddr *addr, socklen_t addr_len)
++{
++ struct timeval now;
++ int res;
++
++ res = sendto(sock, sync, sizeof(sync), 0,
++ addr, addr_len);
++ gettimeofday(&now, 0);
++ if (res < 0)
++ printf("%s: %s\n", "send", strerror(errno));
++ else
++ printf("%ld.%06ld: sent %d bytes\n",
++ (long)now.tv_sec, (long)now.tv_usec,
++ res);
++}
++
++static void printpacket(struct msghdr *msg, int res,
++ char *data,
++ int sock, int recvmsg_flags,
++ int siocgstamp, int siocgstampns)
++{
++ struct sockaddr_in *from_addr = (struct sockaddr_in *)msg->msg_name;
++ struct cmsghdr *cmsg;
++ struct timeval tv;
++ struct timespec ts;
++ struct timeval now;
++
++ gettimeofday(&now, 0);
++
++ printf("%ld.%06ld: received %s data, %d bytes from %s, %zu bytes control messages\n",
++ (long)now.tv_sec, (long)now.tv_usec,
++ (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
++ res,
++ inet_ntoa(from_addr->sin_addr),
++ msg->msg_controllen);
++ for (cmsg = CMSG_FIRSTHDR(msg);
++ cmsg;
++ cmsg = CMSG_NXTHDR(msg, cmsg)) {
++ printf(" cmsg len %zu: ", cmsg->cmsg_len);
++ switch (cmsg->cmsg_level) {
++ case SOL_SOCKET:
++ printf("SOL_SOCKET ");
++ switch (cmsg->cmsg_type) {
++ case SO_TIMESTAMP: {
++ struct timeval *stamp =
++ (struct timeval *)CMSG_DATA(cmsg);
++ printf("SO_TIMESTAMP %ld.%06ld",
++ (long)stamp->tv_sec,
++ (long)stamp->tv_usec);
++ break;
++ }
++ case SO_TIMESTAMPNS: {
++ struct timespec *stamp =
++ (struct timespec *)CMSG_DATA(cmsg);
++ printf("SO_TIMESTAMPNS %ld.%09ld",
++ (long)stamp->tv_sec,
++ (long)stamp->tv_nsec);
++ break;
++ }
++ case SO_TIMESTAMPING: {
++ struct timespec *stamp =
++ (struct timespec *)CMSG_DATA(cmsg);
++ printf("SO_TIMESTAMPING ");
++ printf("SW %ld.%09ld ",
++ (long)stamp->tv_sec,
++ (long)stamp->tv_nsec);
++ stamp++;
++ /* skip deprecated HW transformed */
++ stamp++;
++ printf("HW raw %ld.%09ld",
++ (long)stamp->tv_sec,
++ (long)stamp->tv_nsec);
++ break;
++ }
++ default:
++ printf("type %d", cmsg->cmsg_type);
++ break;
++ }
++ break;
++ case IPPROTO_IP:
++ printf("IPPROTO_IP ");
++ switch (cmsg->cmsg_type) {
++ case IP_RECVERR: {
++ struct sock_extended_err *err =
++ (struct sock_extended_err *)CMSG_DATA(cmsg);
++ printf("IP_RECVERR ee_errno '%s' ee_origin %d => %s",
++ strerror(err->ee_errno),
++ err->ee_origin,
++#ifdef SO_EE_ORIGIN_TIMESTAMPING
++ err->ee_origin == SO_EE_ORIGIN_TIMESTAMPING ?
++ "bounced packet" : "unexpected origin"
++#else
++ "probably SO_EE_ORIGIN_TIMESTAMPING"
++#endif
++ );
++ if (res < sizeof(sync))
++ printf(" => truncated data?!");
++ else if (!memcmp(sync, data + res - sizeof(sync),
++ sizeof(sync)))
++ printf(" => GOT OUR DATA BACK (HURRAY!)");
++ break;
++ }
++ case IP_PKTINFO: {
++ struct in_pktinfo *pktinfo =
++ (struct in_pktinfo *)CMSG_DATA(cmsg);
++ printf("IP_PKTINFO interface index %u",
++ pktinfo->ipi_ifindex);
++ break;
++ }
++ default:
++ printf("type %d", cmsg->cmsg_type);
++ break;
++ }
++ break;
++ default:
++ printf("level %d type %d",
++ cmsg->cmsg_level,
++ cmsg->cmsg_type);
++ break;
++ }
++ printf("\n");
++ }
++
++ if (siocgstamp) {
++ if (ioctl(sock, SIOCGSTAMP, &tv))
++ printf(" %s: %s\n", "SIOCGSTAMP", strerror(errno));
++ else
++ printf("SIOCGSTAMP %ld.%06ld\n",
++ (long)tv.tv_sec,
++ (long)tv.tv_usec);
++ }
++ if (siocgstampns) {
++ if (ioctl(sock, SIOCGSTAMPNS, &ts))
++ printf(" %s: %s\n", "SIOCGSTAMPNS", strerror(errno));
++ else
++ printf("SIOCGSTAMPNS %ld.%09ld\n",
++ (long)ts.tv_sec,
++ (long)ts.tv_nsec);
++ }
++}
++
++static void recvpacket(int sock, int recvmsg_flags,
++ int siocgstamp, int siocgstampns)
++{
++ char data[256];
++ struct msghdr msg;
++ struct iovec entry;
++ struct sockaddr_in from_addr;
++ struct {
++ struct cmsghdr cm;
++ char control[512];
++ } control;
++ int res;
++
++ memset(&msg, 0, sizeof(msg));
++ msg.msg_iov = &entry;
++ msg.msg_iovlen = 1;
++ entry.iov_base = data;
++ entry.iov_len = sizeof(data);
++ msg.msg_name = (caddr_t)&from_addr;
++ msg.msg_namelen = sizeof(from_addr);
++ msg.msg_control = &control;
++ msg.msg_controllen = sizeof(control);
++
++ res = recvmsg(sock, &msg, recvmsg_flags|MSG_DONTWAIT);
++ if (res < 0) {
++ printf("%s %s: %s\n",
++ "recvmsg",
++ (recvmsg_flags & MSG_ERRQUEUE) ? "error" : "regular",
++ strerror(errno));
++ } else {
++ printpacket(&msg, res, data,
++ sock, recvmsg_flags,
++ siocgstamp, siocgstampns);
++ }
++}
++
++int main(int argc, char **argv)
++{
++ int so_timestamping_flags = 0;
++ int so_timestamp = 0;
++ int so_timestampns = 0;
++ int siocgstamp = 0;
++ int siocgstampns = 0;
++ int ip_multicast_loop = 0;
++ char *interface;
++ int i;
++ int enabled = 1;
++ int sock;
++ struct ifreq device;
++ struct ifreq hwtstamp;
++ struct hwtstamp_config hwconfig, hwconfig_requested;
++ struct sockaddr_in addr;
++ struct ip_mreq imr;
++ struct in_addr iaddr;
++ int val;
++ socklen_t len;
++ struct timeval next;
++
++ if (argc < 2)
++ usage(0);
++ interface = argv[1];
++
++ for (i = 2; i < argc; i++) {
++ if (!strcasecmp(argv[i], "SO_TIMESTAMP"))
++ so_timestamp = 1;
++ else if (!strcasecmp(argv[i], "SO_TIMESTAMPNS"))
++ so_timestampns = 1;
++ else if (!strcasecmp(argv[i], "SIOCGSTAMP"))
++ siocgstamp = 1;
++ else if (!strcasecmp(argv[i], "SIOCGSTAMPNS"))
++ siocgstampns = 1;
++ else if (!strcasecmp(argv[i], "IP_MULTICAST_LOOP"))
++ ip_multicast_loop = 1;
++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_HARDWARE"))
++ so_timestamping_flags |= SOF_TIMESTAMPING_TX_HARDWARE;
++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_TX_SOFTWARE"))
++ so_timestamping_flags |= SOF_TIMESTAMPING_TX_SOFTWARE;
++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_HARDWARE"))
++ so_timestamping_flags |= SOF_TIMESTAMPING_RX_HARDWARE;
++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RX_SOFTWARE"))
++ so_timestamping_flags |= SOF_TIMESTAMPING_RX_SOFTWARE;
++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_SOFTWARE"))
++ so_timestamping_flags |= SOF_TIMESTAMPING_SOFTWARE;
++ else if (!strcasecmp(argv[i], "SOF_TIMESTAMPING_RAW_HARDWARE"))
++ so_timestamping_flags |= SOF_TIMESTAMPING_RAW_HARDWARE;
++ else
++ usage(argv[i]);
++ }
++
++ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
++ if (sock < 0)
++ bail("socket");
++
++ memset(&device, 0, sizeof(device));
++ strncpy(device.ifr_name, interface, sizeof(device.ifr_name));
++ if (ioctl(sock, SIOCGIFADDR, &device) < 0)
++ bail("getting interface IP address");
++
++ memset(&hwtstamp, 0, sizeof(hwtstamp));
++ strncpy(hwtstamp.ifr_name, interface, sizeof(hwtstamp.ifr_name));
++ hwtstamp.ifr_data = (void *)&hwconfig;
++ memset(&hwconfig, 0, sizeof(hwconfig));
++ hwconfig.tx_type =
++ (so_timestamping_flags & SOF_TIMESTAMPING_TX_HARDWARE) ?
++ HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF;
++ hwconfig.rx_filter =
++ (so_timestamping_flags & SOF_TIMESTAMPING_RX_HARDWARE) ?
++ HWTSTAMP_FILTER_PTP_V1_L4_SYNC : HWTSTAMP_FILTER_NONE;
++ hwconfig_requested = hwconfig;
++ if (ioctl(sock, SIOCSHWTSTAMP, &hwtstamp) < 0) {
++ if ((errno == EINVAL || errno == ENOTSUP) &&
++ hwconfig_requested.tx_type == HWTSTAMP_TX_OFF &&
++ hwconfig_requested.rx_filter == HWTSTAMP_FILTER_NONE)
++ printf("SIOCSHWTSTAMP: disabling hardware time stamping not possible\n");
++ else
++ bail("SIOCSHWTSTAMP");
++ }
++ printf("SIOCSHWTSTAMP: tx_type %d requested, got %d; rx_filter %d requested, got %d\n",
++ hwconfig_requested.tx_type, hwconfig.tx_type,
++ hwconfig_requested.rx_filter, hwconfig.rx_filter);
++
++ /* bind to PTP port */