summaryrefslogtreecommitdiffstats
path: root/debian/patches
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:02:38 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 01:02:38 +0000
commit08b74a000942a380fe028845f92cd3a0dee827d5 (patch)
treeaa78b4e12607c3e1fcce8d5cc42df4330792f118 /debian/patches
parentAdding upstream version 4.19.249. (diff)
downloadlinux-debian.tar.xz
linux-debian.zip
Adding debian version 4.19.249-2.debian/4.19.249-2debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch80
-rw-r--r--debian/patches/bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch35
-rw-r--r--debian/patches/bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch191
-rw-r--r--debian/patches/bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch33
-rw-r--r--debian/patches/bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch280
-rw-r--r--debian/patches/bugfix/all/cpupower-bump-soname-version.patch29
-rw-r--r--debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch51
-rw-r--r--debian/patches/bugfix/all/disable-some-marvell-phys.patch93
-rw-r--r--debian/patches/bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch52
-rw-r--r--debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch2895
-rw-r--r--debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch70
-rw-r--r--debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch66
-rw-r--r--debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch25
-rw-r--r--debian/patches/bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch42
-rw-r--r--debian/patches/bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch91
-rw-r--r--debian/patches/bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch77
-rw-r--r--debian/patches/bugfix/all/libbpf-add-soname-to-shared-object.patch56
-rw-r--r--debian/patches/bugfix/all/libbpf-generate-pkg-config.patch90
-rw-r--r--debian/patches/bugfix/all/libbpf-link-shared-object-with-libelf.patch22
-rw-r--r--debian/patches/bugfix/all/libcpupower-hide-private-function.patch22
-rw-r--r--debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch25
-rw-r--r--debian/patches/bugfix/all/mt76-use-the-correct-hweight8-function.patch30
-rw-r--r--debian/patches/bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch50
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch153
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch214
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch85
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch76
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch57
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch133
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch76
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch59
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch180
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch87
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch69
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch45
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch61
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch74
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch65
-rw-r--r--debian/patches/bugfix/all/perf-script-python-Remove-mixed-indentation.patch511
-rw-r--r--debian/patches/bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch104
-rw-r--r--debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch135
-rw-r--r--debian/patches/bugfix/all/rtc-s35390a-set-uie_unsupported.patch40
-rw-r--r--debian/patches/bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch47
-rw-r--r--debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch29
-rw-r--r--debian/patches/bugfix/all/tools-lib-traceevent-use-ldflags.patch29
-rw-r--r--debian/patches/bugfix/all/tools-perf-man-date.patch37
-rw-r--r--debian/patches/bugfix/all/tools-perf-remove-shebangs.patch47
-rw-r--r--debian/patches/bugfix/all/usb-add-a-hcd_uses_dma-helper.patch110
-rw-r--r--debian/patches/bugfix/all/usb-dont-create-dma-pools-for-HCD.patch31
-rw-r--r--debian/patches/bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch35
-rw-r--r--debian/patches/bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch105
-rw-r--r--debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch31
-rw-r--r--debian/patches/bugfix/all/usbip-fix-misuse-of-strncpy.patch61
-rw-r--r--debian/patches/bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch77
-rw-r--r--debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch37
-rw-r--r--debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch31
-rw-r--r--debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch47
-rw-r--r--debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch46
-rw-r--r--debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch92
-rw-r--r--debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch28
-rw-r--r--debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch42
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch47
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch29
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch308
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch54
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch33
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch40
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch116
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch113
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch150
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch92
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch429
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch187
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch82
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch43
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch29
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch32
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch157
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch144
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch45
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch30
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch39
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch28
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch46
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch43
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch28
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch63
-rw-r--r--debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch70
-rw-r--r--debian/patches/bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch387
-rw-r--r--debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch39
-rw-r--r--debian/patches/bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch42
-rw-r--r--debian/patches/bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch30
-rw-r--r--debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch132
-rw-r--r--debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch37
-rw-r--r--debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch37
-rw-r--r--debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch35
-rw-r--r--debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch37
-rw-r--r--debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch112
-rw-r--r--debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch35
-rw-r--r--debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch35
-rw-r--r--debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch24
-rw-r--r--debian/patches/bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch114
-rw-r--r--debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch36
-rw-r--r--debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch31
-rw-r--r--debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch99
-rw-r--r--debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch31
-rw-r--r--debian/patches/debian/android-enable-building-ashmem-and-binder-as-modules.patch97
-rw-r--r--debian/patches/debian/arch-sh4-fix-uimage-build.patch20
-rw-r--r--debian/patches/debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch37
-rw-r--r--debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch29
-rw-r--r--debian/patches/debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch45
-rw-r--r--debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch34
-rw-r--r--debian/patches/debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch29
-rw-r--r--debian/patches/debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch17
-rw-r--r--debian/patches/debian/dfsg/drivers-net-appletalk-cops.patch52
-rw-r--r--debian/patches/debian/dfsg/video-remove-nvidiafb-and-rivafb.patch134
-rw-r--r--debian/patches/debian/dfsg/vs6624-disable.patch17
-rw-r--r--debian/patches/debian/export-symbols-needed-by-android-drivers.patch156
-rw-r--r--debian/patches/debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch31
-rw-r--r--debian/patches/debian/firmware_class-refer-to-debian-wiki-firmware-page.patch58
-rw-r--r--debian/patches/debian/fjes-disable-autoload.patch26
-rw-r--r--debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch24
-rw-r--r--debian/patches/debian/gitignore.patch49
-rw-r--r--debian/patches/debian/i386-686-pae-pci-set-pci-nobios-by-default.patch29
-rw-r--r--debian/patches/debian/ia64-hardcode-arch-script-output.patch72
-rw-r--r--debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch28
-rw-r--r--debian/patches/debian/kernelvariables.patch81
-rw-r--r--debian/patches/debian/mips-boston-disable-its.patch22
-rw-r--r--debian/patches/debian/mips-disable-werror.patch25
-rw-r--r--debian/patches/debian/ntfs-mark-it-as-broken.patch21
-rw-r--r--debian/patches/debian/overlayfs-permit-mounts-in-userns.patch59
-rw-r--r--debian/patches/debian/powerpcspe-omit-uimage.patch45
-rw-r--r--debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch31
-rw-r--r--debian/patches/debian/revert-objtool-fix-config_stack_validation-y-warning.patch50
-rw-r--r--debian/patches/debian/sched-autogroup-disabled.patch21
-rw-r--r--debian/patches/debian/snd-pcsp-disable-autoload.patch32
-rw-r--r--debian/patches/debian/tools-perf-install.patch58
-rw-r--r--debian/patches/debian/tools-perf-version.patch119
-rw-r--r--debian/patches/debian/uname-version-timestamp.patch35
-rw-r--r--debian/patches/debian/version.patch177
-rw-r--r--debian/patches/debian/wireless-add-debian-wireless-regdb-certificates.patch963
-rw-r--r--debian/patches/debian/wireless-disable-regulatory.db-direct-loading.patch75
-rw-r--r--debian/patches/debian/yama-disable-by-default.patch28
-rw-r--r--debian/patches/features/all/aufs4/aufs4-base.patch328
-rw-r--r--debian/patches/features/all/aufs4/aufs4-mmap.patch406
-rw-r--r--debian/patches/features/all/aufs4/aufs4-standalone.patch385
-rw-r--r--debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch91
-rw-r--r--debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch64
-rw-r--r--debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch60
-rw-r--r--debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch57
-rw-r--r--debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch129
-rw-r--r--debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch193
-rw-r--r--debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch242
-rw-r--r--debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch108
-rw-r--r--debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch85
-rw-r--r--debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch106
-rw-r--r--debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch28
-rw-r--r--debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch30
-rw-r--r--debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch149
-rw-r--r--debian/patches/features/all/e1000e-Add-support-for-Comet-Lake.patch54
-rw-r--r--debian/patches/features/all/ena/0001-net-ethernet-remove-redundant-include.patch34
-rw-r--r--debian/patches/features/all/ena/0002-net-ena-minor-performance-improvement.patch139
-rw-r--r--debian/patches/features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch178
-rw-r--r--debian/patches/features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch271
-rw-r--r--debian/patches/features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch832
-rw-r--r--debian/patches/features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch655
-rw-r--r--debian/patches/features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch125
-rw-r--r--debian/patches/features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch223
-rw-r--r--debian/patches/features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch54
-rw-r--r--debian/patches/features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch28
-rw-r--r--debian/patches/features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch76
-rw-r--r--debian/patches/features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch28
-rw-r--r--debian/patches/features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch1000
-rw-r--r--debian/patches/features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch50
-rw-r--r--debian/patches/features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch31
-rw-r--r--debian/patches/features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch97
-rw-r--r--debian/patches/features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch26
-rw-r--r--debian/patches/features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch39
-rw-r--r--debian/patches/features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch345
-rw-r--r--debian/patches/features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch106
-rw-r--r--debian/patches/features/all/ena/net-ena-add-good-checksum-counter.patch72
-rw-r--r--debian/patches/features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch232
-rw-r--r--debian/patches/features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch118
-rw-r--r--debian/patches/features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch91
-rw-r--r--debian/patches/features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch54
-rw-r--r--debian/patches/features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch103
-rw-r--r--debian/patches/features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch323
-rw-r--r--debian/patches/features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch49
-rw-r--r--debian/patches/features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch52
-rw-r--r--debian/patches/features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch270
-rw-r--r--debian/patches/features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch63
-rw-r--r--debian/patches/features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch89
-rw-r--r--debian/patches/features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch45
-rw-r--r--debian/patches/features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch34
-rw-r--r--debian/patches/features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch91
-rw-r--r--debian/patches/features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch39
-rw-r--r--debian/patches/features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch41
-rw-r--r--debian/patches/features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch53
-rw-r--r--debian/patches/features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch50
-rw-r--r--debian/patches/features/all/ena/net-ena-reimplement-set-get_coalesce.patch158
-rw-r--r--debian/patches/features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch361
-rw-r--r--debian/patches/features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch71
-rw-r--r--debian/patches/features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch59
-rw-r--r--debian/patches/features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch244
-rw-r--r--debian/patches/features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch83
-rw-r--r--debian/patches/features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch198
-rw-r--r--debian/patches/features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch163
-rw-r--r--debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch27
-rw-r--r--debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch32
-rw-r--r--debian/patches/features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch34
-rw-r--r--debian/patches/features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch164
-rw-r--r--debian/patches/features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch75
-rw-r--r--debian/patches/features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch95
-rw-r--r--debian/patches/features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch35
-rw-r--r--debian/patches/features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch42
-rw-r--r--debian/patches/features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch36
-rw-r--r--debian/patches/features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch40
-rw-r--r--debian/patches/features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch31
-rw-r--r--debian/patches/features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch32
-rw-r--r--debian/patches/features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch104
-rw-r--r--debian/patches/features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch46
-rw-r--r--debian/patches/features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch50
-rw-r--r--debian/patches/features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch55
-rw-r--r--debian/patches/features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch32
-rw-r--r--debian/patches/features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch32
-rw-r--r--debian/patches/features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch40
-rw-r--r--debian/patches/features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch43
-rw-r--r--debian/patches/features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch29
-rw-r--r--debian/patches/features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch34
-rw-r--r--debian/patches/features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch80
-rw-r--r--debian/patches/features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch33
-rw-r--r--debian/patches/features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch53
-rw-r--r--debian/patches/features/all/lockdown/0025-Lock-down-proc-kcore.patch27
-rw-r--r--debian/patches/features/all/lockdown/0026-Lock-down-kprobes.patch29
-rw-r--r--debian/patches/features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch39
-rw-r--r--debian/patches/features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch152
-rw-r--r--debian/patches/features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch83
-rw-r--r--debian/patches/features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch36
-rw-r--r--debian/patches/features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch44
-rw-r--r--debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch97
-rw-r--r--debian/patches/features/all/lockdown/enable-cold-boot-attack-mitigation.patch50
-rw-r--r--debian/patches/features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch34
-rw-r--r--debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch41
-rw-r--r--debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch81
-rw-r--r--debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch211
-rw-r--r--debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch183
-rw-r--r--debian/patches/features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch35
-rw-r--r--debian/patches/features/arm/staging-vc04_services-Use-correct-cache-line-size.patch133
-rw-r--r--debian/patches/features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch55
-rw-r--r--debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch35
-rw-r--r--debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch35
-rw-r--r--debian/patches/features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch32
-rw-r--r--debian/patches/features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch65
-rw-r--r--debian/patches/features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch29
-rw-r--r--debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch101
-rw-r--r--debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch51
-rw-r--r--debian/patches/features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch232
-rw-r--r--debian/patches/features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch236
-rw-r--r--debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch227
-rw-r--r--debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch30
-rw-r--r--debian/patches/series315
261 files changed, 28237 insertions, 0 deletions
diff --git a/debian/patches/bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch b/debian/patches/bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch
new file mode 100644
index 000000000..2172fa43d
--- /dev/null
+++ b/debian/patches/bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch
@@ -0,0 +1,80 @@
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Sat, 15 Jun 2019 10:23:57 +1000
+Subject: [PATCH 1/4] PCI/ACPI: Evaluate PCI Boot Configuration _DSM
+Origin: https://git.kernel.org/linus/a78cf9657ba5426f54aa93a067c10d097944c082
+
+Evaluate _DSM Function #5, the "PCI Boot Configuration" function. If the
+result is 0, the OS should preserve any resource assignments made by the
+firmware.
+
+Link: https://lore.kernel.org/r/20190615002359.29577-2-benh@kernel.crashing.org
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/acpi/pci_root.c | 12 ++++++++++++
+ include/linux/pci-acpi.h | 7 ++++---
+ include/linux/pci.h | 2 ++
+ 3 files changed, 18 insertions(+), 3 deletions(-)
+
+Index: linux/drivers/acpi/pci_root.c
+===================================================================
+--- linux.orig/drivers/acpi/pci_root.c
++++ linux/drivers/acpi/pci_root.c
+@@ -884,6 +884,7 @@ struct pci_bus *acpi_pci_root_create(str
+ int node = acpi_get_node(device->handle);
+ struct pci_bus *bus;
+ struct pci_host_bridge *host_bridge;
++ union acpi_object *obj;
+
+ info->root = root;
+ info->bridge = device;
+@@ -920,6 +921,17 @@ struct pci_bus *acpi_pci_root_create(str
+ if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL))
+ host_bridge->native_ltr = 0;
+
++ /*
++ * Evaluate the "PCI Boot Configuration" _DSM Function. If it
++ * exists and returns 0, we must preserve any PCI resource
++ * assignments made by firmware for this host bridge.
++ */
++ obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1,
++ IGNORE_PCI_BOOT_CONFIG_DSM, NULL);
++ if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0)
++ host_bridge->preserve_config = 1;
++ ACPI_FREE(obj);
++
+ pci_scan_child_bus(bus);
+ pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info,
+ info);
+Index: linux/include/linux/pci-acpi.h
+===================================================================
+--- linux.orig/include/linux/pci-acpi.h
++++ linux/include/linux/pci-acpi.h
+@@ -107,9 +107,10 @@ static inline void acpiphp_check_host_br
+ #endif
+
+ extern const guid_t pci_acpi_dsm_guid;
+-#define DEVICE_LABEL_DSM 0x07
+-#define RESET_DELAY_DSM 0x08
+-#define FUNCTION_DELAY_DSM 0x09
++#define IGNORE_PCI_BOOT_CONFIG_DSM 0x05
++#define DEVICE_LABEL_DSM 0x07
++#define RESET_DELAY_DSM 0x08
++#define FUNCTION_DELAY_DSM 0x09
+
+ #else /* CONFIG_ACPI */
+ static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
+Index: linux/include/linux/pci.h
+===================================================================
+--- linux.orig/include/linux/pci.h
++++ linux/include/linux/pci.h
+@@ -486,6 +486,8 @@ struct pci_host_bridge {
+ unsigned int native_shpc_hotplug:1; /* OS may use SHPC hotplug */
+ unsigned int native_pme:1; /* OS may use PCIe PME */
+ unsigned int native_ltr:1; /* OS may use PCIe LTR */
++ unsigned int preserve_config:1; /* Preserve FW resource setup */
++
+ /* Resource alignment requirements */
+ resource_size_t (*align_resource)(struct pci_dev *dev,
+ const struct resource *res,
diff --git a/debian/patches/bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch b/debian/patches/bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch
new file mode 100644
index 000000000..04fa61629
--- /dev/null
+++ b/debian/patches/bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch
@@ -0,0 +1,35 @@
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Sat, 15 Jun 2019 10:23:58 +1000
+Subject: [PATCH 2/4] PCI: Don't auto-realloc if we're preserving firmware config
+Origin: https://git.kernel.org/linus/7ac0d094fbe95bf7cc96b3066a97e1090ddc734a
+
+Prevent auto-enabling of bridges reallocation when the FW tells us that the
+initial configuration must be preserved for a given host bridge.
+
+Link: https://lore.kernel.org/r/20190615002359.29577-3-benh@kernel.crashing.org
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+---
+ drivers/pci/setup-bus.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+Index: linux/drivers/pci/setup-bus.c
+===================================================================
+--- linux.orig/drivers/pci/setup-bus.c
++++ linux/drivers/pci/setup-bus.c
+@@ -1724,10 +1724,15 @@ static enum enable_type pci_realloc_dete
+ enum enable_type enable_local)
+ {
+ bool unassigned = false;
++ struct pci_host_bridge *host;
+
+ if (enable_local != undefined)
+ return enable_local;
+
++ host = pci_find_host_bridge(bus);
++ if (host->preserve_config)
++ return auto_disabled;
++
+ pci_walk_bus(bus, iov_resources_unassigned, &unassigned);
+ if (unassigned)
+ return auto_enabled;
diff --git a/debian/patches/bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch b/debian/patches/bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch
new file mode 100644
index 000000000..727419539
--- /dev/null
+++ b/debian/patches/bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch
@@ -0,0 +1,191 @@
+From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Date: Wed, 29 May 2019 13:28:43 +0300
+Subject: USB: drop HCD_LOCAL_MEM flag
+Origin: https://git.kernel.org/linus/2d7a3dc3e24f43504b1f25eae8195e600f4cce8b
+
+With the addition of the local memory allocator, the HCD_LOCAL_MEM
+flag can be dropped and the checks against it replaced with a check
+for the localmem_pool ptr being initialized.
+
+Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Tested-by: Fredrik Noring <noring@nocrew.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ drivers/usb/core/buffer.c | 8 +++-----
+ drivers/usb/core/hcd.c | 15 ++++++---------
+ drivers/usb/host/ehci-hcd.c | 2 +-
+ drivers/usb/host/fotg210-hcd.c | 2 +-
+ drivers/usb/host/ohci-hcd.c | 2 +-
+ drivers/usb/host/ohci-sm501.c | 5 +++--
+ drivers/usb/host/ohci-tmio.c | 2 +-
+ drivers/usb/host/uhci-hcd.c | 2 +-
+ include/linux/usb/hcd.h | 1 -
+ 9 files changed, 17 insertions(+), 22 deletions(-)
+
+--- a/drivers/usb/core/buffer.c
++++ b/drivers/usb/core/buffer.c
+@@ -68,7 +68,7 @@
+
+ if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+ (!is_device_dma_capable(hcd->self.sysdev) &&
+- !(hcd->driver->flags & HCD_LOCAL_MEM)))
++ !hcd->localmem_pool))
+ return 0;
+
+ for (i = 0; i < HCD_BUFFER_POOLS; i++) {
+@@ -134,8 +134,7 @@
+
+ /* some USB hosts just use PIO */
+ if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+- (!is_device_dma_capable(bus->sysdev) &&
+- !(hcd->driver->flags & HCD_LOCAL_MEM))) {
++ !is_device_dma_capable(bus->sysdev)) {
+ *dma = ~(dma_addr_t) 0;
+ return kmalloc(size, mem_flags);
+ }
+@@ -166,8 +165,7 @@
+ }
+
+ if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+- (!is_device_dma_capable(bus->sysdev) &&
+- !(hcd->driver->flags & HCD_LOCAL_MEM))) {
++ !is_device_dma_capable(bus->sysdev)) {
+ kfree(addr);
+ return;
+ }
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1346,14 +1346,14 @@
+ * using regular system memory - like pci devices doing bus mastering.
+ *
+ * To support host controllers with limited dma capabilities we provide dma
+- * bounce buffers. This feature can be enabled using the HCD_LOCAL_MEM flag.
++ * bounce buffers. This feature can be enabled by initializing
++ * hcd->localmem_pool using usb_hcd_setup_local_mem().
+ * For this to work properly the host controller code must first use the
+ * function dma_declare_coherent_memory() to point out which memory area
+ * that should be used for dma allocations.
+ *
+- * The HCD_LOCAL_MEM flag then tells the usb code to allocate all data for
+- * dma using dma_alloc_coherent() which in turn allocates from the memory
+- * area pointed out with dma_declare_coherent_memory().
++ * The initialized hcd->localmem_pool then tells the usb code to allocate all
++ * data for dma using the genalloc API.
+ *
+ * So, to summarize...
+ *
+@@ -1363,9 +1363,6 @@
+ * (a) "normal" kernel memory is no good, and
+ * (b) there's not enough to share
+ *
+- * - The only *portable* hook for such stuff in the
+- * DMA framework is dma_declare_coherent_memory()
+- *
+ * - So we use that, even though the primary requirement
+ * is that the memory be "local" (hence addressable
+ * by that device), not "coherent".
+@@ -1532,7 +1529,7 @@
+ urb->setup_dma))
+ return -EAGAIN;
+ urb->transfer_flags |= URB_SETUP_MAP_SINGLE;
+- } else if (hcd->driver->flags & HCD_LOCAL_MEM) {
++ } else if (hcd->localmem_pool) {
+ ret = hcd_alloc_coherent(
+ urb->dev->bus, mem_flags,
+ &urb->setup_dma,
+@@ -1602,7 +1599,7 @@
+ else
+ urb->transfer_flags |= URB_DMA_MAP_SINGLE;
+ }
+- } else if (hcd->driver->flags & HCD_LOCAL_MEM) {
++ } else if (hcd->localmem_pool) {
+ ret = hcd_alloc_coherent(
+ urb->dev->bus, mem_flags,
+ &urb->transfer_dma,
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -560,7 +560,7 @@
+ ehci->command = temp;
+
+ /* Accept arbitrarily long scatter-gather lists */
+- if (!(hcd->driver->flags & HCD_LOCAL_MEM))
++ if (!hcd->localmem_pool)
+ hcd->self.sg_tablesize = ~0;
+
+ /* Prepare for unlinking active QHs */
+--- a/drivers/usb/host/fotg210-hcd.c
++++ b/drivers/usb/host/fotg210-hcd.c
+@@ -4998,7 +4998,7 @@
+ fotg210->command = temp;
+
+ /* Accept arbitrarily long scatter-gather lists */
+- if (!(hcd->driver->flags & HCD_LOCAL_MEM))
++ if (!hcd->localmem_pool)
+ hcd->self.sg_tablesize = ~0;
+ return 0;
+ }
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -457,7 +457,7 @@
+ struct usb_hcd *hcd = ohci_to_hcd(ohci);
+
+ /* Accept arbitrarily long scatter-gather lists */
+- if (!(hcd->driver->flags & HCD_LOCAL_MEM))
++ if (!hcd->localmem_pool)
+ hcd->self.sg_tablesize = ~0;
+
+ if (distrust_firmware)
+--- a/drivers/usb/host/ohci-sm501.c
++++ b/drivers/usb/host/ohci-sm501.c
+@@ -49,7 +49,7 @@
+ * generic hardware linkage
+ */
+ .irq = ohci_irq,
+- .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM,
++ .flags = HCD_USB11 | HCD_MEMORY,
+
+ /*
+ * basic lifecycle operations
+@@ -153,7 +153,8 @@
+ * fine. This is however not always the case - buffers may be allocated
+ * using kmalloc() - so the usb core needs to be told that it must copy
+ * data into our local memory if the buffers happen to be placed in
+- * regular memory. The HCD_LOCAL_MEM flag does just that.
++ * regular memory. A non-null hcd->localmem_pool initialized by the
++ * the call to usb_hcd_setup_local_mem() below does just that.
+ */
+
+ retval = usb_hcd_setup_local_mem(hcd, mem->start,
+--- a/drivers/usb/host/ohci-tmio.c
++++ b/drivers/usb/host/ohci-tmio.c
+@@ -153,7 +153,7 @@
+
+ /* generic hardware linkage */
+ .irq = ohci_irq,
+- .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM,
++ .flags = HCD_USB11 | HCD_MEMORY,
+
+ /* basic lifecycle operations */
+ .start = ohci_tmio_start,
+--- a/drivers/usb/host/uhci-hcd.c
++++ b/drivers/usb/host/uhci-hcd.c
+@@ -581,7 +581,7 @@
+
+ hcd->uses_new_polling = 1;
+ /* Accept arbitrarily long scatter-gather lists */
+- if (!(hcd->driver->flags & HCD_LOCAL_MEM))
++ if (!hcd->localmem_pool)
+ hcd->self.sg_tablesize = ~0;
+
+ spin_lock_init(&uhci->lock);
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -256,7 +256,6 @@
+
+ int flags;
+ #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
+-#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */
+ #define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */
+ #define HCD_USB11 0x0010 /* USB 1.1 */
+ #define HCD_USB2 0x0020 /* USB 2.0 */
diff --git a/debian/patches/bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch b/debian/patches/bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch
new file mode 100644
index 000000000..08a838c66
--- /dev/null
+++ b/debian/patches/bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch
@@ -0,0 +1,33 @@
+From: Wei Yongjun <weiyongjun1@huawei.com>
+Date: Wed, 6 May 2020 13:56:25 +0000
+Subject: USB: ohci-sm501: fix error return code in ohci_hcd_sm501_drv_probe()
+Origin: https://git.kernel.org/linus/b919e077cccfbb77beb98809568b2fb0b4d113ec
+
+Fix to return a negative error code from the error handling
+case instead of 0, as done elsewhere in this function.
+
+Fixes: 7d9e6f5aebe8 ("usb: host: ohci-sm501: init genalloc for local memory")
+Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
+Acked-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20200506135625.106910-1-weiyongjun1@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/host/ohci-sm501.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/ohci-sm501.c
++++ b/drivers/usb/host/ohci-sm501.c
+@@ -156,9 +156,10 @@
+ * regular memory. The HCD_LOCAL_MEM flag does just that.
+ */
+
+- if (usb_hcd_setup_local_mem(hcd, mem->start,
+- mem->start - mem->parent->start,
+- resource_size(mem)) < 0)
++ retval = usb_hcd_setup_local_mem(hcd, mem->start,
++ mem->start - mem->parent->start,
++ resource_size(mem));
++ if (retval < 0)
+ goto err5;
+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (retval)
diff --git a/debian/patches/bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch b/debian/patches/bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch
new file mode 100644
index 000000000..88caafd5a
--- /dev/null
+++ b/debian/patches/bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch
@@ -0,0 +1,280 @@
+From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Date: Wed, 29 May 2019 13:28:40 +0300
+Subject: USB: use genalloc for USB HCs with local memory
+Origin: https://git.kernel.org/linus/b0310c2f09bbe8aebefb97ed67949a3a7092aca6
+
+For HCs that have local memory, replace the current DMA API usage with
+a genalloc generic allocator to manage the mappings for these devices.
+To help users, introduce a new HCD API, usb_hcd_setup_local_mem() that
+will setup up the genalloc backing up the device local memory. It will
+be used in subsequent patches. This is in preparation for dropping
+the existing "coherent" dma mem declaration APIs. The current
+implementation was relying on a short circuit in the DMA API that in
+the end, was acting as an allocator for these type of devices.
+
+Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Tested-by: Fredrik Noring <noring@nocrew.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ drivers/usb/Kconfig | 1 +
+ drivers/usb/core/buffer.c | 9 +++++++++
+ drivers/usb/core/hcd.c | 36 ++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/ohci-hcd.c | 23 ++++++++++++++++++-----
+ drivers/usb/host/ohci-mem.c | 35 +++++++++++++++++++++++++++++++----
+ drivers/usb/host/ohci.h | 2 ++
+ include/linux/usb/hcd.h | 5 +++++
+ 7 files changed, 102 insertions(+), 9 deletions(-)
+
+--- a/drivers/usb/Kconfig
++++ b/drivers/usb/Kconfig
+@@ -44,6 +44,7 @@
+ config USB
+ tristate "Support for Host-side USB"
+ depends on USB_ARCH_HAS_HCD
++ select GENERIC_ALLOCATOR
+ select USB_COMMON
+ select NLS # for UTF-8 strings
+ ---help---
+--- a/drivers/usb/core/buffer.c
++++ b/drivers/usb/core/buffer.c
+@@ -16,6 +16,7 @@
+ #include <linux/io.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dmapool.h>
++#include <linux/genalloc.h>
+ #include <linux/usb.h>
+ #include <linux/usb/hcd.h>
+
+@@ -128,6 +129,9 @@
+ if (size == 0)
+ return NULL;
+
++ if (hcd->localmem_pool)
++ return gen_pool_dma_alloc(hcd->localmem_pool, size, dma);
++
+ /* some USB hosts just use PIO */
+ if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+ (!is_device_dma_capable(bus->sysdev) &&
+@@ -156,6 +160,11 @@
+ if (!addr)
+ return;
+
++ if (hcd->localmem_pool) {
++ gen_pool_free(hcd->localmem_pool, (unsigned long)addr, size);
++ return;
++ }
++
+ if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+ (!is_device_dma_capable(bus->sysdev) &&
+ !(hcd->driver->flags & HCD_LOCAL_MEM))) {
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -29,6 +29,8 @@
+ #include <linux/workqueue.h>
+ #include <linux/pm_runtime.h>
+ #include <linux/types.h>
++#include <linux/genalloc.h>
++#include <linux/io.h>
+
+ #include <linux/phy/phy.h>
+ #include <linux/usb.h>
+@@ -3025,6 +3027,40 @@
+ }
+ EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown);
+
++int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
++ dma_addr_t dma, size_t size)
++{
++ int err;
++ void *local_mem;
++
++ hcd->localmem_pool = devm_gen_pool_create(hcd->self.sysdev, PAGE_SHIFT,
++ dev_to_node(hcd->self.sysdev),
++ dev_name(hcd->self.sysdev));
++ if (IS_ERR(hcd->localmem_pool))
++ return PTR_ERR(hcd->localmem_pool);
++
++ local_mem = devm_memremap(hcd->self.sysdev, phys_addr,
++ size, MEMREMAP_WC);
++ if (!local_mem)
++ return -ENOMEM;
++
++ /*
++ * Here we pass a dma_addr_t but the arg type is a phys_addr_t.
++ * It's not backed by system memory and thus there's no kernel mapping
++ * for it.
++ */
++ err = gen_pool_add_virt(hcd->localmem_pool, (unsigned long)local_mem,
++ dma, size, dev_to_node(hcd->self.sysdev));
++ if (err < 0) {
++ dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n",
++ err);
++ return err;
++ }
++
++ return 0;
++}
++EXPORT_SYMBOL_GPL(usb_hcd_setup_local_mem);
++
+ /*-------------------------------------------------------------------------*/
+
+ #if IS_ENABLED(CONFIG_USB_MON)
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -40,6 +40,7 @@
+ #include <linux/dmapool.h>
+ #include <linux/workqueue.h>
+ #include <linux/debugfs.h>
++#include <linux/genalloc.h>
+
+ #include <asm/io.h>
+ #include <asm/irq.h>
+@@ -514,8 +515,15 @@
+ timer_setup(&ohci->io_watchdog, io_watchdog_func, 0);
+ ohci->prev_frame_no = IO_WATCHDOG_OFF;
+
+- ohci->hcca = dma_alloc_coherent (hcd->self.controller,
+- sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL);
++ if (hcd->localmem_pool)
++ ohci->hcca = gen_pool_dma_alloc(hcd->localmem_pool,
++ sizeof(*ohci->hcca),
++ &ohci->hcca_dma);
++ else
++ ohci->hcca = dma_alloc_coherent(hcd->self.controller,
++ sizeof(*ohci->hcca),
++ &ohci->hcca_dma,
++ GFP_KERNEL);
+ if (!ohci->hcca)
+ return -ENOMEM;
+
+@@ -999,9 +1007,14 @@
+ remove_debug_files (ohci);
+ ohci_mem_cleanup (ohci);
+ if (ohci->hcca) {
+- dma_free_coherent (hcd->self.controller,
+- sizeof *ohci->hcca,
+- ohci->hcca, ohci->hcca_dma);
++ if (hcd->localmem_pool)
++ gen_pool_free(hcd->localmem_pool,
++ (unsigned long)ohci->hcca,
++ sizeof(*ohci->hcca));
++ else
++ dma_free_coherent(hcd->self.controller,
++ sizeof(*ohci->hcca),
++ ohci->hcca, ohci->hcca_dma);
+ ohci->hcca = NULL;
+ ohci->hcca_dma = 0;
+ }
+--- a/drivers/usb/host/ohci-mem.c
++++ b/drivers/usb/host/ohci-mem.c
+@@ -36,6 +36,13 @@
+
+ static int ohci_mem_init (struct ohci_hcd *ohci)
+ {
++ /*
++ * HCs with local memory allocate from localmem_pool so there's
++ * no need to create the below dma pools.
++ */
++ if (ohci_to_hcd(ohci)->localmem_pool)
++ return 0;
++
+ ohci->td_cache = dma_pool_create ("ohci_td",
+ ohci_to_hcd(ohci)->self.controller,
+ sizeof (struct td),
+@@ -88,8 +95,12 @@
+ {
+ dma_addr_t dma;
+ struct td *td;
++ struct usb_hcd *hcd = ohci_to_hcd(hc);
+
+- td = dma_pool_zalloc (hc->td_cache, mem_flags, &dma);
++ if (hcd->localmem_pool)
++ td = gen_pool_dma_zalloc(hcd->localmem_pool, sizeof(*td), &dma);
++ else
++ td = dma_pool_zalloc(hc->td_cache, mem_flags, &dma);
+ if (td) {
+ /* in case hc fetches it, make it look dead */
+ td->hwNextTD = cpu_to_hc32 (hc, dma);
+@@ -103,6 +114,7 @@
+ td_free (struct ohci_hcd *hc, struct td *td)
+ {
+ struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)];
++ struct usb_hcd *hcd = ohci_to_hcd(hc);
+
+ while (*prev && *prev != td)
+ prev = &(*prev)->td_hash;
+@@ -110,7 +122,12 @@
+ *prev = td->td_hash;
+ else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0)
+ ohci_dbg (hc, "no hash for td %p\n", td);
+- dma_pool_free (hc->td_cache, td, td->td_dma);
++
++ if (hcd->localmem_pool)
++ gen_pool_free(hcd->localmem_pool, (unsigned long)td,
++ sizeof(*td));
++ else
++ dma_pool_free(hc->td_cache, td, td->td_dma);
+ }
+
+ /*-------------------------------------------------------------------------*/
+@@ -121,8 +138,12 @@
+ {
+ dma_addr_t dma;
+ struct ed *ed;
++ struct usb_hcd *hcd = ohci_to_hcd(hc);
+
+- ed = dma_pool_zalloc (hc->ed_cache, mem_flags, &dma);
++ if (hcd->localmem_pool)
++ ed = gen_pool_dma_zalloc(hcd->localmem_pool, sizeof(*ed), &dma);
++ else
++ ed = dma_pool_zalloc(hc->ed_cache, mem_flags, &dma);
+ if (ed) {
+ INIT_LIST_HEAD (&ed->td_list);
+ ed->dma = dma;
+@@ -133,6 +154,12 @@
+ static void
+ ed_free (struct ohci_hcd *hc, struct ed *ed)
+ {
+- dma_pool_free (hc->ed_cache, ed, ed->dma);
++ struct usb_hcd *hcd = ohci_to_hcd(hc);
++
++ if (hcd->localmem_pool)
++ gen_pool_free(hcd->localmem_pool, (unsigned long)ed,
++ sizeof(*ed));
++ else
++ dma_pool_free(hc->ed_cache, ed, ed->dma);
+ }
+
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -385,6 +385,8 @@
+
+ /*
+ * memory management for queue data structures
++ *
++ * @td_cache and @ed_cache are %NULL if &usb_hcd.localmem_pool is used.
+ */
+ struct dma_pool *td_cache;
+ struct dma_pool *ed_cache;
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -211,6 +211,9 @@
+ #define HC_IS_RUNNING(state) ((state) & __ACTIVE)
+ #define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
+
++ /* memory pool for HCs having local memory, or %NULL */
++ struct gen_pool *localmem_pool;
++
+ /* more shared queuing code would be good; it should support
+ * smarter scheduling, handle transaction translators, etc;
+ * input size of periodic table to an interrupt scheduler.
+@@ -461,6 +464,8 @@
+ unsigned int irqnum, unsigned long irqflags);
+ extern void usb_remove_hcd(struct usb_hcd *hcd);
+ extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1);
++int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
++ dma_addr_t dma, size_t size);
+
+ struct platform_device;
+ extern void usb_hcd_platform_shutdown(struct platform_device *dev);
diff --git a/debian/patches/bugfix/all/cpupower-bump-soname-version.patch b/debian/patches/bugfix/all/cpupower-bump-soname-version.patch
new file mode 100644
index 000000000..5691bd454
--- /dev/null
+++ b/debian/patches/bugfix/all/cpupower-bump-soname-version.patch
@@ -0,0 +1,29 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 9 Jun 2016 23:35:08 +0100
+Subject: cpupower: Bump soname version
+Forwarded: http://mid.gmane.org/20160610005619.GQ7555@decadent.org.uk
+
+Several functions in the libcpupower API are renamed or removed in
+Linux 4.7. This is an backward-incompatible ABI change, so the
+library soname should change from libcpupower.so.0 to
+libcpupower.so.1.
+
+Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ tools/power/cpupower/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/tools/power/cpupower/Makefile
+===================================================================
+--- linux.orig/tools/power/cpupower/Makefile
++++ linux/tools/power/cpupower/Makefile
+@@ -66,7 +66,7 @@ DESTDIR ?=
+
+ VERSION= $(shell ./utils/version-gen.sh)
+ LIB_MAJ= 0.0.1
+-LIB_MIN= 0
++LIB_MIN= 1
+
+ PACKAGE = cpupower
+ PACKAGE_BUGREPORT = linux-pm@vger.kernel.org
diff --git a/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch b/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch
new file mode 100644
index 000000000..0ad8fc6cd
--- /dev/null
+++ b/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch
@@ -0,0 +1,51 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 03 Nov 2016 15:25:26 -0600
+Subject: cpupower: Fix checks for CPU existence
+Forwarded: https://marc.info/?l=linux-pm&m=149248268214265
+
+Calls to cpufreq_cpu_exists(cpu) were converted to
+cpupower_is_cpu_online(cpu) when libcpupower was introduced and the
+former function was deleted. However, cpupower_is_cpu_online() does
+not distinguish physically absent and offline CPUs, and does not set
+errno.
+
+cpufreq-set has already been fixed (commit c25badc9ceb6).
+
+In cpufreq-bench, which prints an error message for offline CPUs,
+properly distinguish and report the zero and negative cases.
+
+Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library")
+Fixes: 53d1cd6b125f ("cpupowerutils: bench - Fix cpu online check")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+[carnil: Update/Refresh patch for 4.14.17: The issue with the
+incorrect check has been fixed with upstream commit 53d1cd6b125f.
+Keep in the patch the distinction and report for the zero and
+negative cases.]
+---
+Index: linux/tools/power/cpupower/bench/system.c
+===================================================================
+--- linux.orig/tools/power/cpupower/bench/system.c
++++ linux/tools/power/cpupower/bench/system.c
+@@ -58,12 +58,19 @@ long long int get_time()
+
+ int set_cpufreq_governor(char *governor, unsigned int cpu)
+ {
++ int rc;
+
+ dprintf("set %s as cpufreq governor\n", governor);
+
+- if (cpupower_is_cpu_online(cpu) != 1) {
+- perror("cpufreq_cpu_exists");
+- fprintf(stderr, "error: cpu %u does not exist\n", cpu);
++ rc = cpupower_is_cpu_online(cpu);
++ if (rc != 1) {
++ if (rc < 0)
++ fprintf(stderr, "cpupower_is_cpu_online: %s\n",
++ strerror(-rc));
++ else
++ fprintf(stderr,
++ "error: cpu %u is offline or does not exist\n",
++ cpu);
+ return -1;
+ }
+
diff --git a/debian/patches/bugfix/all/disable-some-marvell-phys.patch b/debian/patches/bugfix/all/disable-some-marvell-phys.patch
new file mode 100644
index 000000000..297b38c56
--- /dev/null
+++ b/debian/patches/bugfix/all/disable-some-marvell-phys.patch
@@ -0,0 +1,93 @@
+From: Ian Campbell <ijc@hellion.org.uk>
+Subject: phy/marvell: disable 4-port phys
+Date: Wed, 20 Nov 2013 08:30:14 +0000
+Bug-Debian: https://bugs.debian.org/723177
+Forwarded: http://thread.gmane.org/gmane.linux.debian.devel.bugs.general/1107774/
+
+The Marvell PHY was originally disabled because it can cause networking
+failures on some systems. According to Lennert Buytenhek this is because some
+of the variants added did not share the same register layout. Since the known
+cases are all 4-ports disable those variants (indicated by a 4 in the
+penultimate position of the model name) until they can be audited for
+correctness.
+
+[bwh: Also #if-out the init functions for these PHYs to avoid
+ compiler warnings]
+
+Index: linux/drivers/net/phy/marvell.c
+===================================================================
+--- linux.orig/drivers/net/phy/marvell.c
++++ linux/drivers/net/phy/marvell.c
+@@ -950,6 +950,7 @@ static int m88e1118_config_init(struct p
+ return genphy_soft_reset(phydev);
+ }
+
++#if 0
+ static int m88e1149_config_init(struct phy_device *phydev)
+ {
+ int err;
+@@ -975,7 +976,9 @@ static int m88e1149_config_init(struct p
+
+ return genphy_soft_reset(phydev);
+ }
++#endif
+
++#if 0
+ static int m88e1145_config_init_rgmii(struct phy_device *phydev)
+ {
+ int err;
+@@ -1050,6 +1053,7 @@ static int m88e1145_config_init(struct p
+
+ return 0;
+ }
++#endif
+
+ /* The VOD can be out of specification on link up. Poke an
+ * undocumented register, in an undocumented page, with a magic value
+@@ -2165,6 +2169,7 @@ static struct phy_driver marvell_drivers
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ },
++#if 0
+ {
+ .phy_id = MARVELL_PHY_ID_88E1145,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+@@ -2185,6 +2190,8 @@ static struct phy_driver marvell_drivers
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ },
++#endif
++#if 0
+ {
+ .phy_id = MARVELL_PHY_ID_88E1149R,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+@@ -2204,6 +2211,8 @@ static struct phy_driver marvell_drivers
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ },
++#endif
++#if 0
+ {
+ .phy_id = MARVELL_PHY_ID_88E1240,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+@@ -2223,6 +2232,7 @@ static struct phy_driver marvell_drivers
+ .get_strings = marvell_get_strings,
+ .get_stats = marvell_get_stats,
+ },
++#endif
+ {
+ .phy_id = MARVELL_PHY_ID_88E1116R,
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
+@@ -2359,9 +2369,9 @@ static struct mdio_device_id __maybe_unu
+ { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
+- { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
+- { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
+- { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
++/* { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, */
++/* { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, */
++/* { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, */
+ { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
+ { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
diff --git a/debian/patches/bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch b/debian/patches/bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch
new file mode 100644
index 000000000..97e5d0a64
--- /dev/null
+++ b/debian/patches/bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch
@@ -0,0 +1,52 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 23 Nov 2018 13:38:34 -0500
+Subject: media: Documentation/media: uapi: Explicitly say there are no
+ Invariant Sections
+Origin: https://git.kernel.org/linus/861c56c13d817b76e802d664e6ce7edb09cb9417
+Bug-Debian: https://bugs.debian.org/698668
+
+The GNU Free Documentation License allows for a work to specify
+Invariant Sections that are not allowed to be modified. (Debian
+considers that this makes such works non-free.)
+
+The Linux Media Infrastructure userspace API documentation does not
+specify any such sections, but it also doesn't say there are none (as
+is recommended by the license text). Make it explicit that there are
+none.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
+Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Marcus Metzler <mocm@metzlerbros.de>
+Signed-off-by: Michael Ira Krufky <mkrufky@gmail.com>
+Signed-off-by: Ralph Metzler <rjkm@metzlerbros.de>
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Signed-off-by: Sean Young <sean@mess.org>
+Signed-off-by: Sylwester Nawrocki <snawrocki@kernel.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Kate Stewart <kstewart@linuxfoundation.org>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+---
+ Documentation/media/media_uapi.rst | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Index: linux/Documentation/media/media_uapi.rst
+===================================================================
+--- linux.orig/Documentation/media/media_uapi.rst
++++ linux/Documentation/media/media_uapi.rst
+@@ -10,9 +10,9 @@ Linux Media Infrastructure userspace API
+
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.1 or
+-any later version published by the Free Software Foundation. A copy of
+-the license is included in the chapter entitled "GNU Free Documentation
+-License".
++any later version published by the Free Software Foundation, with no
++Invariant Sections. A copy of the license is included in the chapter
++entitled "GNU Free Documentation License".
+
+ .. only:: html
+
diff --git a/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch b/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch
new file mode 100644
index 000000000..633c5c34c
--- /dev/null
+++ b/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch
@@ -0,0 +1,2895 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: firmware: Remove redundant log messages from drivers
+Date: Sun, 09 Dec 2012 16:40:31 +0000
+Forwarded: no
+
+Now that firmware_class logs every success and failure consistently,
+many other log messages can be removed from drivers.
+
+This will probably need to be split up into multiple patches prior to
+upstream submission.
+
+Index: linux/arch/arm/mach-netx/xc.c
+===================================================================
+--- linux.orig/arch/arm/mach-netx/xc.c
++++ linux/arch/arm/mach-netx/xc.c
+@@ -127,10 +127,8 @@ int xc_request_firmware(struct xc *x)
+
+ ret = request_firmware(&fw, name, x->dev);
+
+- if (ret < 0) {
+- dev_err(x->dev, "request_firmware failed\n");
++ if (ret)
+ return ret;
+- }
+
+ head = (struct fw_header *)fw->data;
+ if (head->magic != 0x4e657458) {
+Index: linux/arch/x86/kernel/cpu/microcode/amd.c
+===================================================================
+--- linux.orig/arch/x86/kernel/cpu/microcode/amd.c
++++ linux/arch/x86/kernel/cpu/microcode/amd.c
+@@ -755,10 +755,8 @@ static enum ucode_state request_microcod
+ if (c->x86 >= 0x15)
+ snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86);
+
+- if (request_firmware_direct(&fw, (const char *)fw_name, device)) {
+- pr_debug("failed to load file %s\n", fw_name);
++ if (request_firmware_direct(&fw, (const char *)fw_name, device))
+ goto out;
+- }
+
+ ret = UCODE_ERROR;
+ if (*(u32 *)fw->data != UCODE_MAGIC) {
+Index: linux/drivers/atm/ambassador.c
+===================================================================
+--- linux.orig/drivers/atm/ambassador.c
++++ linux/drivers/atm/ambassador.c
+@@ -1929,10 +1929,8 @@ static int ucode_init(loader_block *lb,
+ int res;
+
+ res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev);
+- if (res) {
+- PRINTK (KERN_ERR, "Cannot load microcode data");
++ if (res)
+ return res;
+- }
+
+ /* First record contains just the start address */
+ rec = (const struct ihex_binrec *)fw->data;
+Index: linux/drivers/atm/fore200e.c
+===================================================================
+--- linux.orig/drivers/atm/fore200e.c
++++ linux/drivers/atm/fore200e.c
+@@ -2505,10 +2505,9 @@ static int fore200e_load_and_start_fw(st
+ return err;
+
+ sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT);
+- if ((err = request_firmware(&firmware, buf, device)) < 0) {
+- printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name);
++ err = request_firmware(&firmware, buf, device);
++ if (err)
+ return err;
+- }
+
+ fw_data = (const __le32 *)firmware->data;
+ fw_size = firmware->size / sizeof(u32);
+Index: linux/drivers/bluetooth/ath3k.c
+===================================================================
+--- linux.orig/drivers/bluetooth/ath3k.c
++++ linux/drivers/bluetooth/ath3k.c
+@@ -430,10 +430,8 @@ static int ath3k_load_patch(struct usb_d
+ le32_to_cpu(fw_version.rom_version));
+
+ ret = request_firmware(&firmware, filename, &udev->dev);
+- if (ret < 0) {
+- BT_ERR("Patch file not found %s", filename);
++ if (ret)
+ return ret;
+- }
+
+ pt_rom_version = get_unaligned_le32(firmware->data +
+ firmware->size - 8);
+@@ -493,10 +491,8 @@ static int ath3k_load_syscfg(struct usb_
+ le32_to_cpu(fw_version.rom_version), clk_value, ".dfu");
+
+ ret = request_firmware(&firmware, filename, &udev->dev);
+- if (ret < 0) {
+- BT_ERR("Configuration file not found %s", filename);
++ if (ret)
+ return ret;
+- }
+
+ ret = ath3k_load_fwfile(udev, firmware);
+ release_firmware(firmware);
+Index: linux/drivers/bluetooth/bcm203x.c
+===================================================================
+--- linux.orig/drivers/bluetooth/bcm203x.c
++++ linux/drivers/bluetooth/bcm203x.c
+@@ -189,7 +189,6 @@ static int bcm203x_probe(struct usb_inte
+ return -ENOMEM;
+
+ if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) {
+- BT_ERR("Mini driver request failed");
+ usb_free_urb(data->urb);
+ return -EIO;
+ }
+@@ -214,7 +213,6 @@ static int bcm203x_probe(struct usb_inte
+ release_firmware(firmware);
+
+ if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) {
+- BT_ERR("Firmware request failed");
+ usb_free_urb(data->urb);
+ kfree(data->buffer);
+ return -EIO;
+Index: linux/drivers/bluetooth/bfusb.c
+===================================================================
+--- linux.orig/drivers/bluetooth/bfusb.c
++++ linux/drivers/bluetooth/bfusb.c
+@@ -652,10 +652,8 @@ static int bfusb_probe(struct usb_interf
+ skb_queue_head_init(&data->pending_q);
+ skb_queue_head_init(&data->completed_q);
+
+- if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) {
+- BT_ERR("Firmware request failed");
++ if (request_firmware(&firmware, "bfubase.frm", &udev->dev))
+ goto done;
+- }
+
+ BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);
+
+Index: linux/drivers/bluetooth/bt3c_cs.c
+===================================================================
+--- linux.orig/drivers/bluetooth/bt3c_cs.c
++++ linux/drivers/bluetooth/bt3c_cs.c
+@@ -566,10 +566,8 @@ static int bt3c_open(struct bt3c_info *i
+
+ /* Load firmware */
+ err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev);
+- if (err < 0) {
+- BT_ERR("Firmware request failed");
++ if (err)
+ goto error;
+- }
+
+ err = bt3c_load_firmware(info, firmware->data, firmware->size);
+
+Index: linux/drivers/bluetooth/btmrvl_sdio.c
+===================================================================
+--- linux.orig/drivers/bluetooth/btmrvl_sdio.c
++++ linux/drivers/bluetooth/btmrvl_sdio.c
+@@ -455,8 +455,6 @@ static int btmrvl_sdio_download_helper(s
+ ret = request_firmware(&fw_helper, card->helper,
+ &card->func->dev);
+ if ((ret < 0) || !fw_helper) {
+- BT_ERR("request_firmware(helper) failed, error code = %d",
+- ret);
+ ret = -ENOENT;
+ goto done;
+ }
+@@ -555,8 +553,6 @@ static int btmrvl_sdio_download_fw_w_hel
+ ret = request_firmware(&fw_firmware, card->firmware,
+ &card->func->dev);
+ if ((ret < 0) || !fw_firmware) {
+- BT_ERR("request_firmware(firmware) failed, error code = %d",
+- ret);
+ ret = -ENOENT;
+ goto done;
+ }
+Index: linux/drivers/char/dsp56k.c
+===================================================================
+--- linux.orig/drivers/char/dsp56k.c
++++ linux/drivers/char/dsp56k.c
+@@ -140,11 +140,8 @@ static int dsp56k_upload(u_char __user *
+ }
+ err = request_firmware(&fw, fw_name, &pdev->dev);
+ platform_device_unregister(pdev);
+- if (err) {
+- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+- fw_name, err);
++ if (err)
+ return err;
+- }
+ if (fw->size % 3) {
+ printk(KERN_ERR "Bogus length %d in image \"%s\"\n",
+ fw->size, fw_name);
+Index: linux/drivers/dma/imx-sdma.c
+===================================================================
+--- linux.orig/drivers/dma/imx-sdma.c
++++ linux/drivers/dma/imx-sdma.c
+@@ -1674,11 +1674,8 @@ static void sdma_load_firmware(const str
+ const struct sdma_script_start_addrs *addr;
+ unsigned short *ram_code;
+
+- if (!fw) {
+- dev_info(sdma->dev, "external firmware not found, using ROM firmware\n");
+- /* In this case we just use the ROM firmware. */
++ if (!fw)
+ return;
+- }
+
+ if (fw->size < sizeof(*header))
+ goto err_firmware;
+Index: linux/drivers/gpu/drm/mga/mga_warp.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/mga/mga_warp.c
++++ linux/drivers/gpu/drm/mga/mga_warp.c
+@@ -79,11 +79,8 @@ int mga_warp_install_microcode(drm_mga_p
+ }
+ rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev);
+ platform_device_unregister(pdev);
+- if (rc) {
+- DRM_ERROR("mga: Failed to load microcode \"%s\"\n",
+- firmware_name);
++ if (rc)
+ return rc;
+- }
+
+ size = 0;
+ where = 0;
+Index: linux/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
++++ linux/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+@@ -1920,10 +1920,8 @@ gf100_gr_ctor_fw_legacy(struct gf100_gr
+ if (ret) {
+ snprintf(f, sizeof(f), "nouveau/%s", fwname);
+ ret = request_firmware(&fw, f, device->dev);
+- if (ret) {
+- nvkm_error(subdev, "failed to load %s\n", fwname);
++ if (ret)
+ return ret;
+- }
+ }
+
+ fuc->size = fw->size;
+Index: linux/drivers/gpu/drm/r128/r128_cce.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/r128/r128_cce.c
++++ linux/drivers/gpu/drm/r128/r128_cce.c
+@@ -154,11 +154,8 @@ static int r128_cce_load_microcode(drm_r
+ }
+ rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev);
+ platform_device_unregister(pdev);
+- if (rc) {
+- pr_err("r128_cce: Failed to load firmware \"%s\"\n",
+- FIRMWARE_NAME);
++ if (rc)
+ return rc;
+- }
+
+ if (fw->size != 256 * 8) {
+ pr_err("r128_cce: Bogus length %zu in firmware \"%s\"\n",
+Index: linux/drivers/gpu/drm/radeon/ni.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/radeon/ni.c
++++ linux/drivers/gpu/drm/radeon/ni.c
+@@ -830,9 +830,6 @@ int ni_init_microcode(struct radeon_devi
+
+ out:
+ if (err) {
+- if (err != -EINVAL)
+- pr_err("ni_cp: Failed to load firmware \"%s\"\n",
+- fw_name);
+ release_firmware(rdev->pfp_fw);
+ rdev->pfp_fw = NULL;
+ release_firmware(rdev->me_fw);
+Index: linux/drivers/gpu/drm/radeon/r100.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/radeon/r100.c
++++ linux/drivers/gpu/drm/radeon/r100.c
+@@ -1041,9 +1041,7 @@ static int r100_cp_init_microcode(struct
+ }
+
+ err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
+- if (err) {
+- pr_err("radeon_cp: Failed to load firmware \"%s\"\n", fw_name);
+- } else if (rdev->me_fw->size % 8) {
++ if (err == 0 && rdev->me_fw->size % 8) {
+ pr_err("radeon_cp: Bogus length %zu in firmware \"%s\"\n",
+ rdev->me_fw->size, fw_name);
+ err = -EINVAL;
+Index: linux/drivers/gpu/drm/radeon/r600.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/radeon/r600.c
++++ linux/drivers/gpu/drm/radeon/r600.c
+@@ -2593,9 +2593,6 @@ int r600_init_microcode(struct radeon_de
+
+ out:
+ if (err) {
+- if (err != -EINVAL)
+- pr_err("r600_cp: Failed to load firmware \"%s\"\n",
+- fw_name);
+ release_firmware(rdev->pfp_fw);
+ rdev->pfp_fw = NULL;
+ release_firmware(rdev->me_fw);
+Index: linux/drivers/infiniband/hw/qib/qib_sd7220.c
+===================================================================
+--- linux.orig/drivers/infiniband/hw/qib/qib_sd7220.c
++++ linux/drivers/infiniband/hw/qib/qib_sd7220.c
+@@ -406,10 +406,8 @@ int qib_sd7220_init(struct qib_devdata *
+ }
+
+ ret = request_firmware(&fw, SD7220_FW_NAME, &dd->pcidev->dev);
+- if (ret) {
+- qib_dev_err(dd, "Failed to load IB SERDES image\n");
++ if (ret)
+ goto done;
+- }
+
+ /* Substitute our deduced value for was_reset */
+ ret = qib_ibsd_ucode_loaded(dd->pport, fw);
+Index: linux/drivers/input/touchscreen/atmel_mxt_ts.c
+===================================================================
+--- linux.orig/drivers/input/touchscreen/atmel_mxt_ts.c
++++ linux/drivers/input/touchscreen/atmel_mxt_ts.c
+@@ -2783,10 +2783,8 @@ static int mxt_load_fw(struct device *de
+ int ret;
+
+ ret = request_firmware(&fw, fn, dev);
+- if (ret) {
+- dev_err(dev, "Unable to open firmware %s\n", fn);
++ if (ret)
+ return ret;
+- }
+
+ /* Check for incorrect enc file */
+ ret = mxt_check_firmware_format(dev, fw);
+Index: linux/drivers/isdn/hardware/mISDN/speedfax.c
+===================================================================
+--- linux.orig/drivers/isdn/hardware/mISDN/speedfax.c
++++ linux/drivers/isdn/hardware/mISDN/speedfax.c
+@@ -392,11 +392,8 @@ setup_instance(struct sfax_hw *card)
+ card->isar.owner = THIS_MODULE;
+
+ err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev);
+- if (err < 0) {
+- pr_info("%s: firmware request failed %d\n",
+- card->name, err);
++ if (err)
+ goto error_fw;
+- }
+ if (debug & DEBUG_HW)
+ pr_notice("%s: got firmware %zu bytes\n",
+ card->name, firmware->size);
+Index: linux/drivers/media/tuners/tuner-xc2028.c
+===================================================================
+--- linux.orig/drivers/media/tuners/tuner-xc2028.c
++++ linux/drivers/media/tuners/tuner-xc2028.c
+@@ -1367,7 +1367,6 @@ static void load_firmware_cb(const struc
+
+ tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
+ if (!fw) {
+- tuner_err("Could not load firmware %s.\n", priv->fname);
+ priv->state = XC2028_NODEV;
+ return;
+ }
+Index: linux/drivers/media/usb/dvb-usb/dib0700_devices.c
+===================================================================
+--- linux.orig/drivers/media/usb/dvb-usb/dib0700_devices.c
++++ linux/drivers/media/usb/dvb-usb/dib0700_devices.c
+@@ -2416,12 +2416,9 @@ static int stk9090m_frontend_attach(stru
+
+ dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
+
+- if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
+- deb_info("%s: Upload failed. (file not found?)\n", __func__);
++ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev))
+ return -ENODEV;
+- } else {
+- deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size);
+- }
++ deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size);
+ stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
+ stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
+
+@@ -2486,12 +2483,9 @@ static int nim9090md_frontend_attach(str
+ msleep(20);
+ dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
+
+- if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
+- deb_info("%s: Upload failed. (file not found?)\n", __func__);
++ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev))
+ return -EIO;
+- } else {
+- deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size);
+- }
++ deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size);
+ nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
+ nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
+ nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
+Index: linux/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+===================================================================
+--- linux.orig/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
++++ linux/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+@@ -89,13 +89,9 @@ int dvb_usb_download_firmware(struct usb
+ int ret;
+ const struct firmware *fw = NULL;
+
+- if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) {
+- err("did not find the firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware",
+- props->firmware,ret);
++ ret = request_firmware(&fw, props->firmware, &udev->dev);
++ if (ret)
+ return ret;
+- }
+-
+- info("downloading firmware from file '%s'",props->firmware);
+
+ switch (props->usb_ctrl) {
+ case CYPRESS_AN2135:
+Index: linux/drivers/media/usb/dvb-usb/gp8psk.c
+===================================================================
+--- linux.orig/drivers/media/usb/dvb-usb/gp8psk.c
++++ linux/drivers/media/usb/dvb-usb/gp8psk.c
+@@ -134,19 +134,14 @@ static int gp8psk_load_bcm4500fw(struct
+ const u8 *ptr;
+ u8 *buf;
+ if ((ret = request_firmware(&fw, bcm4500_firmware,
+- &d->udev->dev)) != 0) {
+- err("did not find the bcm4500 firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware",
+- bcm4500_firmware,ret);
++ &d->udev->dev)) != 0)
+ return ret;
+- }
+
+ ret = -EINVAL;
+
+ if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
+ goto out_rel_fw;
+
+- info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware);
+-
+ ptr = fw->data;
+ buf = kmalloc(64, GFP_KERNEL);
+ if (!buf) {
+Index: linux/drivers/media/usb/dvb-usb/opera1.c
+===================================================================
+--- linux.orig/drivers/media/usb/dvb-usb/opera1.c
++++ linux/drivers/media/usb/dvb-usb/opera1.c
+@@ -453,8 +453,6 @@ static int opera1_xilinx_load_firmware(s
+ info("start downloading fpga firmware %s",filename);
+
+ if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) {
+- err("did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware",
+- filename);
+ return ret;
+ } else {
+ p = kmalloc(fw->size, GFP_KERNEL);
+Index: linux/drivers/media/dvb-frontends/af9013.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/af9013.c
++++ linux/drivers/media/dvb-frontends/af9013.c
+@@ -1059,14 +1059,8 @@ static int af9013_download_firmware(stru
+
+ /* Request the firmware, will block and timeout */
+ ret = request_firmware(&firmware, name, &client->dev);
+- if (ret) {
+- dev_info(&client->dev, "firmware file '%s' not found %d\n",
+- name, ret);
++ if (ret)
+ goto err;
+- }
+-
+- dev_info(&client->dev, "downloading firmware from file '%s'\n",
+- name);
+
+ /* Write firmware checksum & size */
+ for (i = 0; i < firmware->size; i++)
+Index: linux/drivers/media/dvb-frontends/bcm3510.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/bcm3510.c
++++ linux/drivers/media/dvb-frontends/bcm3510.c
+@@ -636,10 +636,9 @@ static int bcm3510_download_firmware(str
+ int ret,i;
+
+ deb_info("requesting firmware\n");
+- if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) {
+- err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret);
++ ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE);
++ if (ret)
+ return ret;
+- }
+ deb_info("got firmware: %zu\n", fw->size);
+
+ b = fw->data;
+Index: linux/drivers/media/dvb-frontends/cx24116.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/cx24116.c
++++ linux/drivers/media/dvb-frontends/cx24116.c
+@@ -491,13 +491,8 @@ static int cx24116_firmware_ondemand(str
+ __func__, CX24116_DEFAULT_FIRMWARE);
+ ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE,
+ state->i2c->dev.parent);
+- printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n",
+- __func__);
+- if (ret) {
+- printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n",
+- __func__);
++ if (ret)
+ return ret;
+- }
+
+ /* Make sure we don't recurse back through here
+ * during loading */
+Index: linux/drivers/media/dvb-frontends/drxd_hard.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/drxd_hard.c
++++ linux/drivers/media/dvb-frontends/drxd_hard.c
+@@ -903,10 +903,8 @@ static int load_firmware(struct drxd_sta
+ {
+ const struct firmware *fw;
+
+- if (request_firmware(&fw, fw_name, state->dev) < 0) {
+- printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name);
++ if (request_firmware(&fw, fw_name, state->dev))
+ return -EIO;
+- }
+
+ state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ if (!state->microcode) {
+Index: linux/drivers/media/dvb-frontends/drxk_hard.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/drxk_hard.c
++++ linux/drivers/media/dvb-frontends/drxk_hard.c
+@@ -6281,10 +6281,6 @@ static void load_firmware_cb(const struc
+
+ dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded");
+ if (!fw) {
+- pr_err("Could not load firmware file %s.\n",
+- state->microcode_name);
+- pr_info("Copy %s to your hotplug directory!\n",
+- state->microcode_name);
+ state->microcode_name = NULL;
+
+ /*
+Index: linux/drivers/media/dvb-frontends/ds3000.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/ds3000.c
++++ linux/drivers/media/dvb-frontends/ds3000.c
+@@ -360,12 +360,8 @@ static int ds3000_firmware_ondemand(stru
+ DS3000_DEFAULT_FIRMWARE);
+ ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
+ state->i2c->dev.parent);
+- printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
+- if (ret) {
+- printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n",
+- __func__);
++ if (ret)
+ return ret;
+- }
+
+ ret = ds3000_load_firmware(fe, fw);
+ if (ret)
+Index: linux/drivers/media/dvb-frontends/nxt200x.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/nxt200x.c
++++ linux/drivers/media/dvb-frontends/nxt200x.c
+@@ -886,12 +886,8 @@ static int nxt2002_init(struct dvb_front
+ __func__, NXT2002_DEFAULT_FIRMWARE);
+ ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE,
+ state->i2c->dev.parent);
+- pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
+- if (ret) {
+- pr_err("%s: No firmware uploaded (timeout or file not found?)\n",
+- __func__);
++ if (ret)
+ return ret;
+- }
+
+ ret = nxt2002_load_firmware(fe, fw);
+ release_firmware(fw);
+@@ -953,12 +949,8 @@ static int nxt2004_init(struct dvb_front
+ __func__, NXT2004_DEFAULT_FIRMWARE);
+ ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE,
+ state->i2c->dev.parent);
+- pr_debug("%s: Waiting for firmware upload(2)...\n", __func__);
+- if (ret) {
+- pr_err("%s: No firmware uploaded (timeout or file not found?)\n",
+- __func__);
++ if (ret)
+ return ret;
+- }
+
+ ret = nxt2004_load_firmware(fe, fw);
+ release_firmware(fw);
+Index: linux/drivers/media/dvb-frontends/or51132.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/or51132.c
++++ linux/drivers/media/dvb-frontends/or51132.c
+@@ -337,10 +337,8 @@ static int or51132_set_parameters(struct
+ printk("or51132: Waiting for firmware upload(%s)...\n",
+ fwname);
+ ret = request_firmware(&fw, fwname, state->i2c->dev.parent);
+- if (ret) {
+- printk(KERN_WARNING "or51132: No firmware uploaded(timeout or file not found?)\n");
++ if (ret)
+ return ret;
+- }
+ ret = or51132_load_firmware(fe, fw);
+ release_firmware(fw);
+ if (ret) {
+Index: linux/drivers/media/dvb-frontends/or51211.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/or51211.c
++++ linux/drivers/media/dvb-frontends/or51211.c
+@@ -371,11 +371,8 @@ static int or51211_init(struct dvb_front
+ OR51211_DEFAULT_FIRMWARE);
+ ret = config->request_firmware(fe, &fw,
+ OR51211_DEFAULT_FIRMWARE);
+- pr_info("Got Hotplug firmware\n");
+- if (ret) {
+- pr_warn("No firmware uploaded (timeout or file not found?)\n");
++ if (ret)
+ return ret;
+- }
+
+ ret = or51211_load_firmware(fe, fw);
+ release_firmware(fw);
+Index: linux/drivers/media/dvb-frontends/sp8870.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/sp8870.c
++++ linux/drivers/media/dvb-frontends/sp8870.c
+@@ -315,10 +315,8 @@ static int sp8870_init (struct dvb_front
+
+ /* request the firmware, this will block until someone uploads it */
+ printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE);
+- if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) {
+- printk("sp8870: no firmware upload (timeout or file not found?)\n");
++ if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE))
+ return -EIO;
+- }
+
+ if (sp8870_firmware_upload(state, fw)) {
+ printk("sp8870: writing firmware to device failed\n");
+Index: linux/drivers/media/dvb-frontends/sp887x.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/sp887x.c
++++ linux/drivers/media/dvb-frontends/sp887x.c
+@@ -526,10 +526,8 @@ static int sp887x_init(struct dvb_fronte
+ /* request the firmware, this will block until someone uploads it */
+ printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE);
+ ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE);
+- if (ret) {
+- printk("sp887x: no firmware upload (timeout or file not found?)\n");
++ if (ret)
+ return ret;
+- }
+
+ ret = sp887x_initial_setup(fe, fw);
+ release_firmware(fw);
+Index: linux/drivers/media/dvb-frontends/tda10048.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/tda10048.c
++++ linux/drivers/media/dvb-frontends/tda10048.c
+@@ -495,8 +495,6 @@ static int tda10048_firmware_upload(stru
+ ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE,
+ state->i2c->dev.parent);
+ if (ret) {
+- printk(KERN_ERR "%s: Upload failed. (file not found?)\n",
+- __func__);
+ return -EIO;
+ } else {
+ printk(KERN_INFO "%s: firmware read %zu bytes.\n",
+Index: linux/drivers/media/dvb-frontends/tda1004x.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/tda1004x.c
++++ linux/drivers/media/dvb-frontends/tda1004x.c
+@@ -401,10 +401,8 @@ static int tda10045_fwupload(struct dvb_
+ /* request the firmware, this will block until someone uploads it */
+ printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE);
+ ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
+- if (ret) {
+- printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
++ if (ret)
+ return ret;
+- }
+
+ /* reset chip */
+ tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0);
+@@ -545,7 +543,6 @@ static int tda10046_fwupload(struct dvb_
+ /* remain compatible to old bug: try to load with tda10045 image name */
+ ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE);
+ if (ret) {
+- printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n");
+ return ret;
+ } else {
+ printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n",
+Index: linux/drivers/media/dvb-frontends/tda10071.c
+===================================================================
+--- linux.orig/drivers/media/dvb-frontends/tda10071.c
++++ linux/drivers/media/dvb-frontends/tda10071.c
+@@ -850,12 +850,8 @@ static int tda10071_init(struct dvb_fron
+
+ /* request the firmware, this will block and timeout */
+ ret = request_firmware(&fw, fw_file, &client->dev);
+- if (ret) {
+- dev_err(&client->dev,
+- "did not find the firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware\n",
+- fw_file, ret);
++ if (ret)
+ goto error;
+- }
+
+ /* init */
+ for (i = 0; i < ARRAY_SIZE(tab2); i++) {
+Index: linux/drivers/media/pci/ngene/ngene-core.c
+===================================================================
+--- linux.orig/drivers/media/pci/ngene/ngene-core.c
++++ linux/drivers/media/pci/ngene/ngene-core.c
+@@ -1253,19 +1253,14 @@ static int ngene_load_firm(struct ngene
+ break;
+ }
+
+- if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) {
+- dev_err(pdev, "Could not load firmware file %s.\n", fw_name);
+- dev_info(pdev, "Copy %s to your hotplug directory!\n",
+- fw_name);
++ if (request_firmware(&fw, fw_name, &dev->pci_dev->dev))
+ return -1;
+- }
+ if (size == 0)
+ size = fw->size;
+ if (size != fw->size) {
+ dev_err(pdev, "Firmware %s has invalid size!", fw_name);
+ err = -1;
+ } else {
+- dev_info(pdev, "Loading firmware file %s.\n", fw_name);
+ ngene_fw = (u8 *) fw->data;
+ err = ngene_command_load_firmware(dev, ngene_fw, size);
+ }
+Index: linux/drivers/media/common/siano/smscoreapi.c
+===================================================================
+--- linux.orig/drivers/media/common/siano/smscoreapi.c
++++ linux/drivers/media/common/siano/smscoreapi.c
+@@ -1164,10 +1164,8 @@ static int smscore_load_firmware_from_fi
+ return -EINVAL;
+
+ rc = request_firmware(&fw, fw_filename, coredev->device);
+- if (rc < 0) {
+- pr_err("failed to open firmware file '%s'\n", fw_filename);
++ if (rc < 0)
+ return rc;
+- }
+ pr_debug("read fw %s, buffer size=0x%zx\n", fw_filename, fw->size);
+ fw_buf = kmalloc(ALIGN(fw->size + sizeof(struct sms_firmware),
+ SMS_ALLOC_ALIGNMENT), GFP_KERNEL | coredev->gfp_buf_flags);
+Index: linux/drivers/media/pci/ttpci/av7110.c
+===================================================================
+--- linux.orig/drivers/media/pci/ttpci/av7110.c
++++ linux/drivers/media/pci/ttpci/av7110.c
+@@ -1516,13 +1516,8 @@ static int get_firmware(struct av7110* a
+ /* request the av7110 firmware, this will block until someone uploads it */
+ ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
+ if (ret) {
+- if (ret == -ENOENT) {
+- printk(KERN_ERR "dvb-ttpci: could not load firmware, file not found: dvb-ttpci-01.fw\n");
+- printk(KERN_ERR "dvb-ttpci: usually this should be in /usr/lib/hotplug/firmware or /lib/firmware\n");
+- printk(KERN_ERR "dvb-ttpci: and can be downloaded from https://linuxtv.org/download/dvb/firmware/\n");
+- } else
+- printk(KERN_ERR "dvb-ttpci: cannot request firmware (error %i)\n",
+- ret);
++ if (ret == -ENOENT)
++ printk(KERN_ERR "dvb-ttpci: firmware can be downloaded from https://linuxtv.org/download/dvb/firmware/\n");
+ return -EINVAL;
+ }
+
+Index: linux/drivers/media/pci/ttpci/av7110_hw.c
+===================================================================
+--- linux.orig/drivers/media/pci/ttpci/av7110_hw.c
++++ linux/drivers/media/pci/ttpci/av7110_hw.c
+@@ -247,11 +247,8 @@ int av7110_bootarm(struct av7110 *av7110
+ //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT);
+
+ ret = request_firmware(&fw, fw_name, &dev->pci->dev);
+- if (ret) {
+- printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n",
+- fw_name);
++ if (ret)
+ return ret;
+- }
+
+ mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size);
+ release_firmware(fw);
+Index: linux/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+===================================================================
+--- linux.orig/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
++++ linux/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c
+@@ -295,10 +295,8 @@ static int ttusb_boot_dsp(struct ttusb *
+
+ err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin",
+ &ttusb->dev->dev);
+- if (err) {
+- printk(KERN_ERR "ttusb-budget: failed to request firmware\n");
++ if (err)
+ return err;
+- }
+
+ /* BootBlock */
+ b[0] = 0xaa;
+Index: linux/drivers/media/usb/ttusb-dec/ttusb_dec.c
+===================================================================
+--- linux.orig/drivers/media/usb/ttusb-dec/ttusb_dec.c
++++ linux/drivers/media/usb/ttusb-dec/ttusb_dec.c
+@@ -1334,11 +1334,8 @@ static int ttusb_dec_boot_dsp(struct ttu
+ dprintk("%s\n", __func__);
+
+ result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev);
+- if (result) {
+- printk(KERN_ERR "%s: Firmware (%s) unavailable.\n",
+- __func__, dec->firmware_name);
++ if (result)
+ return result;
+- }
+
+ firmware = fw_entry->data;
+ firmware_size = fw_entry->size;
+Index: linux/drivers/media/radio/radio-wl1273.c
+===================================================================
+--- linux.orig/drivers/media/radio/radio-wl1273.c
++++ linux/drivers/media/radio/radio-wl1273.c
+@@ -510,11 +510,8 @@ static int wl1273_fm_upload_firmware_pat
+ * Uploading the firmware patch is not always necessary,
+ * so we only print an info message.
+ */
+- if (request_firmware(&fw_p, fw_name, dev)) {
+- dev_info(dev, "%s - %s not found\n", __func__, fw_name);
+-
++ if (request_firmware(&fw_p, fw_name, dev))
+ return 0;
+- }
+
+ ptr = (__u8 *) fw_p->data;
+ packet_num = ptr[0];
+Index: linux/drivers/media/radio/wl128x/fmdrv_common.c
+===================================================================
+--- linux.orig/drivers/media/radio/wl128x/fmdrv_common.c
++++ linux/drivers/media/radio/wl128x/fmdrv_common.c
+@@ -1245,10 +1245,8 @@ static int fm_download_firmware(struct f
+
+ ret = request_firmware(&fw_entry, fw_name,
+ &fmdev->radio_dev->dev);
+- if (ret < 0) {
+- fmerr("Unable to read firmware(%s) content\n", fw_name);
++ if (ret)
+ return ret;
+- }
+ fmdbg("Firmware(%s) length : %zu bytes\n", fw_name, fw_entry->size);
+
+ fw_data = (void *)fw_entry->data;
+Index: linux/drivers/media/pci/bt8xx/bttv-cards.c
+===================================================================
+--- linux.orig/drivers/media/pci/bt8xx/bttv-cards.c
++++ linux/drivers/media/pci/bt8xx/bttv-cards.c
+@@ -3916,10 +3916,8 @@ static int pvr_boot(struct bttv *btv)
+ int rc;
+
+ rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
+- if (rc != 0) {
+- pr_warn("%d: no altera firmware [via hotplug]\n", btv->c.nr);
++ if (rc != 0)
+ return rc;
+- }
+ rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
+ pr_info("%d: altera firmware upload %s\n",
+ btv->c.nr, (rc < 0) ? "failed" : "ok");
+Index: linux/drivers/media/usb/cpia2/cpia2_core.c
+===================================================================
+--- linux.orig/drivers/media/usb/cpia2/cpia2_core.c
++++ linux/drivers/media/usb/cpia2/cpia2_core.c
+@@ -921,11 +921,8 @@ static int apply_vp_patch(struct camera_
+ struct cpia2_command cmd;
+
+ ret = request_firmware(&fw, fw_name, &cam->dev->dev);
+- if (ret) {
+- printk(KERN_ERR "cpia2: failed to load VP patch \"%s\"\n",
+- fw_name);
++ if (ret)
+ return ret;
+- }
+
+ cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP;
+ cmd.direction = TRANSFER_WRITE;
+Index: linux/drivers/media/pci/cx18/cx18-av-firmware.c
+===================================================================
+--- linux.orig/drivers/media/pci/cx18/cx18-av-firmware.c
++++ linux/drivers/media/pci/cx18/cx18-av-firmware.c
+@@ -79,10 +79,8 @@ int cx18_av_loadfw(struct cx18 *cx)
+ int i;
+ int retries1 = 0;
+
+- if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
+- CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
++ if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0)
+ return -EINVAL;
+- }
+
+ /* The firmware load often has byte errors, so allow for several
+ retries, both at byte level and at the firmware load level. */
+Index: linux/drivers/media/pci/cx18/cx18-dvb.c
+===================================================================
+--- linux.orig/drivers/media/pci/cx18/cx18-dvb.c
++++ linux/drivers/media/pci/cx18/cx18-dvb.c
+@@ -137,9 +137,7 @@ static int yuan_mpc718_mt352_reqfw(struc
+ int ret;
+
+ ret = request_firmware(fw, fn, &cx->pci_dev->dev);
+- if (ret)
+- CX18_ERR("Unable to open firmware file %s\n", fn);
+- else {
++ if (!ret) {
+ size_t sz = (*fw)->size;
+ if (sz < 2 || sz > 64 || (sz % 2) != 0) {
+ CX18_ERR("Firmware %s has a bad size: %lu bytes\n",
+Index: linux/drivers/media/pci/cx18/cx18-firmware.c
+===================================================================
+--- linux.orig/drivers/media/pci/cx18/cx18-firmware.c
++++ linux/drivers/media/pci/cx18/cx18-firmware.c
+@@ -101,11 +101,8 @@ static int load_cpu_fw_direct(const char
+ u32 __iomem *dst = (u32 __iomem *)mem;
+ const u32 *src;
+
+- if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
+- CX18_ERR("Unable to open firmware %s\n", fn);
+- CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
++ if (request_firmware(&fw, fn, &cx->pci_dev->dev))
+ return -ENOMEM;
+- }
+
+ src = (const u32 *)fw->data;
+
+@@ -146,8 +143,6 @@ static int load_apu_fw_direct(const char
+ int sz;
+
+ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
+- CX18_ERR("unable to open firmware %s\n", fn);
+- CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
+ cx18_setup_page(cx, 0);
+ return -ENOMEM;
+ }
+Index: linux/drivers/media/usb/cx231xx/cx231xx-417.c
+===================================================================
+--- linux.orig/drivers/media/usb/cx231xx/cx231xx-417.c
++++ linux/drivers/media/usb/cx231xx/cx231xx-417.c
+@@ -996,11 +996,6 @@ static int cx231xx_load_firmware(struct
+ dev->dev);
+
+ if (retval != 0) {
+- dev_err(dev->dev,
+- "ERROR: Hotplug firmware request failed (%s).\n",
+- CX231xx_FIRM_IMAGE_NAME);
+- dev_err(dev->dev,
+- "Please fix your hotplug setup, the board will not work without firmware loaded!\n");
+ vfree(p_current_fw);
+ vfree(p_buffer);
+ return retval;
+Index: linux/drivers/media/pci/cx23885/cx23885-417.c
+===================================================================
+--- linux.orig/drivers/media/pci/cx23885/cx23885-417.c
++++ linux/drivers/media/pci/cx23885/cx23885-417.c
+@@ -929,12 +929,8 @@ static int cx23885_load_firmware(struct
+ retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME,
+ &dev->pci->dev);
+
+- if (retval != 0) {
+- pr_err("ERROR: Hotplug firmware request failed (%s).\n",
+- CX23885_FIRM_IMAGE_NAME);
+- pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n");
++ if (retval != 0)
+ return -1;
+- }
+
+ if (firmware->size != CX23885_FIRM_IMAGE_SIZE) {
+ pr_err("ERROR: Firmware size mismatch (have %zu, expected %d)\n",
+Index: linux/drivers/media/pci/cx23885/cx23885-cards.c
+===================================================================
+--- linux.orig/drivers/media/pci/cx23885/cx23885-cards.c
++++ linux/drivers/media/pci/cx23885/cx23885-cards.c
+@@ -2425,10 +2425,7 @@ void cx23885_card_setup(struct cx23885_d
+ cinfo.rev, filename);
+
+ ret = request_firmware(&fw, filename, &dev->pci->dev);
+- if (ret != 0)
+- pr_err("did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware.",
+- filename);
+- else
++ if (ret == 0)
+ altera_init(&netup_config, fw);
+
+ release_firmware(fw);
+Index: linux/drivers/media/i2c/cx25840/cx25840-firmware.c
+===================================================================
+--- linux.orig/drivers/media/i2c/cx25840/cx25840-firmware.c
++++ linux/drivers/media/i2c/cx25840/cx25840-firmware.c
+@@ -122,10 +122,8 @@ int cx25840_loadfw(struct i2c_client *cl
+ if (is_cx231xx(state) && max_buf_size > 16)
+ max_buf_size = 16;
+
+- if (request_firmware(&fw, fwname, FWDEV(client)) != 0) {
+- v4l_err(client, "unable to open firmware %s\n", fwname);
++ if (request_firmware(&fw, fwname, FWDEV(client)) != 0)
+ return -EINVAL;
+- }
+
+ start_fw_load(client);
+
+Index: linux/drivers/media/pci/cx88/cx88-blackbird.c
+===================================================================
+--- linux.orig/drivers/media/pci/cx88/cx88-blackbird.c
++++ linux/drivers/media/pci/cx88/cx88-blackbird.c
+@@ -471,12 +471,8 @@ static int blackbird_load_firmware(struc
+ retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME,
+ &dev->pci->dev);
+
+- if (retval != 0) {
+- pr_err("Hotplug firmware request failed (%s).\n",
+- CX2341X_FIRM_ENC_FILENAME);
+- pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n");
++ if (retval != 0)
+ return -EIO;
+- }
+
+ if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) {
+ pr_err("Firmware size mismatch (have %zd, expected %d)\n",
+Index: linux/drivers/media/usb/gspca/vicam.c
+===================================================================
+--- linux.orig/drivers/media/usb/gspca/vicam.c
++++ linux/drivers/media/usb/gspca/vicam.c
+@@ -239,10 +239,8 @@ static int sd_init(struct gspca_dev *gsp
+
+ ret = request_ihex_firmware(&fw, VICAM_FIRMWARE,
+ &gspca_dev->dev->dev);
+- if (ret) {
+- pr_err("Failed to load \"vicam/firmware.fw\": %d\n", ret);
++ if (ret)
+ return ret;
+- }
+
+ firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!firmware_buf) {
+Index: linux/drivers/media/pci/ivtv/ivtv-firmware.c
+===================================================================
+--- linux.orig/drivers/media/pci/ivtv/ivtv-firmware.c
++++ linux/drivers/media/pci/ivtv/ivtv-firmware.c
+@@ -80,8 +80,6 @@ retry:
+ release_firmware(fw);
+ return size;
+ }
+- IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size);
+- IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n");
+ return -ENOMEM;
+ }
+
+Index: linux/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+===================================================================
+--- linux.orig/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
++++ linux/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+@@ -1379,25 +1379,6 @@ static int pvr2_locate_firmware(struct p
+ "request_firmware fatal error with code=%d",ret);
+ return ret;
+ }
+- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+- "***WARNING*** Device %s firmware seems to be missing.",
+- fwtypename);
+- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+- "Did you install the pvrusb2 firmware files in their proper location?");
+- if (fwcount == 1) {
+- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+- "request_firmware unable to locate %s file %s",
+- fwtypename,fwnames[0]);
+- } else {
+- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+- "request_firmware unable to locate one of the following %s files:",
+- fwtypename);
+- for (idx = 0; idx < fwcount; idx++) {
+- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+- "request_firmware: Failed to find %s",
+- fwnames[idx]);
+- }
+- }
+ return ret;
+ }
+
+Index: linux/drivers/media/usb/s2255/s2255drv.c
+===================================================================
+--- linux.orig/drivers/media/usb/s2255/s2255drv.c
++++ linux/drivers/media/usb/s2255/s2255drv.c
+@@ -2298,10 +2298,8 @@ static int s2255_probe(struct usb_interf
+ }
+ /* load the first chunk */
+ if (request_firmware(&dev->fw_data->fw,
+- FIRMWARE_FILE_NAME, &dev->udev->dev)) {
+- dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n");
++ FIRMWARE_FILE_NAME, &dev->udev->dev))
+ goto errorREQFW;
+- }
+ /* check the firmware is valid */
+ fw_size = dev->fw_data->fw->size;
+ pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8];
+Index: linux/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+===================================================================
+--- linux.orig/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
++++ linux/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c
+@@ -69,10 +69,8 @@ int s5p_mfc_load_firmware(struct s5p_mfc
+ }
+ }
+
+- if (err != 0) {
+- mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
++ if (err != 0)
+ return -EINVAL;
+- }
+ if (fw_blob->size > dev->fw_buf.size) {
+ mfc_err("MFC firmware is too big to be loaded\n");
+ release_firmware(fw_blob);
+Index: linux/drivers/media/pci/saa7164/saa7164-fw.c
+===================================================================
+--- linux.orig/drivers/media/pci/saa7164/saa7164-fw.c
++++ linux/drivers/media/pci/saa7164/saa7164-fw.c
+@@ -416,11 +416,8 @@ int saa7164_downloadfirmware(struct saa7
+ __func__, fwname);
+
+ ret = request_firmware(&fw, fwname, &dev->pci->dev);
+- if (ret) {
+- printk(KERN_ERR "%s() Upload failed. (file not found?)\n",
+- __func__);
++ if (ret)
+ return -ENOMEM;
+- }
+
+ printk(KERN_INFO "%s() firmware read %zu bytes.\n",
+ __func__, fw->size);
+Index: linux/drivers/misc/ti-st/st_kim.c
+===================================================================
+--- linux.orig/drivers/misc/ti-st/st_kim.c
++++ linux/drivers/misc/ti-st/st_kim.c
+@@ -301,11 +301,8 @@ static long download_firmware(struct kim
+ request_firmware(&kim_gdata->fw_entry, bts_scr_name,
+ &kim_gdata->kim_pdev->dev);
+ if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) ||
+- (kim_gdata->fw_entry->size == 0))) {
+- pr_err(" request_firmware failed(errno %ld) for %s", err,
+- bts_scr_name);
++ (kim_gdata->fw_entry->size == 0)))
+ return -EINVAL;
+- }
+ ptr = (void *)kim_gdata->fw_entry->data;
+ len = kim_gdata->fw_entry->size;
+ /* bts_header to remove out magic number and
+Index: linux/drivers/net/can/softing/softing_fw.c
+===================================================================
+--- linux.orig/drivers/net/can/softing/softing_fw.c
++++ linux/drivers/net/can/softing/softing_fw.c
+@@ -237,11 +237,8 @@ int softing_load_app_fw(const char *file
+ int8_t type_end = 0, type_entrypoint = 0;
+
+ ret = request_firmware(&fw, file, &card->pdev->dev);
+- if (ret) {
+- dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n",
+- file, ret);
++ if (ret)
+ return ret;
+- }
+ dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n",
+ file, (unsigned long)fw->size);
+ /* parse the firmware */
+Index: linux/drivers/net/ethernet/3com/typhoon.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/3com/typhoon.c
++++ linux/drivers/net/ethernet/3com/typhoon.c
+@@ -1283,11 +1283,8 @@ typhoon_request_firmware(struct typhoon
+ return 0;
+
+ err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev);
+- if (err) {
+- netdev_err(tp->dev, "Failed to load firmware \"%s\"\n",
+- FIRMWARE_NAME);
++ if (err)
+ return err;
+- }
+
+ image_data = typhoon_fw->data;
+ remaining = typhoon_fw->size;
+Index: linux/drivers/net/ethernet/adaptec/starfire.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/adaptec/starfire.c
++++ linux/drivers/net/ethernet/adaptec/starfire.c
+@@ -1015,11 +1015,8 @@ static int netdev_open(struct net_device
+ #endif /* VLAN_SUPPORT */
+
+ retval = request_firmware(&fw_rx, FIRMWARE_RX, &np->pci_dev->dev);
+- if (retval) {
+- printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
+- FIRMWARE_RX);
++ if (retval)
+ goto out_init;
+- }
+ if (fw_rx->size % 4) {
+ printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
+ fw_rx->size, FIRMWARE_RX);
+@@ -1027,11 +1024,8 @@ static int netdev_open(struct net_device
+ goto out_rx;
+ }
+ retval = request_firmware(&fw_tx, FIRMWARE_TX, &np->pci_dev->dev);
+- if (retval) {
+- printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n",
+- FIRMWARE_TX);
++ if (retval)
+ goto out_rx;
+- }
+ if (fw_tx->size % 4) {
+ printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n",
+ fw_tx->size, FIRMWARE_TX);
+Index: linux/drivers/net/ethernet/alteon/acenic.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/alteon/acenic.c
++++ linux/drivers/net/ethernet/alteon/acenic.c
+@@ -2890,11 +2890,8 @@ static int ace_load_firmware(struct net_
+ fw_name = "acenic/tg1.bin";
+
+ ret = request_firmware(&fw, fw_name, &ap->pdev->dev);
+- if (ret) {
+- printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n",
+- ap->name, fw_name);
++ if (ret)
+ return ret;
+- }
+
+ fw_data = (void *)fw->data;
+
+Index: linux/drivers/net/ethernet/broadcom/bnx2.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/broadcom/bnx2.c
++++ linux/drivers/net/ethernet/broadcom/bnx2.c
+@@ -3720,16 +3720,13 @@ static int bnx2_request_uncached_firmwar
+ }
+
+ rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev);
+- if (rc) {
+- pr_err("Can't load firmware file \"%s\"\n", mips_fw_file);
++ if (rc)
+ goto out;
+- }
+
+ rc = request_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev);
+- if (rc) {
+- pr_err("Can't load firmware file \"%s\"\n", rv2p_fw_file);
++ if (rc)
+ goto err_release_mips_firmware;
+- }
++
+ mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data;
+ rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data;
+ if (bp->mips_firmware->size < sizeof(*mips_fw) ||
+Index: linux/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
++++ linux/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+@@ -13557,11 +13557,8 @@ static int bnx2x_init_firmware(struct bn
+ BNX2X_DEV_INFO("Loading %s\n", fw_file_name);
+
+ rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev);
+- if (rc) {
+- BNX2X_ERR("Can't load firmware file %s\n",
+- fw_file_name);
++ if (rc)
+ goto request_firmware_exit;
+- }
+
+ rc = bnx2x_check_firmware(bp);
+ if (rc) {
+Index: linux/drivers/net/ethernet/broadcom/tg3.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/broadcom/tg3.c
++++ linux/drivers/net/ethernet/broadcom/tg3.c
+@@ -11408,11 +11408,8 @@ static int tg3_request_firmware(struct t
+ {
+ const struct tg3_firmware_hdr *fw_hdr;
+
+- if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) {
+- netdev_err(tp->dev, "Failed to load firmware \"%s\"\n",
+- tp->fw_needed);
++ if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev))
+ return -ENOENT;
+- }
+
+ fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data;
+
+Index: linux/drivers/net/ethernet/brocade/bna/cna_fwimg.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/brocade/bna/cna_fwimg.c
++++ linux/drivers/net/ethernet/brocade/bna/cna_fwimg.c
+@@ -32,10 +32,8 @@ cna_read_firmware(struct pci_dev *pdev,
+ const struct firmware *fw;
+ u32 n;
+
+- if (request_firmware(&fw, fw_name, &pdev->dev)) {
+- dev_alert(&pdev->dev, "can't load firmware %s\n", fw_name);
++ if (request_firmware(&fw, fw_name, &pdev->dev))
+ goto error;
+- }
+
+ *bfi_image = (u32 *)fw->data;
+ *bfi_image_size = fw->size/sizeof(u32);
+Index: linux/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
++++ linux/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c
+@@ -1038,12 +1038,8 @@ int t3_get_edc_fw(struct cphy *phy, int
+ fw_name = get_edc_fw_name(edc_idx);
+ if (fw_name)
+ ret = request_firmware(&fw, fw_name, &adapter->pdev->dev);
+- if (ret < 0) {
+- dev_err(&adapter->pdev->dev,
+- "could not upgrade firmware: unable to load %s\n",
+- fw_name);
++ if (ret)
+ return ret;
+- }
+
+ /* check size, take checksum in account */
+ if (fw->size > size + 4) {
+@@ -1080,11 +1076,8 @@ static int upgrade_fw(struct adapter *ad
+ struct device *dev = &adap->pdev->dev;
+
+ ret = request_firmware(&fw, FW_FNAME, dev);
+- if (ret < 0) {
+- dev_err(dev, "could not upgrade firmware: unable to load %s\n",
+- FW_FNAME);
++ if (ret)
+ return ret;
+- }
+ ret = t3_load_fw(adap, fw->data, fw->size);
+ release_firmware(fw);
+
+@@ -1129,11 +1122,8 @@ static int update_tpsram(struct adapter
+ snprintf(buf, sizeof(buf), TPSRAM_NAME, rev);
+
+ ret = request_firmware(&tpsram, buf, dev);
+- if (ret < 0) {
+- dev_err(dev, "could not load TP SRAM: unable to load %s\n",
+- buf);
++ if (ret)
+ return ret;
+- }
+
+ ret = t3_check_tpsram(adap, tpsram->data, tpsram->size);
+ if (ret)
+Index: linux/drivers/net/ethernet/intel/e100.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/intel/e100.c
++++ linux/drivers/net/ethernet/intel/e100.c
+@@ -1265,9 +1265,6 @@ static const struct firmware *e100_reque
+
+ if (err) {
+ if (required) {
+- netif_err(nic, probe, nic->netdev,
+- "Failed to load firmware \"%s\": %d\n",
+- fw_name, err);
+ return ERR_PTR(err);
+ } else {
+ netif_info(nic, probe, nic->netdev,
+Index: linux/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
++++ linux/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+@@ -581,8 +581,6 @@ static int myri10ge_load_hotplug_firmwar
+ unsigned i;
+
+ if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) {
+- dev_err(dev, "Unable to load %s firmware image via hotplug\n",
+- mgp->fw_name);
+ status = -EINVAL;
+ goto abort_with_nothing;
+ }
+Index: linux/drivers/net/ethernet/smsc/smc91c92_cs.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/smsc/smc91c92_cs.c
++++ linux/drivers/net/ethernet/smsc/smc91c92_cs.c
+@@ -647,10 +647,8 @@ static int osi_load_firmware(struct pcmc
+ int i, err;
+
+ err = request_firmware(&fw, FIRMWARE_NAME, &link->dev);
+- if (err) {
+- pr_err("Failed to load firmware \"%s\"\n", FIRMWARE_NAME);
++ if (err)
+ return err;
+- }
+
+ /* Download the Seven of Diamonds firmware */
+ for (i = 0; i < fw->size; i++) {
+Index: linux/drivers/net/ethernet/sun/cassini.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/sun/cassini.c
++++ linux/drivers/net/ethernet/sun/cassini.c
+@@ -805,11 +805,8 @@ static void cas_saturn_firmware_init(str
+ return;
+
+ err = request_firmware(&fw, fw_name, &cp->pdev->dev);
+- if (err) {
+- pr_err("Failed to load firmware \"%s\"\n",
+- fw_name);
++ if (err)
+ return;
+- }
+ if (fw->size < 2) {
+ pr_err("bogus length %zu in \"%s\"\n",
+ fw->size, fw_name);
+Index: linux/drivers/net/hamradio/yam.c
+===================================================================
+--- linux.orig/drivers/net/hamradio/yam.c
++++ linux/drivers/net/hamradio/yam.c
+@@ -372,11 +372,8 @@ static unsigned char *add_mcs(unsigned c
+ }
+ err = request_firmware(&fw, fw_name[predef], &pdev->dev);
+ platform_device_unregister(pdev);
+- if (err) {
+- printk(KERN_ERR "Failed to load firmware \"%s\"\n",
+- fw_name[predef]);
++ if (err)
+ return NULL;
+- }
+ if (fw->size != YAM_FPGA_SIZE) {
+ printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n",
+ fw->size, fw_name[predef]);
+Index: linux/drivers/net/usb/kaweth.c
+===================================================================
+--- linux.orig/drivers/net/usb/kaweth.c
++++ linux/drivers/net/usb/kaweth.c
+@@ -390,10 +390,8 @@ static int kaweth_download_firmware(stru
+ int ret;
+
+ ret = request_firmware(&fw, fwname, &kaweth->dev->dev);
+- if (ret) {
+- dev_err(&kaweth->intf->dev, "Firmware request failed\n");
++ if (ret)
+ return ret;
+- }
+
+ if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) {
+ dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n",
+Index: linux/drivers/net/wimax/i2400m/fw.c
+===================================================================
+--- linux.orig/drivers/net/wimax/i2400m/fw.c
++++ linux/drivers/net/wimax/i2400m/fw.c
+@@ -1583,11 +1583,8 @@ int i2400m_dev_bootstrap(struct i2400m *
+ }
+ d_printf(1, dev, "trying firmware %s (%d)\n", fw_name, itr);
+ ret = request_firmware(&fw, fw_name, dev);
+- if (ret < 0) {
+- dev_err(dev, "fw %s: cannot load file: %d\n",
+- fw_name, ret);
++ if (ret)
+ continue;
+- }
+ i2400m->fw_name = fw_name;
+ ret = i2400m_fw_bootstrap(i2400m, fw, flags);
+ release_firmware(fw);
+@@ -1630,8 +1627,6 @@ void i2400m_fw_cache(struct i2400m *i240
+ kref_init(&i2400m_fw->kref);
+ result = request_firmware(&i2400m_fw->fw, i2400m->fw_name, dev);
+ if (result < 0) {
+- dev_err(dev, "firmware %s: failed to cache: %d\n",
+- i2400m->fw_name, result);
+ kfree(i2400m_fw);
+ i2400m_fw = (void *) ~0;
+ } else
+Index: linux/drivers/net/wireless/atmel/at76c50x-usb.c
+===================================================================
+--- linux.orig/drivers/net/wireless/atmel/at76c50x-usb.c
++++ linux/drivers/net/wireless/atmel/at76c50x-usb.c
+@@ -1622,13 +1622,8 @@ static struct fwentry *at76_load_firmwar
+
+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+- if (ret < 0) {
+- dev_err(&udev->dev, "firmware %s not found!\n",
+- fwe->fwname);
+- dev_err(&udev->dev,
+- "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n");
++ if (ret)
+ goto exit;
+- }
+
+ at76_dbg(DBG_FW, "got it.");
+ fwh = (struct at76_fw_header *)(fwe->fw->data);
+Index: linux/drivers/net/wireless/ath/ath9k/hif_usb.c
+===================================================================
+--- linux.orig/drivers/net/wireless/ath/ath9k/hif_usb.c
++++ linux/drivers/net/wireless/ath/ath9k/hif_usb.c
+@@ -1164,9 +1164,6 @@ static void ath9k_hif_usb_firmware_cb(co
+ if (!ret)
+ return;
+
+- dev_err(&hif_dev->udev->dev,
+- "ath9k_htc: Failed to get firmware %s\n",
+- hif_dev->fw_name);
+ goto err_fw;
+ }
+
+Index: linux/drivers/net/wireless/ath/carl9170/usb.c
+===================================================================
+--- linux.orig/drivers/net/wireless/ath/carl9170/usb.c
++++ linux/drivers/net/wireless/ath/carl9170/usb.c
+@@ -1029,7 +1029,6 @@ static void carl9170_usb_firmware_step2(
+ return;
+ }
+
+- dev_err(&ar->udev->dev, "firmware not found.\n");
+ carl9170_usb_firmware_failed(ar);
+ }
+
+Index: linux/drivers/net/wireless/atmel/atmel.c
+===================================================================
+--- linux.orig/drivers/net/wireless/atmel/atmel.c
++++ linux/drivers/net/wireless/atmel/atmel.c
+@@ -3893,12 +3893,8 @@ static int reset_atmel_card(struct net_d
+ strcpy(priv->firmware_id, "atmel_at76c502.bin");
+ }
+ err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev);
+- if (err != 0) {
+- printk(KERN_ALERT
+- "%s: firmware %s is missing, cannot continue.\n",
+- dev->name, priv->firmware_id);
++ if (err != 0)
+ return err;
+- }
+ } else {
+ int fw_index = 0;
+ int success = 0;
+Index: linux/drivers/net/wireless/broadcom/b43/main.c
+===================================================================
+--- linux.orig/drivers/net/wireless/broadcom/b43/main.c
++++ linux/drivers/net/wireless/broadcom/b43/main.c
+@@ -2263,19 +2263,8 @@ int b43_do_request_fw(struct b43_request
+ }
+ err = request_firmware(&ctx->blob, ctx->fwname,
+ ctx->dev->dev->dev);
+- if (err == -ENOENT) {
+- snprintf(ctx->errors[ctx->req_type],
+- sizeof(ctx->errors[ctx->req_type]),
+- "Firmware file \"%s\" not found\n",
+- ctx->fwname);
++ if (err)
+ return err;
+- } else if (err) {
+- snprintf(ctx->errors[ctx->req_type],
+- sizeof(ctx->errors[ctx->req_type]),
+- "Firmware file \"%s\" request failed (err=%d)\n",
+- ctx->fwname, err);
+- return err;
+- }
+ fw_ready:
+ if (ctx->blob->size < sizeof(struct b43_fw_header))
+ goto err_format;
+Index: linux/drivers/net/wireless/broadcom/b43legacy/main.c
+===================================================================
+--- linux.orig/drivers/net/wireless/broadcom/b43legacy/main.c
++++ linux/drivers/net/wireless/broadcom/b43legacy/main.c
+@@ -1554,11 +1554,8 @@ static int do_request_fw(struct b43legac
+ } else {
+ err = request_firmware(fw, path, dev->dev->dev);
+ }
+- if (err) {
+- b43legacyerr(dev->wl, "Firmware file \"%s\" not found "
+- "or load failed.\n", path);
++ if (err)
+ return err;
+- }
+ if ((*fw)->size < sizeof(struct b43legacy_fw_header))
+ goto err_format;
+ hdr = (struct b43legacy_fw_header *)((*fw)->data);
+Index: linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+===================================================================
+--- linux.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
++++ linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c
+@@ -378,19 +378,13 @@ static int brcms_request_fw(struct brcms
+ sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
+ UCODE_LOADER_API_VER);
+ status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
+- if (status) {
+- wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+- KBUILD_MODNAME, fw_name);
++ if (status)
+ return status;
+- }
+ sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
+ UCODE_LOADER_API_VER);
+ status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
+- if (status) {
+- wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+- KBUILD_MODNAME, fw_name);
++ if (status)
+ return status;
+- }
+ wl->fw.hdr_num_entries[i] =
+ wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
+ }
+Index: linux/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intel/ipw2x00/ipw2100.c
++++ linux/drivers/net/wireless/intel/ipw2x00/ipw2100.c
+@@ -8410,12 +8410,8 @@ static int ipw2100_get_firmware(struct i
+
+ rc = request_firmware(&fw->fw_entry, fw_name, &priv->pci_dev->dev);
+
+- if (rc < 0) {
+- printk(KERN_ERR DRV_NAME ": "
+- "%s: Firmware '%s' not available or load failed.\n",
+- priv->net_dev->name, fw_name);
++ if (rc)
+ return rc;
+- }
+ IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
+ fw->fw_entry->size);
+
+Index: linux/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intel/ipw2x00/ipw2200.c
++++ linux/drivers/net/wireless/intel/ipw2x00/ipw2200.c
+@@ -3410,10 +3410,8 @@ static int ipw_get_fw(struct ipw_priv *p
+
+ /* ask firmware_class module to get the boot firmware off disk */
+ rc = request_firmware(raw, name, &priv->pci_dev->dev);
+- if (rc < 0) {
+- IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc);
++ if (rc)
+ return rc;
+- }
+
+ if ((*raw)->size < sizeof(*fw)) {
+ IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size);
+Index: linux/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intel/iwlegacy/3945-mac.c
++++ linux/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+@@ -1854,7 +1854,6 @@ il3945_read_ucode(struct il_priv *il)
+ sprintf(buf, "%s%u%s", name_pre, idx, ".ucode");
+ ret = request_firmware(&ucode_raw, buf, &il->pci_dev->dev);
+ if (ret < 0) {
+- IL_ERR("%s firmware file req failed: %d\n", buf, ret);
+ if (ret == -ENOENT)
+ continue;
+ else
+Index: linux/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
++++ linux/drivers/net/wireless/intel/iwlwifi/iwl-drv.c
+@@ -236,8 +236,6 @@ static int iwl_request_firmware(struct i
+ }
+
+ if (drv->fw_index < cfg->ucode_api_min) {
+- IWL_ERR(drv, "no suitable firmware found!\n");
+-
+ if (cfg->ucode_api_min == cfg->ucode_api_max) {
+ IWL_ERR(drv, "%s%d is required\n", fw_pre_name,
+ cfg->ucode_api_max);
+Index: linux/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+===================================================================
+--- linux.orig/drivers/net/wireless/marvell/libertas_tf/if_usb.c
++++ linux/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+@@ -817,8 +817,6 @@ static int if_usb_prog_firmware(struct i
+ kernel_param_lock(THIS_MODULE);
+ ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev);
+ if (ret < 0) {
+- pr_err("request_firmware() failed with %#x\n", ret);
+- pr_err("firmware %s not found\n", lbtf_fw_name);
+ kernel_param_unlock(THIS_MODULE);
+ goto done;
+ }
+Index: linux/drivers/net/wireless/marvell/mwifiex/main.c
+===================================================================
+--- linux.orig/drivers/net/wireless/marvell/mwifiex/main.c
++++ linux/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -528,11 +528,8 @@ static int _mwifiex_fw_dpc(const struct
+ struct wireless_dev *wdev;
+ struct completion *fw_done = adapter->fw_done;
+
+- if (!firmware) {
+- mwifiex_dbg(adapter, ERROR,
+- "Failed to get firmware %s\n", adapter->fw_name);
++ if (!firmware)
+ goto err_dnld_fw;
+- }
+
+ memset(&fw, 0, sizeof(struct mwifiex_fw_image));
+ adapter->firmware = firmware;
+Index: linux/drivers/net/wireless/marvell/mwl8k.c
+===================================================================
+--- linux.orig/drivers/net/wireless/marvell/mwl8k.c
++++ linux/drivers/net/wireless/marvell/mwl8k.c
+@@ -5724,16 +5724,12 @@ static int mwl8k_firmware_load_success(s
+ static void mwl8k_fw_state_machine(const struct firmware *fw, void *context)
+ {
+ struct mwl8k_priv *priv = context;
+- struct mwl8k_device_info *di = priv->device_info;
+ int rc;
+
+ switch (priv->fw_state) {
+ case FW_STATE_INIT:
+- if (!fw) {
+- printk(KERN_ERR "%s: Error requesting helper fw %s\n",
+- pci_name(priv->pdev), di->helper_image);
++ if (!fw)
+ goto fail;
+- }
+ priv->fw_helper = fw;
+ rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode,
+ true);
+@@ -5768,11 +5764,8 @@ static void mwl8k_fw_state_machine(const
+ break;
+
+ case FW_STATE_LOADING_ALT:
+- if (!fw) {
+- printk(KERN_ERR "%s: Error requesting alt fw %s\n",
+- pci_name(priv->pdev), di->helper_image);
++ if (!fw)
+ goto fail;
+- }
+ priv->fw_ucode = fw;
+ rc = mwl8k_firmware_load_success(priv);
+ if (rc)
+@@ -5810,10 +5803,8 @@ retry:
+
+ /* Ask userland hotplug daemon for the device firmware */
+ rc = mwl8k_request_firmware(priv, fw_image, nowait);
+- if (rc) {
+- wiphy_err(hw->wiphy, "Firmware files not found\n");
++ if (rc)
+ return rc;
+- }
+
+ if (nowait)
+ return rc;
+Index: linux/drivers/net/wireless/intersil/orinoco/fw.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intersil/orinoco/fw.c
++++ linux/drivers/net/wireless/intersil/orinoco/fw.c
+@@ -132,7 +132,6 @@ orinoco_dl_firmware(struct orinoco_priva
+ err = request_firmware(&fw_entry, firmware, priv->dev);
+
+ if (err) {
+- dev_err(dev, "Cannot find firmware %s\n", firmware);
+ err = -ENOENT;
+ goto free;
+ }
+@@ -292,10 +291,8 @@ symbol_dl_firmware(struct orinoco_privat
+ const struct firmware *fw_entry;
+
+ if (!orinoco_cached_fw_get(priv, true)) {
+- if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
+- dev_err(dev, "Cannot find firmware: %s\n", fw->pri_fw);
++ if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0)
+ return -ENOENT;
+- }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, true);
+
+@@ -311,10 +308,8 @@ symbol_dl_firmware(struct orinoco_privat
+ }
+
+ if (!orinoco_cached_fw_get(priv, false)) {
+- if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
+- dev_err(dev, "Cannot find firmware: %s\n", fw->sta_fw);
++ if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0)
+ return -ENOENT;
+- }
+ } else
+ fw_entry = orinoco_cached_fw_get(priv, false);
+
+Index: linux/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
++++ linux/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
+@@ -1677,7 +1677,6 @@ static int ezusb_probe(struct usb_interf
+ if (ezusb_firmware_download(upriv, &firmware) < 0)
+ goto error;
+ } else {
+- err("No firmware to download");
+ goto error;
+ }
+
+Index: linux/drivers/net/wireless/intersil/p54/p54pci.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intersil/p54/p54pci.c
++++ linux/drivers/net/wireless/intersil/p54/p54pci.c
+@@ -499,7 +499,6 @@ static void p54p_firmware_step2(const st
+ int err;
+
+ if (!fw) {
+- dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
+ err = -ENOENT;
+ goto out;
+ }
+Index: linux/drivers/net/wireless/intersil/p54/p54spi.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intersil/p54/p54spi.c
++++ linux/drivers/net/wireless/intersil/p54/p54spi.c
+@@ -170,10 +170,8 @@ static int p54spi_request_firmware(struc
+ /* FIXME: should driver use it's own struct device? */
+ ret = request_firmware(&priv->firmware, "3826.arm", &priv->spi->dev);
+
+- if (ret < 0) {
+- dev_err(&priv->spi->dev, "request_firmware() failed: %d", ret);
++ if (ret)
+ return ret;
+- }
+
+ ret = p54_parse_firmware(dev, priv->firmware);
+ if (ret) {
+Index: linux/drivers/net/wireless/intersil/p54/p54usb.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intersil/p54/p54usb.c
++++ linux/drivers/net/wireless/intersil/p54/p54usb.c
+@@ -931,7 +931,6 @@ static void p54u_load_firmware_cb(const
+ err = p54u_start_ops(priv);
+ } else {
+ err = -ENOENT;
+- dev_err(&udev->dev, "Firmware not found.\n");
+ }
+
+ complete(&priv->fw_wait_load);
+Index: linux/drivers/net/wireless/intersil/prism54/islpci_dev.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intersil/prism54/islpci_dev.c
++++ linux/drivers/net/wireless/intersil/prism54/islpci_dev.c
+@@ -92,12 +92,9 @@ isl_upload_firmware(islpci_private *priv
+ const u32 *fw_ptr;
+
+ rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV);
+- if (rc) {
+- printk(KERN_ERR
+- "%s: request_firmware() failed for '%s'\n",
+- "prism54", priv->firmware);
++ if (rc)
+ return rc;
+- }
++
+ /* prepare the Direct Memory Base register */
+ reg = ISL38XX_DEV_FIRMWARE_ADDRES;
+
+Index: linux/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c
+===================================================================
+--- linux.orig/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c
++++ linux/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c
+@@ -49,10 +49,8 @@ static int rt2x00lib_request_firmware(st
+ rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name);
+
+ retval = request_firmware(&fw, fw_name, device);
+- if (retval) {
+- rt2x00_err(rt2x00dev, "Failed to request Firmware\n");
++ if (retval)
+ return retval;
+- }
+
+ if (!fw || !fw->size || !fw->data) {
+ rt2x00_err(rt2x00dev, "Failed to read Firmware\n");
+Index: linux/drivers/net/wireless/realtek/rtlwifi/core.c
+===================================================================
+--- linux.orig/drivers/net/wireless/realtek/rtlwifi/core.c
++++ linux/drivers/net/wireless/realtek/rtlwifi/core.c
+@@ -111,7 +111,6 @@ static void rtl_fw_do_work(const struct
+ if (!err)
+ goto found_alt;
+ }
+- pr_err("Selected firmware is not available\n");
+ rtlpriv->max_fw_size = 0;
+ return;
+ }
+Index: linux/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
+===================================================================
+--- linux.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
++++ linux/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c
+@@ -86,13 +86,11 @@ static void rtl92se_fw_cb(const struct f
+ struct ieee80211_hw *hw = context;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rt_firmware *pfirmware = NULL;
+- char *fw_name = "rtlwifi/rtl8192sefw.bin";
+
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+ "Firmware callback routine entered!\n");
+ complete(&rtlpriv->firmware_loading_complete);
+ if (!firmware) {
+- pr_err("Firmware %s not available\n", fw_name);
+ rtlpriv->max_fw_size = 0;
+ return;
+ }
+Index: linux/drivers/net/wireless/ti/wl1251/main.c
+===================================================================
+--- linux.orig/drivers/net/wireless/ti/wl1251/main.c
++++ linux/drivers/net/wireless/ti/wl1251/main.c
+@@ -71,10 +71,8 @@ static int wl1251_fetch_firmware(struct
+
+ ret = request_firmware(&fw, WL1251_FW_NAME, dev);
+
+- if (ret < 0) {
+- wl1251_error("could not get firmware: %d", ret);
++ if (ret)
+ return ret;
+- }
+
+ if (fw->size % 4) {
+ wl1251_error("firmware size is not multiple of 32 bits: %zu",
+@@ -110,10 +108,8 @@ static int wl1251_fetch_nvs(struct wl125
+
+ ret = request_firmware(&fw, WL1251_NVS_NAME, dev);
+
+- if (ret < 0) {
+- wl1251_error("could not get nvs file: %d", ret);
++ if (ret)
+ return ret;
+- }
+
+ if (fw->size % 4) {
+ wl1251_error("nvs size is not multiple of 32 bits: %zu",
+Index: linux/drivers/net/wireless/ti/wlcore/main.c
+===================================================================
+--- linux.orig/drivers/net/wireless/ti/wlcore/main.c
++++ linux/drivers/net/wireless/ti/wlcore/main.c
+@@ -768,10 +768,8 @@ static int wl12xx_fetch_firmware(struct
+
+ ret = request_firmware(&fw, fw_name, wl->dev);
+
+- if (ret < 0) {
+- wl1271_error("could not get firmware %s: %d", fw_name, ret);
++ if (ret)
+ return ret;
+- }
+
+ if (fw->size % 4) {
+ wl1271_error("firmware size is not multiple of 32 bits: %zu",
+Index: linux/drivers/net/wireless/zydas/zd1201.c
+===================================================================
+--- linux.orig/drivers/net/wireless/zydas/zd1201.c
++++ linux/drivers/net/wireless/zydas/zd1201.c
+@@ -65,8 +65,6 @@ static int zd1201_fw_upload(struct usb_d
+
+ err = request_firmware(&fw_entry, fwfile, &dev->dev);
+ if (err) {
+- dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile);
+- dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n");
+ dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n");
+ return err;
+ }
+Index: linux/drivers/net/wireless/zydas/zd1211rw/zd_usb.c
+===================================================================
+--- linux.orig/drivers/net/wireless/zydas/zd1211rw/zd_usb.c
++++ linux/drivers/net/wireless/zydas/zd1211rw/zd_usb.c
+@@ -120,16 +120,9 @@ static void int_urb_complete(struct urb
+ static int request_fw_file(
+ const struct firmware **fw, const char *name, struct device *device)
+ {
+- int r;
+-
+ dev_dbg_f(device, "fw name %s\n", name);
+
+- r = request_firmware(fw, name, device);
+- if (r)
+- dev_err(device,
+- "Could not load firmware file %s. Error number %d\n",
+- name, r);
+- return r;
++ return request_firmware(fw, name, device);
+ }
+
+ static inline u16 get_bcdDevice(const struct usb_device *udev)
+Index: linux/drivers/scsi/advansys.c
+===================================================================
+--- linux.orig/drivers/scsi/advansys.c
++++ linux/drivers/scsi/advansys.c
+@@ -4107,8 +4107,6 @@ static int AscInitAsc1000Driver(ASC_DVC_
+
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+- fwname, err);
+ asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
+ return err;
+ }
+@@ -4473,8 +4471,6 @@ static int AdvInitAsc3550Driver(ADV_DVC_
+
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+- fwname, err);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
+ return err;
+ }
+@@ -4973,8 +4969,6 @@ static int AdvInitAsc38C0800Driver(ADV_D
+
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+- fwname, err);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
+ return err;
+ }
+@@ -5461,8 +5455,6 @@ static int AdvInitAsc38C1600Driver(ADV_D
+
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+- fwname, err);
+ asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM;
+ return err;
+ }
+Index: linux/drivers/scsi/aic94xx/aic94xx_init.c
+===================================================================
+--- linux.orig/drivers/scsi/aic94xx/aic94xx_init.c
++++ linux/drivers/scsi/aic94xx/aic94xx_init.c
+@@ -384,8 +384,6 @@ static ssize_t asd_store_update_bios(str
+ filename_ptr,
+ &asd_ha->pcidev->dev);
+ if (err) {
+- asd_printk("Failed to load bios image file %s, error %d\n",
+- filename_ptr, err);
+ err = FAIL_OPEN_BIOS_FILE;
+ goto out1;
+ }
+Index: linux/drivers/scsi/aic94xx/aic94xx_seq.c
+===================================================================
+--- linux.orig/drivers/scsi/aic94xx/aic94xx_seq.c
++++ linux/drivers/scsi/aic94xx/aic94xx_seq.c
+@@ -1317,11 +1317,8 @@ int asd_init_seqs(struct asd_ha_struct *
+
+ err = asd_request_firmware(asd_ha);
+
+- if (err) {
+- asd_printk("Failed to load sequencer firmware file %s, error %d\n",
+- SAS_RAZOR_SEQUENCER_FW_FILE, err);
++ if (err)
+ return err;
+- }
+
+ err = asd_seq_download_seqs(asd_ha);
+ if (err) {
+Index: linux/drivers/scsi/bfa/bfad.c
+===================================================================
+--- linux.orig/drivers/scsi/bfa/bfad.c
++++ linux/drivers/scsi/bfa/bfad.c
+@@ -1755,7 +1755,6 @@ bfad_read_firmware(struct pci_dev *pdev,
+ const struct firmware *fw;
+
+ if (request_firmware(&fw, fw_name, &pdev->dev)) {
+- printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
+ *bfi_image = NULL;
+ goto out;
+ }
+Index: linux/drivers/scsi/ipr.c
+===================================================================
+--- linux.orig/drivers/scsi/ipr.c
++++ linux/drivers/scsi/ipr.c
+@@ -4102,10 +4102,8 @@ static ssize_t ipr_store_update_fw(struc
+ if (endline)
+ *endline = '\0';
+
+- if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) {
+- dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname);
++ if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev))
+ return -EIO;
+- }
+
+ image_hdr = (struct ipr_ucode_image_header *)fw_entry->data;
+
+Index: linux/drivers/scsi/pm8001/pm8001_ctl.c
+===================================================================
+--- linux.orig/drivers/scsi/pm8001/pm8001_ctl.c
++++ linux/drivers/scsi/pm8001/pm8001_ctl.c
+@@ -737,10 +737,6 @@ static ssize_t pm8001_store_update_fw(st
+ pm8001_ha->dev);
+
+ if (ret) {
+- PM8001_FAIL_DBG(pm8001_ha,
+- pm8001_printk(
+- "Failed to load firmware image file %s, error %d\n",
+- filename_ptr, ret));
+ pm8001_ha->fw_status = FAIL_OPEN_BIOS_FILE;
+ goto out;
+ }
+Index: linux/drivers/scsi/qla1280.c
+===================================================================
+--- linux.orig/drivers/scsi/qla1280.c
++++ linux/drivers/scsi/qla1280.c
+@@ -1552,8 +1552,6 @@ qla1280_request_firmware(struct scsi_qla
+ err = request_firmware(&fw, fwname, &ha->pdev->dev);
+
+ if (err) {
+- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+- fwname, err);
+ fw = ERR_PTR(err);
+ goto unlock;
+ }
+Index: linux/drivers/scsi/qla2xxx/qla_init.c
+===================================================================
+--- linux.orig/drivers/scsi/qla2xxx/qla_init.c
++++ linux/drivers/scsi/qla2xxx/qla_init.c
+@@ -7470,8 +7470,6 @@ qla2x00_load_risc(scsi_qla_host_t *vha,
+ /* Load firmware blob. */
+ blob = qla2x00_request_firmware(vha);
+ if (!blob) {
+- ql_log(ql_log_info, vha, 0x0083,
+- "Firmware image unavailable.\n");
+ ql_log(ql_log_info, vha, 0x0084,
+ "Firmware images can be retrieved from: "QLA_FW_URL ".\n");
+ return QLA_FUNCTION_FAILED;
+@@ -7573,8 +7571,6 @@ qla24xx_load_risc_blob(scsi_qla_host_t *
+ /* Load firmware blob. */
+ blob = qla2x00_request_firmware(vha);
+ if (!blob) {
+- ql_log(ql_log_warn, vha, 0x0090,
+- "Firmware image unavailable.\n");
+ ql_log(ql_log_warn, vha, 0x0091,
+ "Firmware images can be retrieved from: "
+ QLA_FW_URL ".\n");
+Index: linux/drivers/scsi/qla2xxx/qla_nx.c
+===================================================================
+--- linux.orig/drivers/scsi/qla2xxx/qla_nx.c
++++ linux/drivers/scsi/qla2xxx/qla_nx.c
+@@ -2464,11 +2464,8 @@ try_blob_fw:
+
+ /* Load firmware blob. */
+ blob = ha->hablob = qla2x00_request_firmware(vha);
+- if (!blob) {
+- ql_log(ql_log_fatal, vha, 0x00a3,
+- "Firmware image not present.\n");
++ if (!blob)
+ goto fw_load_failed;
+- }
+
+ /* Validating firmware blob */
+ if (qla82xx_validate_firmware_blob(vha,
+Index: linux/drivers/scsi/qla2xxx/qla_os.c
+===================================================================
+--- linux.orig/drivers/scsi/qla2xxx/qla_os.c
++++ linux/drivers/scsi/qla2xxx/qla_os.c
+@@ -6543,8 +6543,6 @@ qla2x00_request_firmware(scsi_qla_host_t
+ goto out;
+
+ if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
+- ql_log(ql_log_warn, vha, 0x0063,
+- "Failed to load firmware image (%s).\n", blob->name);
+ blob->fw = NULL;
+ blob = NULL;
+ goto out;
+Index: linux/drivers/scsi/qlogicpti.c
+===================================================================
+--- linux.orig/drivers/scsi/qlogicpti.c
++++ linux/drivers/scsi/qlogicpti.c
+@@ -475,11 +475,8 @@ static int qlogicpti_load_firmware(struc
+ int i, timeout;
+
+ err = request_firmware(&fw, fwname, &qpti->op->dev);
+- if (err) {
+- printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+- fwname, err);
++ if (err)
+ return err;
+- }
+ if (fw->size % 2) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+Index: linux/drivers/media/usb/go7007/go7007-driver.c
+===================================================================
+--- linux.orig/drivers/media/usb/go7007/go7007-driver.c
++++ linux/drivers/media/usb/go7007/go7007-driver.c
+@@ -92,10 +92,8 @@ static int go7007_load_encoder(struct go
+ u16 intr_val, intr_data;
+
+ if (go->boot_fw == NULL) {
+- if (request_firmware(&fw_entry, fw_name, go->dev)) {
+- v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name);
++ if (request_firmware(&fw_entry, fw_name, go->dev))
+ return -1;
+- }
+ if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
+ v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name);
+ release_firmware(fw_entry);
+Index: linux/drivers/media/usb/go7007/go7007-fw.c
+===================================================================
+--- linux.orig/drivers/media/usb/go7007/go7007-fw.c
++++ linux/drivers/media/usb/go7007/go7007-fw.c
+@@ -1573,12 +1573,8 @@ int go7007_construct_fw_image(struct go7
+ default:
+ return -1;
+ }
+- if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) {
+- dev_err(go->dev,
+- "unable to load firmware from file \"%s\"\n",
+- GO7007_FW_NAME);
++ if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev))
+ return -1;
+- }
+ code = kcalloc(codespace, 2, GFP_KERNEL);
+ if (code == NULL)
+ goto fw_failed;
+Index: linux/drivers/media/usb/go7007/go7007-loader.c
+===================================================================
+--- linux.orig/drivers/media/usb/go7007/go7007-loader.c
++++ linux/drivers/media/usb/go7007/go7007-loader.c
+@@ -75,11 +75,8 @@ static int go7007_loader_probe(struct us
+
+ dev_info(&interface->dev, "loading firmware %s\n", fw1);
+
+- if (request_firmware(&fw, fw1, &usbdev->dev)) {
+- dev_err(&interface->dev,
+- "unable to load firmware from file \"%s\"\n", fw1);
++ if (request_firmware(&fw, fw1, &usbdev->dev))
+ goto failed2;
+- }
+ ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+ release_firmware(fw);
+ if (0 != ret) {
+@@ -90,11 +87,8 @@ static int go7007_loader_probe(struct us
+ if (fw2 == NULL)
+ return 0;
+
+- if (request_firmware(&fw, fw2, &usbdev->dev)) {
+- dev_err(&interface->dev,
+- "unable to load firmware from file \"%s\"\n", fw2);
++ if (request_firmware(&fw, fw2, &usbdev->dev))
+ goto failed2;
+- }
+ ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2);
+ release_firmware(fw);
+ if (0 != ret) {
+Index: linux/drivers/staging/rtl8192u/r819xU_firmware.c
+===================================================================
+--- linux.orig/drivers/staging/rtl8192u/r819xU_firmware.c
++++ linux/drivers/staging/rtl8192u/r819xU_firmware.c
+@@ -245,10 +245,8 @@ bool init_firmware(struct net_device *de
+ */
+ if (rst_opt == OPT_SYSTEM_RESET) {
+ rc = request_firmware(&fw_entry, fw_name[init_step], &priv->udev->dev);
+- if (rc < 0) {
+- RT_TRACE(COMP_ERR, "request firmware fail!\n");
++ if (rc)
+ goto download_firmware_fail;
+- }
+
+ if (fw_entry->size > sizeof(pfirmware->firmware_buf)) {
+ RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n");
+Index: linux/drivers/staging/rtl8712/hal_init.c
+===================================================================
+--- linux.orig/drivers/staging/rtl8712/hal_init.c
++++ linux/drivers/staging/rtl8712/hal_init.c
+@@ -67,8 +67,6 @@ int rtl871x_load_fw(struct _adapter *pad
+ dev_info(dev, "r8712u: Loading firmware from \"%s\"\n", firmware_file);
+ rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev,
+ GFP_KERNEL, padapter, rtl871x_load_fw_cb);
+- if (rc)
+- dev_err(dev, "r8712u: Firmware request error %d\n", rc);
+ return rc;
+ }
+ MODULE_FIRMWARE("rtlwifi/rtl8712u.bin");
+Index: linux/drivers/net/ethernet/alacritech/slicoss.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/alacritech/slicoss.c
++++ linux/drivers/net/ethernet/alacritech/slicoss.c
+@@ -1063,11 +1063,8 @@ static int slic_load_rcvseq_firmware(str
+ file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_RCV_FIRMWARE_OASIS :
+ SLIC_RCV_FIRMWARE_MOJAVE;
+ err = request_firmware(&fw, file, &sdev->pdev->dev);
+- if (err) {
+- dev_err(&sdev->pdev->dev,
+- "failed to load receive sequencer firmware %s\n", file);
++ if (err)
+ return err;
+- }
+ /* Do an initial sanity check concerning firmware size now. A further
+ * check follows below.
+ */
+@@ -1138,10 +1135,8 @@ static int slic_load_firmware(struct sli
+ file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_FIRMWARE_OASIS :
+ SLIC_FIRMWARE_MOJAVE;
+ err = request_firmware(&fw, file, &sdev->pdev->dev);
+- if (err) {
+- dev_err(&sdev->pdev->dev, "failed to load firmware %s\n", file);
++ if (err)
+ return err;
+- }
+ /* Do an initial sanity check concerning firmware size now. A further
+ * check follows below.
+ */
+Index: linux/drivers/staging/vt6656/firmware.c
+===================================================================
+--- linux.orig/drivers/staging/vt6656/firmware.c
++++ linux/drivers/staging/vt6656/firmware.c
+@@ -39,11 +39,8 @@ int vnt_download_firmware(struct vnt_pri
+ dev_dbg(dev, "---->Download firmware\n");
+
+ rc = request_firmware(&fw, FIRMWARE_NAME, dev);
+- if (rc) {
+- dev_err(dev, "firmware file %s request failed (%d)\n",
+- FIRMWARE_NAME, rc);
+- goto out;
+- }
++ if (rc)
++ goto out;
+
+ buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
+ if (!buffer)
+Index: linux/drivers/tty/cyclades.c
+===================================================================
+--- linux.orig/drivers/tty/cyclades.c
++++ linux/drivers/tty/cyclades.c
+@@ -3489,10 +3489,8 @@ static int cyz_load_fw(struct pci_dev *p
+ int retval;
+
+ retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev);
+- if (retval) {
+- dev_err(&pdev->dev, "can't get firmware\n");
++ if (retval)
+ goto err;
+- }
+
+ /* Check whether the firmware is already loaded and running. If
+ positive, skip this board */
+Index: linux/drivers/tty/moxa.c
+===================================================================
+--- linux.orig/drivers/tty/moxa.c
++++ linux/drivers/tty/moxa.c
+@@ -862,13 +862,8 @@ static int moxa_init_board(struct moxa_b
+ }
+
+ ret = request_firmware(&fw, file, dev);
+- if (ret) {
+- printk(KERN_ERR "MOXA: request_firmware failed. Make sure "
+- "you've placed '%s' file into your firmware "
+- "loader directory (e.g. /lib/firmware)\n",
+- file);
++ if (ret)
+ goto err_free;
+- }
+
+ ret = moxa_load_fw(brd, fw);
+
+Index: linux/drivers/tty/serial/icom.c
+===================================================================
+--- linux.orig/drivers/tty/serial/icom.c
++++ linux/drivers/tty/serial/icom.c
+@@ -360,7 +360,6 @@ static void load_code(struct icom_port *
+
+ /* Load Call Setup into Adapter */
+ if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) {
+- dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n");
+ status = -1;
+ goto load_code_exit;
+ }
+@@ -380,7 +379,6 @@ static void load_code(struct icom_port *
+
+ /* Load Resident DCE portion of Adapter */
+ if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) {
+- dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n");
+ status = -1;
+ goto load_code_exit;
+ }
+@@ -425,7 +423,6 @@ static void load_code(struct icom_port *
+ }
+
+ if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) {
+- dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n");
+ status = -1;
+ goto load_code_exit;
+ }
+Index: linux/drivers/tty/serial/ucc_uart.c
+===================================================================
+--- linux.orig/drivers/tty/serial/ucc_uart.c
++++ linux/drivers/tty/serial/ucc_uart.c
+@@ -1165,10 +1165,8 @@ static void uart_firmware_cont(const str
+ struct device *dev = context;
+ int ret;
+
+- if (!fw) {
+- dev_err(dev, "firmware not found\n");
++ if (!fw)
+ return;
+- }
+
+ firmware = (struct qe_firmware *) fw->data;
+
+Index: linux/drivers/usb/atm/cxacru.c
+===================================================================
+--- linux.orig/drivers/usb/atm/cxacru.c
++++ linux/drivers/usb/atm/cxacru.c
+@@ -1080,8 +1080,6 @@ static int cxacru_find_firmware(struct c
+ return -ENOENT;
+ }
+
+- usb_info(usbatm, "found firmware %s\n", buf);
+-
+ return 0;
+ }
+
+Index: linux/drivers/usb/atm/ueagle-atm.c
+===================================================================
+--- linux.orig/drivers/usb/atm/ueagle-atm.c
++++ linux/drivers/usb/atm/ueagle-atm.c
+@@ -650,10 +650,8 @@ static void uea_upload_pre_firmware(cons
+ int ret, size;
+
+ uea_enters(usb);
+- if (!fw_entry) {
+- uea_err(usb, "firmware is not available\n");
++ if (!fw_entry)
+ goto err;
+- }
+
+ pfw = fw_entry->data;
+ size = fw_entry->size;
+@@ -748,10 +746,6 @@ static int uea_load_firmware(struct usb_
+ ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
+ GFP_KERNEL, usb,
+ uea_upload_pre_firmware);
+- if (ret)
+- uea_err(usb, "firmware %s is not available\n", fw_name);
+- else
+- uea_info(usb, "loading firmware %s\n", fw_name);
+
+ uea_leaves(usb);
+ return ret;
+@@ -913,12 +907,8 @@ static int request_dsp(struct uea_softc
+ }
+
+ ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev);
+- if (ret < 0) {
+- uea_err(INS_TO_USBDEV(sc),
+- "requesting firmware %s failed with error %d\n",
+- dsp_name, ret);
++ if (ret)
+ return ret;
+- }
+
+ if (UEA_CHIP_VERSION(sc) == EAGLE_IV)
+ ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size);
+@@ -1631,12 +1621,8 @@ static int request_cmvs_old(struct uea_s
+
+ cmvs_file_name(sc, cmv_name, 1);
+ ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev);
+- if (ret < 0) {
+- uea_err(INS_TO_USBDEV(sc),
+- "requesting firmware %s failed with error %d\n",
+- cmv_name, ret);
++ if (ret)
+ return ret;
+- }
+
+ data = (u8 *) (*fw)->data;
+ size = (*fw)->size;
+@@ -1673,9 +1659,6 @@ static int request_cmvs(struct uea_softc
+ "try to get older cmvs\n", cmv_name);
+ return request_cmvs_old(sc, cmvs, fw);
+ }
+- uea_err(INS_TO_USBDEV(sc),
+- "requesting firmware %s failed with error %d\n",
+- cmv_name, ret);
+ return ret;
+ }
+
+@@ -1958,11 +1941,8 @@ static int load_XILINX_firmware(struct u
+ uea_enters(INS_TO_USBDEV(sc));
+
+ ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev);
+- if (ret) {
+- uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n",
+- fw_name);
++ if (ret)
+ goto err0;
+- }
+
+ pfw = fw_entry->data;
+ size = fw_entry->size;
+Index: linux/drivers/usb/misc/emi26.c
+===================================================================
+--- linux.orig/drivers/usb/misc/emi26.c
++++ linux/drivers/usb/misc/emi26.c
+@@ -85,21 +85,17 @@ static int emi26_load_firmware (struct u
+
+ err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev);
+ if (err)
+- goto nofw;
++ goto wraperr;
+
+ err = request_ihex_firmware(&bitstream_fw, "emi26/bitstream.fw",
+ &dev->dev);
+ if (err)
+- goto nofw;
++ goto wraperr;
+
+ err = request_ihex_firmware(&firmware_fw, "emi26/firmware.fw",
+ &dev->dev);
+- if (err) {
+- nofw:
+- dev_err(&dev->dev, "%s - request_firmware() failed\n",
+- __func__);
++ if (err)
+ goto wraperr;
+- }
+
+ /* Assert reset (stop the CPU in the EMI) */
+ err = emi26_set_reset(dev,1);
+Index: linux/drivers/usb/misc/ezusb.c
+===================================================================
+--- linux.orig/drivers/usb/misc/ezusb.c
++++ linux/drivers/usb/misc/ezusb.c
+@@ -76,12 +76,8 @@ static int ezusb_ihex_firmware_download(
+ const struct ihex_binrec *record;
+
+ if (request_ihex_firmware(&firmware, firmware_path,
+- &dev->dev)) {
+- dev_err(&dev->dev,
+- "%s - request \"%s\" failed\n",
+- __func__, firmware_path);
++ &dev->dev))
+ goto out;
+- }
+
+ ret = ezusb_set_reset(dev, fx.cpucs_reg, 0);
+ if (ret < 0)
+Index: linux/drivers/usb/misc/isight_firmware.c
+===================================================================
+--- linux.orig/drivers/usb/misc/isight_firmware.c
++++ linux/drivers/usb/misc/isight_firmware.c
+@@ -45,7 +45,6 @@ static int isight_firmware_load(struct u
+ return -ENOMEM;
+
+ if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) {
+- printk(KERN_ERR "Unable to load isight firmware\n");
+ ret = -ENODEV;
+ goto out;
+ }
+Index: linux/drivers/usb/serial/io_edgeport.c
+===================================================================
+--- linux.orig/drivers/usb/serial/io_edgeport.c
++++ linux/drivers/usb/serial/io_edgeport.c
+@@ -375,11 +375,8 @@ static void update_edgeport_E2PROM(struc
+
+ response = request_ihex_firmware(&fw, fw_name,
+ &edge_serial->serial->dev->dev);
+- if (response) {
+- dev_err(dev, "Failed to load image \"%s\" err %d\n",
+- fw_name, response);
++ if (response)
+ return;
+- }
+
+ rec = (const struct ihex_binrec *)fw->data;
+ BootMajorVersion = rec->data[0];
+Index: linux/drivers/usb/serial/io_ti.c
+===================================================================
+--- linux.orig/drivers/usb/serial/io_ti.c
++++ linux/drivers/usb/serial/io_ti.c
+@@ -1010,8 +1010,6 @@ static int download_fw(struct edgeport_s
+
+ status = request_firmware(&fw, fw_name, dev);
+ if (status) {
+- dev_err(dev, "Failed to load image \"%s\" err %d\n",
+- fw_name, status);
+ return status;
+ }
+
+Index: linux/drivers/usb/serial/ti_usb_3410_5052.c
+===================================================================
+--- linux.orig/drivers/usb/serial/ti_usb_3410_5052.c
++++ linux/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -1689,10 +1689,8 @@ static int ti_download_firmware(struct t
+ }
+
+ check_firmware:
+- if (status) {
+- dev_err(&dev->dev, "%s - firmware not found\n", __func__);
++ if (status)
+ return -ENOENT;
+- }
+ if (fw_p->size > TI_FIRMWARE_BUF_SIZE) {
+ dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size);
+ release_firmware(fw_p);
+Index: linux/drivers/video/fbdev/broadsheetfb.c
+===================================================================
+--- linux.orig/drivers/video/fbdev/broadsheetfb.c
++++ linux/drivers/video/fbdev/broadsheetfb.c
+@@ -743,10 +743,8 @@ static ssize_t broadsheet_loadstore_wave
+ return -EINVAL;
+
+ err = request_firmware(&fw_entry, "broadsheet.wbf", dev);
+- if (err < 0) {
+- dev_err(dev, "Failed to get broadsheet waveform\n");
++ if (err)
+ goto err_failed;
+- }
+
+ /* try to enforce reasonable min max on waveform */
+ if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) {
+Index: linux/drivers/video/fbdev/metronomefb.c
+===================================================================
+--- linux.orig/drivers/video/fbdev/metronomefb.c
++++ linux/drivers/video/fbdev/metronomefb.c
+@@ -679,10 +679,8 @@ static int metronomefb_probe(struct plat
+ a) request the waveform file from userspace
+ b) process waveform and decode into metromem */
+ retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev);
+- if (retval < 0) {
+- dev_err(&dev->dev, "Failed to get waveform\n");
++ if (retval)
+ goto err_csum_table;
+- }
+
+ retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31,
+ par);
+Index: linux/sound/drivers/vx/vx_hwdep.c
+===================================================================
+--- linux.orig/sound/drivers/vx/vx_hwdep.c
++++ linux/sound/drivers/vx/vx_hwdep.c
+@@ -71,10 +71,8 @@ int snd_vx_setup_firmware(struct vx_core
+ if (! fw_files[chip->type][i])
+ continue;
+ sprintf(path, "vx/%s", fw_files[chip->type][i]);
+- if (request_firmware(&fw, path, chip->dev)) {
+- snd_printk(KERN_ERR "vx: can't load firmware %s\n", path);
++ if (request_firmware(&fw, path, chip->dev))
+ return -ENOENT;
+- }
+ err = chip->ops->load_dsp(chip, i, fw);
+ if (err < 0) {
+ release_firmware(fw);
+Index: linux/sound/isa/msnd/msnd_pinnacle.c
+===================================================================
+--- linux.orig/sound/isa/msnd/msnd_pinnacle.c
++++ linux/sound/isa/msnd/msnd_pinnacle.c
+@@ -390,15 +390,11 @@ static int upload_dsp_code(struct snd_ca
+ outb(HPBLKSEL_0, chip->io + HP_BLKS);
+
+ err = request_firmware(&init_fw, INITCODEFILE, card->dev);
+- if (err < 0) {
+- printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE);
++ if (err)
+ goto cleanup1;
+- }
+ err = request_firmware(&perm_fw, PERMCODEFILE, card->dev);
+- if (err < 0) {
+- printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE);
++ if (err)
+ goto cleanup;
+- }
+
+ memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size);
+ if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) {
+Index: linux/sound/isa/sscape.c
+===================================================================
+--- linux.orig/sound/isa/sscape.c
++++ linux/sound/isa/sscape.c
+@@ -544,10 +544,8 @@ static int sscape_upload_bootblock(struc
+ int ret;
+
+ ret = request_firmware(&init_fw, "scope.cod", card->dev);
+- if (ret < 0) {
+- snd_printk(KERN_ERR "sscape: Error loading scope.cod");
++ if (ret)
+ return ret;
+- }
+ ret = upload_dma_data(sscape, init_fw->data, init_fw->size);
+
+ release_firmware(init_fw);
+@@ -584,11 +582,8 @@ static int sscape_upload_microcode(struc
+ snprintf(name, sizeof(name), "sndscape.co%d", version);
+
+ err = request_firmware(&init_fw, name, card->dev);
+- if (err < 0) {
+- snd_printk(KERN_ERR "sscape: Error loading sndscape.co%d",
+- version);
++ if (err)
+ return err;
+- }
+ err = upload_dma_data(sscape, init_fw->data, init_fw->size);
+ if (err == 0)
+ snd_printk(KERN_INFO "sscape: MIDI firmware loaded %zu KBs\n",
+Index: linux/sound/isa/wavefront/wavefront_synth.c
+===================================================================
+--- linux.orig/sound/isa/wavefront/wavefront_synth.c
++++ linux/sound/isa/wavefront/wavefront_synth.c
+@@ -1957,10 +1957,8 @@ wavefront_download_firmware (snd_wavefro
+ const struct firmware *firmware;
+
+ err = request_firmware(&firmware, path, dev->card->dev);
+- if (err < 0) {
+- snd_printk(KERN_ERR "firmware (%s) download failed!!!\n", path);
++ if (err)
+ return 1;
+- }
+
+ len = 0;
+ buf = firmware->data;
+Index: linux/sound/pci/asihpi/hpidspcd.c
+===================================================================
+--- linux.orig/sound/pci/asihpi/hpidspcd.c
++++ linux/sound/pci/asihpi/hpidspcd.c
+@@ -46,8 +46,6 @@ short hpi_dsp_code_open(u32 adapter, voi
+ err = request_firmware(&firmware, fw_name, &dev->dev);
+
+ if (err || !firmware) {
+- dev_err(&dev->dev, "%d, request_firmware failed for %s\n",
+- err, fw_name);
+ goto error1;
+ }
+ if (firmware->size < sizeof(header)) {
+Index: linux/sound/pci/echoaudio/echoaudio.c
+===================================================================
+--- linux.orig/sound/pci/echoaudio/echoaudio.c
++++ linux/sound/pci/echoaudio/echoaudio.c
+@@ -60,11 +60,8 @@ static int get_firmware(const struct fir
+ "firmware requested: %s\n", card_fw[fw_index].data);
+ snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data);
+ err = request_firmware(fw_entry, name, &chip->pci->dev);
+- if (err < 0)
+- dev_err(chip->card->dev,
+- "get_firmware(): Firmware not available (%d)\n", err);
+ #ifdef CONFIG_PM_SLEEP
+- else
++ if (!err)
+ chip->fw_cache[fw_index] = *fw_entry;
+ #endif
+ return err;
+Index: linux/sound/pci/emu10k1/emu10k1_main.c
+===================================================================
+--- linux.orig/sound/pci/emu10k1/emu10k1_main.c
++++ linux/sound/pci/emu10k1/emu10k1_main.c
+@@ -888,10 +888,8 @@ static int snd_emu10k1_emu1010_init(stru
+ dev_info(emu->card->dev, "emu1010: EMU_HANA_ID = 0x%x\n", reg);
+
+ err = snd_emu1010_load_firmware(emu, 0, &emu->firmware);
+- if (err < 0) {
+- dev_info(emu->card->dev, "emu1010: Loading Firmware failed\n");
++ if (err < 0)
+ return err;
+- }
+
+ /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
+ snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
+Index: linux/sound/pci/hda/hda_intel.c
+===================================================================
+--- linux.orig/sound/pci/hda/hda_intel.c
++++ linux/sound/pci/hda/hda_intel.c
+@@ -2079,8 +2079,6 @@ static void azx_firmware_cb(const struct
+
+ if (fw)
+ chip->fw = fw;
+- else
+- dev_err(card->dev, "Cannot load firmware, continue without patching\n");
+ if (!chip->disabled) {
+ /* continue probing */
+ azx_probe_continue(chip);
+Index: linux/sound/pci/korg1212/korg1212.c
+===================================================================
+--- linux.orig/sound/pci/korg1212/korg1212.c
++++ linux/sound/pci/korg1212/korg1212.c
+@@ -2348,7 +2348,6 @@ static int snd_korg1212_create(struct sn
+
+ err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
+ if (err < 0) {
+- snd_printk(KERN_ERR "firmware not available\n");
+ snd_korg1212_free(korg1212);
+ return err;
+ }
+Index: linux/sound/pci/mixart/mixart_hwdep.c
+===================================================================
+--- linux.orig/sound/pci/mixart/mixart_hwdep.c
++++ linux/sound/pci/mixart/mixart_hwdep.c
+@@ -571,11 +571,8 @@ int snd_mixart_setup_firmware(struct mix
+
+ for (i = 0; i < 3; i++) {
+ sprintf(path, "mixart/%s", fw_files[i]);
+- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
+- dev_err(&mgr->pci->dev,
+- "miXart: can't load firmware %s\n", path);
++ if (request_firmware(&fw_entry, path, &mgr->pci->dev))
+ return -ENOENT;
+- }
+ /* fake hwdep dsp record */
+ err = mixart_dsp_load(mgr, i, fw_entry);
+ release_firmware(fw_entry);
+Index: linux/sound/pci/pcxhr/pcxhr_hwdep.c
+===================================================================
+--- linux.orig/sound/pci/pcxhr/pcxhr_hwdep.c
++++ linux/sound/pci/pcxhr/pcxhr_hwdep.c
+@@ -385,12 +385,8 @@ int pcxhr_setup_firmware(struct pcxhr_mg
+ if (!fw_files[fw_set][i])
+ continue;
+ sprintf(path, "pcxhr/%s", fw_files[fw_set][i]);
+- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
+- dev_err(&mgr->pci->dev,
+- "pcxhr: can't load firmware %s\n",
+- path);
++ if (request_firmware(&fw_entry, path, &mgr->pci->dev))
+ return -ENOENT;
+- }
+ /* fake hwdep dsp record */
+ err = pcxhr_dsp_load(mgr, i, fw_entry);
+ release_firmware(fw_entry);
+Index: linux/sound/pci/riptide/riptide.c
+===================================================================
+--- linux.orig/sound/pci/riptide/riptide.c
++++ linux/sound/pci/riptide/riptide.c
+@@ -1231,11 +1231,8 @@ static int try_to_load_firmware(struct c
+ if (!chip->fw_entry) {
+ err = request_firmware(&chip->fw_entry, "riptide.hex",
+ &chip->pci->dev);
+- if (err) {
+- snd_printk(KERN_ERR
+- "Riptide: Firmware not available %d\n", err);
++ if (err)
+ return -EIO;
+- }
+ }
+ err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size);
+ if (err) {
+Index: linux/sound/pci/rme9652/hdsp.c
+===================================================================
+--- linux.orig/sound/pci/rme9652/hdsp.c
++++ linux/sound/pci/rme9652/hdsp.c
+@@ -5134,11 +5134,8 @@ static int hdsp_request_fw_loader(struct
+ return -EINVAL;
+ }
+
+- if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) {
+- dev_err(hdsp->card->dev,
+- "cannot load firmware %s\n", fwfile);
++ if (request_firmware(&fw, fwfile, &hdsp->pci->dev))
+ return -ENOENT;
+- }
+ if (fw->size < HDSP_FIRMWARE_SIZE) {
+ dev_err(hdsp->card->dev,
+ "too short firmware size %d (expected %d)\n",
+Index: linux/sound/soc/codecs/wm2000.c
+===================================================================
+--- linux.orig/sound/soc/codecs/wm2000.c
++++ linux/sound/soc/codecs/wm2000.c
+@@ -891,10 +891,8 @@ static int wm2000_i2c_probe(struct i2c_c
+ }
+
+ ret = request_firmware(&fw, filename, &i2c->dev);
+- if (ret != 0) {
+- dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
++ if (ret != 0)
+ goto err_supplies;
+- }
+
+ /* Pre-cook the concatenation of the register address onto the image */
+ wm2000->anc_download_size = fw->size + 2;
+Index: linux/sound/usb/6fire/firmware.c
+===================================================================
+--- linux.orig/sound/usb/6fire/firmware.c
++++ linux/sound/usb/6fire/firmware.c
+@@ -219,8 +219,6 @@ static int usb6fire_fw_ezusb_upload(
+ ret = request_firmware(&fw, fwname, &device->dev);
+ if (ret < 0) {
+ kfree(rec);
+- dev_err(&intf->dev,
+- "error requesting ezusb firmware %s.\n", fwname);
+ return ret;
+ }
+ ret = usb6fire_fw_ihex_init(fw, rec);
+@@ -296,8 +294,6 @@ static int usb6fire_fw_fpga_upload(
+
+ ret = request_firmware(&fw, fwname, &device->dev);
+ if (ret < 0) {
+- dev_err(&intf->dev, "unable to get fpga firmware %s.\n",
+- fwname);
+ kfree(buffer);
+ return -EIO;
+ }
+Index: linux/sound/pci/cs46xx/cs46xx_lib.c
+===================================================================
+--- linux.orig/sound/pci/cs46xx/cs46xx_lib.c
++++ linux/sound/pci/cs46xx/cs46xx_lib.c
+@@ -3253,11 +3253,8 @@ int snd_cs46xx_start_dsp(struct snd_cs46
+ #ifdef CONFIG_SND_CS46XX_NEW_DSP
+ for (i = 0; i < CS46XX_DSP_MODULES; i++) {
+ err = load_firmware(chip, &chip->modules[i], module_names[i]);
+- if (err < 0) {
+- dev_err(chip->card->dev, "firmware load error [%s]\n",
+- module_names[i]);
++ if (err < 0)
+ return err;
+- }
+ err = cs46xx_dsp_load_module(chip, chip->modules[i]);
+ if (err < 0) {
+ dev_err(chip->card->dev, "image download error [%s]\n",
diff --git a/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch b/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch
new file mode 100644
index 000000000..266688652
--- /dev/null
+++ b/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch
@@ -0,0 +1,70 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: firmware_class: Log every success and failure against given device
+Date: Sun, 09 Dec 2012 16:02:00 +0000
+Forwarded: no
+
+The hundreds of users of request_firmware() have nearly as many
+different log formats for reporting failures. They also have only the
+vaguest hint as to what went wrong; only firmware_class really knows
+that. Therefore, add specific log messages for the failure modes that
+aren't currently logged.
+
+In case of a driver that tries multiple names, this may result in the
+impression that it failed to initialise. Therefore, also log successes.
+
+This makes many error messages in drivers redundant, which will be
+removed in later patches.
+
+This does not cover the case where we fall back to a user-mode helper
+(which is no longer enabled in Debian).
+
+NOTE: hw-detect will depend on the "firmware: failed to load %s (%d)\n"
+format to detect missing firmware.
+---
+Index: linux/drivers/base/firmware_loader/main.c
+===================================================================
+--- linux.orig/drivers/base/firmware_loader/main.c
++++ linux/drivers/base/firmware_loader/main.c
+@@ -328,21 +328,22 @@ fw_get_filesystem_firmware(struct device
+ rc = kernel_read_file_from_path(path, &fw_priv->data, &size,
+ msize, id);
+ if (rc) {
+- if (rc == -ENOENT)
+- dev_dbg(device, "loading %s failed with error %d\n",
+- path, rc);
+- else
+- dev_warn(device, "loading %s failed with error %d\n",
+- path, rc);
++ dev_dbg(device, "loading %s failed with error %d\n",
++ path, rc);
+ continue;
+ }
+- dev_dbg(device, "direct-loading %s\n", fw_priv->fw_name);
++ dev_info(device, "firmware: direct-loading firmware %s\n",
++ fw_priv->fw_name);
+ fw_priv->size = size;
+ fw_state_done(fw_priv);
+ break;
+ }
+ __putname(path);
+
++ if (rc)
++ dev_err(device, "firmware: failed to load %s (%d)\n",
++ fw_priv->fw_name, rc);
++
+ return rc;
+ }
+
+Index: linux/drivers/base/firmware_loader/fallback.c
+===================================================================
+--- linux.orig/drivers/base/firmware_loader/fallback.c
++++ linux/drivers/base/firmware_loader/fallback.c
+@@ -604,7 +604,7 @@ static int fw_load_from_user_helper(stru
+ if (opt_flags & FW_OPT_NOWAIT) {
+ timeout = usermodehelper_read_lock_wait(timeout);
+ if (!timeout) {
+- dev_dbg(device, "firmware: %s loading timed out\n",
++ dev_err(device, "firmware: %s loading timed out\n",
+ name);
+ return -EBUSY;
+ }
diff --git a/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch b/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch
new file mode 100644
index 000000000..d6cb0ffac
--- /dev/null
+++ b/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch
@@ -0,0 +1,66 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 13 Apr 2016 21:48:06 +0100
+Subject: fs: Add MODULE_SOFTDEP declarations for hard-coded crypto drivers
+Bug-Debian: https://bugs.debian.org/819725
+Forwarded: http://mid.gmane.org/20160517133631.GF7555@decadent.org.uk
+
+This helps initramfs builders and other tools to find the full
+dependencies of a module.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream]
+---
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -2536,3 +2536,4 @@ late_initcall(init_btrfs_fs);
+ module_exit(exit_btrfs_fs)
+
+ MODULE_LICENSE("GPL");
++MODULE_SOFTDEP("pre: crypto-crc32c");
+--- a/fs/crypto/crypto.c
++++ b/fs/crypto/crypto.c
+@@ -504,3 +504,4 @@ static void __exit fscrypt_exit(void)
+ module_exit(fscrypt_exit);
+
+ MODULE_LICENSE("GPL");
++MODULE_SOFTDEP("pre: crypto-aes crypto-ecb");
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -6200,6 +6200,6 @@ static void __exit ext4_exit_fs(void)
+ MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others");
+ MODULE_DESCRIPTION("Fourth Extended Filesystem");
+ MODULE_LICENSE("GPL");
+-MODULE_SOFTDEP("pre: crc32c");
++MODULE_SOFTDEP("pre: crypto-crc32c");
+ module_init(ext4_init_fs)
+ module_exit(ext4_exit_fs)
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -3373,5 +3373,5 @@ module_exit(exit_f2fs_fs)
+ MODULE_AUTHOR("Samsung Electronics's Praesto Team");
+ MODULE_DESCRIPTION("Flash Friendly File System");
+ MODULE_LICENSE("GPL");
+-MODULE_SOFTDEP("pre: crc32");
++MODULE_SOFTDEP("pre: crypto-crc32");
+
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -2744,6 +2744,7 @@ static void __exit journal_exit(void)
+ }
+
+ MODULE_LICENSE("GPL");
++MODULE_SOFTDEP("pre: crypto-crc32c");
+ module_init(journal_init);
+ module_exit(journal_exit);
+
+--- a/fs/nfsd/nfsctl.c
++++ b/fs/nfsd/nfsctl.c
+@@ -1337,5 +1337,8 @@ static void __exit exit_nfsd(void)
+
+ MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
+ MODULE_LICENSE("GPL");
++#ifdef CONFIG_NFSD_V4
++MODULE_SOFTDEP("pre: crypto-md5");
++#endif
+ module_init(init_nfsd)
+ module_exit(exit_nfsd)
diff --git a/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch b/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch
new file mode 100644
index 000000000..8e942af28
--- /dev/null
+++ b/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch
@@ -0,0 +1,25 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: kbuild: Fix recordmcount dependency for OOT modules
+Date: Mon, 08 Sep 2014 18:31:24 +0100
+Forwarded: no
+
+We never rebuild anything in-tree when building an out-of-tree
+modules, so external modules should not depend on the recordmcount
+sources.
+
+Index: linux/scripts/Makefile.build
+===================================================================
+--- linux.orig/scripts/Makefile.build
++++ linux/scripts/Makefile.build
+@@ -232,6 +232,11 @@ cmd_record_mcount = \
+ endif # CC_USING_RECORD_MCOUNT
+ endif # CONFIG_FTRACE_MCOUNT_RECORD
+
++# Don't require recordmcount source for an OOT build.
++ifdef KBUILD_EXTMOD
++recordmcount_source :=
++endif
++
+ ifdef CONFIG_STACK_VALIDATION
+ ifneq ($(SKIP_STACK_VALIDATION),1)
+
diff --git a/debian/patches/bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch b/debian/patches/bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch
new file mode 100644
index 000000000..22ef11a3b
--- /dev/null
+++ b/debian/patches/bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch
@@ -0,0 +1,42 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 04 Mar 2017 01:44:15 +0000
+Subject: Kbuild.include: addtree: Remove quotes before matching path
+Bug-Debian: https://bugs.debian.org/856474
+Forwarded: https://marc.info/?l=linux-kbuild&m=148987677205629
+
+systemtap currently fails to build modules when the kernel source and
+object trees are separate.
+
+systemtap adds something like -I"/usr/share/systemtap/runtime" to
+EXTRA_CFLAGS, and addtree should not adjust this as it's specifying an
+absolute directory. But since make has no understanding of shell
+quoting, it does anyway.
+
+For a long time this didn't matter, because addtree would still emit
+the original -I option after the adjusted one. However, commit
+db547ef19064 ("Kbuild: don't add obj tree in additional includes")
+changed it to remove the original -I option.
+
+Remove quotes (both double and single) before matching against the
+excluded patterns.
+
+References: https://bugs.debian.org/856474
+Reported-by: Jack Henschel <jackdev@mailbox.org>
+Reported-by: Ritesh Raj Sarraf <rrs@debian.org>
+Fixes: db547ef19064 ("Kbuild: don't add obj tree in additional includes")
+Cc: stable@vger.kernel.org # 4.8+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/scripts/Kbuild.include
+===================================================================
+--- linux.orig/scripts/Kbuild.include
++++ linux/scripts/Kbuild.include
+@@ -211,7 +211,7 @@ hdr-inst := -f $(srctree)/scripts/Makefi
+ # Prefix -I with $(srctree) if it is not an absolute path.
+ # skip if -I has no parameter
+ addtree = $(if $(patsubst -I%,%,$(1)), \
+-$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1))
++$(if $(filter-out -I/% -I./% -I../%,$(subst $(quote),,$(subst $(squote),,$(1)))),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1))
+
+ # Find all -I options and call addtree
+ flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o)))
diff --git a/debian/patches/bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch b/debian/patches/bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch
new file mode 100644
index 000000000..61a4628a4
--- /dev/null
+++ b/debian/patches/bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch
@@ -0,0 +1,91 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 19 Oct 2013 19:43:35 +0100
+Subject: kbuild: Use -nostdinc in compile tests
+Bug-Debian: https://bugs.debian.org/726861
+Bug-Debian: https://bugs.debian.org/717557
+Forwarded: https://marc.info/?l=linux-kbuild&m=141523555023625
+
+gcc 4.8 and later include <stdc-predef.h> by default. In some
+versions of eglibc that includes <bits/predefs.h>, but that may be
+missing when building with a biarch compiler. Also <stdc-predef.h>
+itself could be missing as we are only trying to build a kernel, not
+userland.
+
+The -nostdinc option disables this, though it isn't explicitly
+documented. This option is already used when actually building
+the kernel, but not by cc-option and other tests. This can result
+in silently miscompiling the kernel.
+
+References: https://bugs.debian.org/717557
+References: https://bugs.debian.org/726861
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+--- a/scripts/Kbuild.include
++++ b/scripts/Kbuild.include
+@@ -121,7 +121,7 @@ CC_OPTION_CFLAGS = $(filter-out $(GCC_PL
+ # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586)
+
+ cc-option = $(call __cc-option, $(CC),\
+- $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2))
++ $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2))
+
+ # hostcc-option
+ # Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586)
+@@ -131,23 +131,24 @@ hostcc-option = $(call __cc-option, $(HO
+ # cc-option-yn
+ # Usage: flag := $(call cc-option-yn,-march=winchip-c6)
+ cc-option-yn = $(call try-run,\
+- $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
++ $(CC) -Werror $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n)
+
+ # cc-disable-warning
+ # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable)
+ cc-disable-warning = $(call try-run,\
+- $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
++ $(CC) -Werror $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
+
+ # cc-name
+ # Expands to either gcc or clang
+ cc-name = $(shell $(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc)
+
+ # cc-version
+-cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
++cc-version = $(shell $(CONFIG_SHELL) \
++ $(srctree)/scripts/gcc-version.sh $(CC) $(NOSTDINC_FLAGS))
+
+ # cc-fullversion
+ cc-fullversion = $(shell $(CONFIG_SHELL) \
+- $(srctree)/scripts/gcc-version.sh -p $(CC))
++ $(srctree)/scripts/gcc-version.sh -p $(CC) $(NOSTDINC_FLAGS))
+
+ # cc-ifversion
+ # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
+@@ -156,7 +157,7 @@ cc-ifversion = $(shell [ $(cc-version) $
+ # cc-ldoption
+ # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both)
+ cc-ldoption = $(call try-run,\
+- $(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
++ $(CC) $(1) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2))
+
+ # ld-option
+ # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y)
+--- a/Makefile
++++ b/Makefile
+@@ -661,6 +661,8 @@ else
+ KBUILD_CFLAGS += -O2
+ endif
+
++NOSTDINC_FLAGS += -nostdinc
++
+ # Tell gcc to never replace conditional load with a non-conditional one
+ KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0)
+ KBUILD_CFLAGS += $(call cc-option,-fno-allow-store-data-races)
+@@ -781,7 +783,7 @@ LDFLAGS_vmlinux += --gc-sections
+ endif
+
+ # arch Makefile may override CC so keep this after arch Makefile is included
+-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
++NOSTDINC_FLAGS += -isystem $(shell $(CC) -print-file-name=include)
+
+ # warn about C99 declaration after statement
+ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
diff --git a/debian/patches/bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch b/debian/patches/bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch
new file mode 100644
index 000000000..360a16aa5
--- /dev/null
+++ b/debian/patches/bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch
@@ -0,0 +1,77 @@
+From: Fredrik Noring <noring@nocrew.org>
+Date: Wed, 29 May 2019 13:28:39 +0300
+Subject: lib/genalloc: add gen_pool_dma_zalloc() for zeroed DMA allocations
+Origin: https://git.kernel.org/linus/da83a722959a82733c3ca60030cc364ca2318c5a
+
+gen_pool_dma_zalloc() is a zeroed memory variant of
+gen_pool_dma_alloc(). Also document the return values of both, and
+indicate NULL as a "%NULL" constant.
+
+Signed-off-by: Fredrik Noring <noring@nocrew.org>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ include/linux/genalloc.h | 1 +
+ lib/genalloc.c | 29 ++++++++++++++++++++++++++++-
+ 2 files changed, 29 insertions(+), 1 deletion(-)
+
+--- a/include/linux/genalloc.h
++++ b/include/linux/genalloc.h
+@@ -121,6 +121,7 @@
+ genpool_algo_t algo, void *data);
+ extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size,
+ dma_addr_t *dma);
++void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma);
+ extern void gen_pool_free(struct gen_pool *, unsigned long, size_t);
+ extern void gen_pool_for_each_chunk(struct gen_pool *,
+ void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *);
+--- a/lib/genalloc.c
++++ b/lib/genalloc.c
+@@ -337,12 +337,14 @@
+ * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage
+ * @pool: pool to allocate from
+ * @size: number of bytes to allocate from the pool
+- * @dma: dma-view physical address return value. Use NULL if unneeded.
++ * @dma: dma-view physical address return value. Use %NULL if unneeded.
+ *
+ * Allocate the requested number of bytes from the specified pool.
+ * Uses the pool allocation function (with first-fit algorithm by default).
+ * Can not be used in NMI handler on architectures without
+ * NMI-safe cmpxchg implementation.
++ *
++ * Return: virtual address of the allocated memory, or %NULL on failure
+ */
+ void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma)
+ {
+@@ -363,6 +365,31 @@
+ EXPORT_SYMBOL(gen_pool_dma_alloc);
+
+ /**
++ * gen_pool_dma_zalloc - allocate special zeroed memory from the pool for
++ * DMA usage
++ * @pool: pool to allocate from
++ * @size: number of bytes to allocate from the pool
++ * @dma: dma-view physical address return value. Use %NULL if unneeded.
++ *
++ * Allocate the requested number of zeroed bytes from the specified pool.
++ * Uses the pool allocation function (with first-fit algorithm by default).
++ * Can not be used in NMI handler on architectures without
++ * NMI-safe cmpxchg implementation.
++ *
++ * Return: virtual address of the allocated zeroed memory, or %NULL on failure
++ */
++void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma)
++{
++ void *vaddr = gen_pool_dma_alloc(pool, size, dma);
++
++ if (vaddr)
++ memset(vaddr, 0, size);
++
++ return vaddr;
++}
++EXPORT_SYMBOL(gen_pool_dma_zalloc);
++
++/**
+ * gen_pool_free - free allocated special memory back to the pool
+ * @pool: pool to free to
+ * @addr: starting address of memory to free back to pool
diff --git a/debian/patches/bugfix/all/libbpf-add-soname-to-shared-object.patch b/debian/patches/bugfix/all/libbpf-add-soname-to-shared-object.patch
new file mode 100644
index 000000000..40f2bcc1d
--- /dev/null
+++ b/debian/patches/bugfix/all/libbpf-add-soname-to-shared-object.patch
@@ -0,0 +1,56 @@
+From: Hilko Bengen <bengen@debian.org>
+Date: Sun, 02 Dec 2018 23:26:03 +0000
+Subject: libbpf: add SONAME to shared object
+
+tools/lib/bpf/libbpf: Add proper version to the shared object.
+
+Add versioning to the shared object to make it easier on distros to
+distribute the library without having to watch for API/ABI versioning.
+
+This is similar to the change made to tools/lib/lockdep/Makefile in
+be227b45fb228adff4371b8de9e3989904209ff4.
+
+Signed-off-by: Hilko Bengen <bengen@debian.org>
+[bwh: Drop unnecessary changes]
+---
+Index: linux/tools/lib/bpf/Makefile
+===================================================================
+--- linux.orig/tools/lib/bpf/Makefile
++++ linux/tools/lib/bpf/Makefile
+@@ -94,7 +94,7 @@ export prefix libdir src obj
+ libdir_SQ = $(subst ','\'',$(libdir))
+ libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
+
+-LIB_FILE = libbpf.a libbpf.so
++LIB_FILE = libbpf.a libbpf.so.$(LIBBPF_VERSION)
+
+ VERSION = $(BPF_VERSION)
+ PATCHLEVEL = $(BPF_PATCHLEVEL)
+@@ -103,7 +103,7 @@ EXTRAVERSION = $(BPF_EXTRAVERSION)
+ OBJ = $@
+ N =
+
+-LIBBPF_VERSION = $(BPF_VERSION).$(BPF_PATCHLEVEL).$(BPF_EXTRAVERSION)
++LIBBPF_VERSION = $(shell make --no-print-directory -sC ../../.. kernelversion | cut -d. -f1,2)
+
+ # Set compile option CFLAGS
+ ifdef EXTRA_CFLAGS
+@@ -169,8 +169,8 @@ $(BPF_IN): force elfdep bpfdep
+ echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h' differs from latest version at 'include/uapi/linux/if_link.h'" >&2 )) || true
+ $(Q)$(MAKE) $(build)=libbpf
+
+-$(OUTPUT)libbpf.so: $(BPF_IN)
+- $(QUIET_LINK)$(CC) --shared $^ -o $@
++$(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN)
++ $(QUIET_LINK)$(CC) --shared $^ -Wl,-soname,$(@F) -o $@
+
+ $(OUTPUT)libbpf.a: $(BPF_IN)
+ $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
+@@ -185,6 +185,7 @@ endef
+ install_lib: all_cmd
+ $(call QUIET_INSTALL, $(LIB_FILE)) \
+ $(call do_install,$(LIB_FILE),$(libdir_SQ))
++ $(Q)ln -sf libbpf.so.$(LIBBPF_VERSION) $(DESTDIR_SQ)$(libdir_SQ)/libbpf.so
+
+ install_headers:
+ $(call QUIET_INSTALL, headers) \
diff --git a/debian/patches/bugfix/all/libbpf-generate-pkg-config.patch b/debian/patches/bugfix/all/libbpf-generate-pkg-config.patch
new file mode 100644
index 000000000..63ecffe5f
--- /dev/null
+++ b/debian/patches/bugfix/all/libbpf-generate-pkg-config.patch
@@ -0,0 +1,90 @@
+Author: Luca Boccassi <bluca@debian.org>
+Description: generate pkg-config file for libbpf
+ Generate a libbpf.pc file at build time so that users can rely
+ on pkg-config to find the library, its CFLAGS and LDFLAGS.
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=dd399ac9e343c7573c47d6820e4a23013c54749d
+Applied-Upstream: yes
+Index: linux/tools/lib/bpf/.gitignore
+===================================================================
+--- linux.orig/tools/lib/bpf/.gitignore
++++ linux/tools/lib/bpf/.gitignore
+@@ -1,2 +1,3 @@
+ libbpf_version.h
++libbpf.pc
+ FEATURE-DUMP.libbpf
+Index: linux/tools/lib/bpf/Makefile
+===================================================================
+--- linux.orig/tools/lib/bpf/Makefile
++++ linux/tools/lib/bpf/Makefile
+@@ -95,6 +95,7 @@ libdir_SQ = $(subst ','\'',$(libdir))
+ libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
+
+ LIB_FILE = libbpf.a libbpf.so.$(LIBBPF_VERSION)
++PC_FILE = libbpf.pc
+
+ VERSION = $(BPF_VERSION)
+ PATCHLEVEL = $(BPF_PATCHLEVEL)
+@@ -144,8 +145,9 @@ include $(srctree)/tools/build/Makefile.
+
+ BPF_IN := $(OUTPUT)libbpf-in.o
+ LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
++PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE))
+
+-CMD_TARGETS = $(LIB_FILE)
++CMD_TARGETS = $(LIB_FILE) $(PC_FILE)
+
+ TARGETS = $(CMD_TARGETS)
+
+@@ -175,6 +177,12 @@ $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(
+ $(OUTPUT)libbpf.a: $(BPF_IN)
+ $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
+
++$(OUTPUT)libbpf.pc:
++ $(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \
++ -e "s|@LIBDIR@|$(libdir_SQ)|" \
++ -e "s|@VERSION@|$(LIBBPF_VERSION)|" \
++ < libbpf.pc.template > $@
++
+ define do_install
+ if [ ! -d '$(DESTDIR_SQ)$2' ]; then \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
+@@ -193,7 +201,12 @@ install_headers:
+ $(call do_install,libbpf.h,$(prefix)/include/bpf,644);
+ $(call do_install,btf.h,$(prefix)/include/bpf,644);
+
+-install: install_lib
++install_pkgconfig: $(PC_FILE)
++ $(call QUIET_INSTALL, $(PC_FILE)) \
++ $(call do_install,$(PC_FILE),$(libdir_SQ)/pkgconfig,644)
++
++
++install: install_lib install_pkgconfig
+
+ ### Cleaning rules
+
+@@ -202,7 +215,7 @@ config-clean:
+ $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null
+
+ clean:
+- $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so .*.d .*.cmd \
++ $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so .*.d .*.cmd *.pc \
+ $(RM) LIBBPF-CFLAGS
+ $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf
+
+Index: linux/tools/lib/bpf/libbpf.pc.template
+===================================================================
+--- /dev/null
++++ linux/tools/lib/bpf/libbpf.pc.template
+@@ -0,0 +1,12 @@
++# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
++
++prefix=@PREFIX@
++libdir=@LIBDIR@
++includedir=${prefix}/include
++
++Name: libbpf
++Description: BPF library
++Version: @VERSION@
++Libs: -L${libdir} -lbpf
++Requires.private: libelf
++Cflags: -I${includedir}
diff --git a/debian/patches/bugfix/all/libbpf-link-shared-object-with-libelf.patch b/debian/patches/bugfix/all/libbpf-link-shared-object-with-libelf.patch
new file mode 100644
index 000000000..f02cb07e2
--- /dev/null
+++ b/debian/patches/bugfix/all/libbpf-link-shared-object-with-libelf.patch
@@ -0,0 +1,22 @@
+From: Hilko Bengen <bengen@debian.org>
+Date: Sun, 02 Dec 2018 23:26:03 +0000
+Subject: libbpf: link shared object with libelf
+
+libbpf.so needs to be linked against libelf to avoid missing symbols.
+
+Signed-off-by: Hilko Bengen <bengen@debian.org>
+
+---
+Index: linux/tools/lib/bpf/Makefile
+===================================================================
+--- linux.orig/tools/lib/bpf/Makefile
++++ linux/tools/lib/bpf/Makefile
+@@ -170,7 +170,7 @@ $(BPF_IN): force elfdep bpfdep
+ $(Q)$(MAKE) $(build)=libbpf
+
+ $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN)
+- $(QUIET_LINK)$(CC) --shared $^ -Wl,-soname,$(@F) -o $@
++ $(QUIET_LINK)$(CC) --shared $^ -lelf -Wl,-soname,$(@F) -o $@
+
+ $(OUTPUT)libbpf.a: $(BPF_IN)
+ $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
diff --git a/debian/patches/bugfix/all/libcpupower-hide-private-function.patch b/debian/patches/bugfix/all/libcpupower-hide-private-function.patch
new file mode 100644
index 000000000..dba71b64e
--- /dev/null
+++ b/debian/patches/bugfix/all/libcpupower-hide-private-function.patch
@@ -0,0 +1,22 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 01 Dec 2018 19:22:50 +0000
+Subject: libcpupower: Hide private function
+
+cpupower_read_sysfs() (previously known as sysfs_read_file()) is an
+internal function in libcpupower and should not be exported when
+libcpupower is a shared library. Change its visibility to "hidden".
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/tools/power/cpupower/lib/cpupower.c
+===================================================================
+--- linux.orig/tools/power/cpupower/lib/cpupower.c
++++ linux/tools/power/cpupower/lib/cpupower.c
+@@ -15,6 +15,7 @@
+ #include "cpupower.h"
+ #include "cpupower_intern.h"
+
++__attribute__((visibility("hidden")))
+ unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen)
+ {
+ int fd;
diff --git a/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch b/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch
new file mode 100644
index 000000000..9c3461019
--- /dev/null
+++ b/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch
@@ -0,0 +1,25 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 02 Dec 2016 23:06:18 +0000
+Subject: module: Disable matching missing version CRC
+Forwarded: not-needed
+
+This partly reverts commit cd3caefb4663e3811d37cc2afad3cce642d60061.
+We want to fail closed if a symbol version CRC is missing, as the
+alternative may allow subverting module signing.
+---
+Index: linux/kernel/module.c
+===================================================================
+--- linux.orig/kernel/module.c
++++ linux/kernel/module.c
+@@ -1317,9 +1317,8 @@ static int check_version(const struct lo
+ goto bad_version;
+ }
+
+- /* Broken toolchain. Warn once, then let it go.. */
+- pr_warn_once("%s: no symbol version for %s\n", info->name, symname);
+- return 1;
++ pr_warn("%s: no symbol version for %s\n", info->name, symname);
++ return 0;
+
+ bad_version:
+ pr_warn("%s: disagrees about version of symbol %s\n",
diff --git a/debian/patches/bugfix/all/mt76-use-the-correct-hweight8-function.patch b/debian/patches/bugfix/all/mt76-use-the-correct-hweight8-function.patch
new file mode 100644
index 000000000..ce3b63af3
--- /dev/null
+++ b/debian/patches/bugfix/all/mt76-use-the-correct-hweight8-function.patch
@@ -0,0 +1,30 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 12 Feb 2019 15:20:48 +0000
+Subject: mt76: Use the correct hweight8() function
+Forwarded: https://marc.info/?l=linux-wireless&m=154998579614180&w=2
+
+mt76_init_stream_cap() and mt76_get_txpower() call __sw_hweight8()
+directly, but that's only defined if CONFIG_GENERIC_HWEIGHT is
+enabled. The function that works on all architectures is hweight8().
+
+Fixes: 551e1ef4d291 ("mt76: add mt76_init_stream_cap routine")
+Fixes: 9313faacbb4e ("mt76: move mt76x02_get_txpower to mt76 core")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+[bwh: For 4.19, drop change in mt76_get_txpower()]
+---
+ drivers/net/wireless/mediatek/mt76/mac80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/wireless/mediatek/mt76/mac80211.c
+===================================================================
+--- linux.orig/drivers/net/wireless/mediatek/mt76/mac80211.c
++++ linux/drivers/net/wireless/mediatek/mt76/mac80211.c
+@@ -124,7 +124,7 @@ static void mt76_init_stream_cap(struct
+ bool vht)
+ {
+ struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap;
+- int i, nstream = __sw_hweight8(dev->antenna_mask);
++ int i, nstream = hweight8(dev->antenna_mask);
+ struct ieee80211_sta_vht_cap *vht_cap;
+ u16 mcs_map = 0;
+
diff --git a/debian/patches/bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch b/debian/patches/bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch
new file mode 100644
index 000000000..3f259ac4c
--- /dev/null
+++ b/debian/patches/bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch
@@ -0,0 +1,50 @@
+From: Diederik de Haas <didi.debian@cknow.org>
+Date: Wed, 22 Jun 2022 11:44:05 +0200
+Subject: net_sched: let qdisc_put() accept NULL pointer
+Bug-Debian: https://bugs.debian.org/1013299
+
+In commit 92833e8b5db6c209e9311ac8c6a44d3bf1856659 titled
+"net: sched: rename qdisc_destroy() to qdisc_put()" part of the
+functionality of qdisc_destroy() was moved into a (for linux-4.19.y)
+new function qdisk_put(), and the previous calls to qdisc_destroy()
+were changed to qdisk_put().
+This made it similar to f.e. 5.10.y and current master.
+
+There was one part of qdisc_destroy() not moved over to qdisc_put() and
+that was the check for a NULL value, causing oopses.
+(See upstream commit: 6efb971ba8edfbd80b666f29de12882852f095ae)
+This patch fixes that.
+
+Fixes: 92833e8b5db6c209e9311ac8c6a44d3bf1856659
+Reported-by: Thorsten Glaser <tg@mirbsd.de>
+Link: https://bugs.debian.org/1013299
+---
+ net/sched/sch_generic.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 7c1b1eff84f4..cad2586c3473 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -970,8 +970,6 @@ static void qdisc_destroy(struct Qdisc *qdisc)
+ const struct Qdisc_ops *ops;
+ struct sk_buff *skb, *tmp;
+
+- if (!qdisc)
+- return;
+ ops = qdisc->ops;
+
+ #ifdef CONFIG_NET_SCHED
+@@ -1003,6 +1001,9 @@ static void qdisc_destroy(struct Qdisc *qdisc)
+
+ void qdisc_put(struct Qdisc *qdisc)
+ {
++ if (!qdisc)
++ return;
++
+ if (qdisc->flags & TCQ_F_BUILTIN ||
+ !refcount_dec_and_test(&qdisc->refcnt))
+ return;
+--
+2.36.1
+
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch
new file mode 100644
index 000000000..d50476bca
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch
@@ -0,0 +1,153 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 1 Mar 2019 17:19:00 -0800
+Subject: perf script python: Add Python3 support to event_analyzing_sample.py
+Origin: https://git.kernel.org/linus/c253c72e9d6723c8b078beb362f050059ef5de39
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the event_analyzing_sample.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Cc: Feng Tang <feng.tang@intel.com>
+Link: http://lkml.kernel.org/r/20190302011903.2416-5-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/event_analyzing_sample.py | 48 ++++++++++----------
+ 1 file changed, 25 insertions(+), 23 deletions(-)
+
+--- a/tools/perf/scripts/python/event_analyzing_sample.py
++++ b/tools/perf/scripts/python/event_analyzing_sample.py
+@@ -15,6 +15,8 @@
+ # for a x86 HW PMU event: PEBS with load latency data.
+ #
+
++from __future__ import print_function
++
+ import os
+ import sys
+ import math
+@@ -37,7 +39,7 @@ con = sqlite3.connect("/dev/shm/perf.db"
+ con.isolation_level = None
+
+ def trace_begin():
+- print "In trace_begin:\n"
++ print("In trace_begin:\n")
+
+ #
+ # Will create several tables at the start, pebs_ll is for PEBS data with
+@@ -76,12 +78,12 @@ def process_event(param_dict):
+ name = param_dict["ev_name"]
+
+ # Symbol and dso info are not always resolved
+- if (param_dict.has_key("dso")):
++ if ("dso" in param_dict):
+ dso = param_dict["dso"]
+ else:
+ dso = "Unknown_dso"
+
+- if (param_dict.has_key("symbol")):
++ if ("symbol" in param_dict):
+ symbol = param_dict["symbol"]
+ else:
+ symbol = "Unknown_symbol"
+@@ -102,7 +104,7 @@ def insert_db(event):
+ event.ip, event.status, event.dse, event.dla, event.lat))
+
+ def trace_end():
+- print "In trace_end:\n"
++ print("In trace_end:\n")
+ # We show the basic info for the 2 type of event classes
+ show_general_events()
+ show_pebs_ll()
+@@ -123,29 +125,29 @@ def show_general_events():
+ # Check the total record number in the table
+ count = con.execute("select count(*) from gen_events")
+ for t in count:
+- print "There is %d records in gen_events table" % t[0]
++ print("There is %d records in gen_events table" % t[0])
+ if t[0] == 0:
+ return
+
+- print "Statistics about the general events grouped by thread/symbol/dso: \n"
++ print("Statistics about the general events grouped by thread/symbol/dso: \n")
+
+ # Group by thread
+ commq = con.execute("select comm, count(comm) from gen_events group by comm order by -count(comm)")
+- print "\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42)
++ print("\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42))
+ for row in commq:
+- print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
++ print("%16s %8d %s" % (row[0], row[1], num2sym(row[1])))
+
+ # Group by symbol
+- print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58)
++ print("\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58))
+ symbolq = con.execute("select symbol, count(symbol) from gen_events group by symbol order by -count(symbol)")
+ for row in symbolq:
+- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1])))
+
+ # Group by dso
+- print "\n%40s %8s %16s\n%s" % ("dso", "number", "histogram", "="*74)
++ print("\n%40s %8s %16s\n%s" % ("dso", "number", "histogram", "="*74))
+ dsoq = con.execute("select dso, count(dso) from gen_events group by dso order by -count(dso)")
+ for row in dsoq:
+- print "%40s %8d %s" % (row[0], row[1], num2sym(row[1]))
++ print("%40s %8d %s" % (row[0], row[1], num2sym(row[1])))
+
+ #
+ # This function just shows the basic info, and we could do more with the
+@@ -156,35 +158,35 @@ def show_pebs_ll():
+
+ count = con.execute("select count(*) from pebs_ll")
+ for t in count:
+- print "There is %d records in pebs_ll table" % t[0]
++ print("There is %d records in pebs_ll table" % t[0])
+ if t[0] == 0:
+ return
+
+- print "Statistics about the PEBS Load Latency events grouped by thread/symbol/dse/latency: \n"
++ print("Statistics about the PEBS Load Latency events grouped by thread/symbol/dse/latency: \n")
+
+ # Group by thread
+ commq = con.execute("select comm, count(comm) from pebs_ll group by comm order by -count(comm)")
+- print "\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42)
++ print("\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42))
+ for row in commq:
+- print "%16s %8d %s" % (row[0], row[1], num2sym(row[1]))
++ print("%16s %8d %s" % (row[0], row[1], num2sym(row[1])))
+
+ # Group by symbol
+- print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58)
++ print("\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58))
+ symbolq = con.execute("select symbol, count(symbol) from pebs_ll group by symbol order by -count(symbol)")
+ for row in symbolq:
+- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1])))
+
+ # Group by dse
+ dseq = con.execute("select dse, count(dse) from pebs_ll group by dse order by -count(dse)")
+- print "\n%32s %8s %16s\n%s" % ("dse", "number", "histogram", "="*58)
++ print("\n%32s %8s %16s\n%s" % ("dse", "number", "histogram", "="*58))
+ for row in dseq:
+- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1])))
+
+ # Group by latency
+ latq = con.execute("select lat, count(lat) from pebs_ll group by lat order by lat")
+- print "\n%32s %8s %16s\n%s" % ("latency", "number", "histogram", "="*58)
++ print("\n%32s %8s %16s\n%s" % ("latency", "number", "histogram", "="*58))
+ for row in latq:
+- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1])))
+
+ def trace_unhandled(event_name, context, event_fields_dict):
+- print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
++ print (' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]))
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch
new file mode 100644
index 000000000..25633c098
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch
@@ -0,0 +1,214 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 8 Mar 2019 16:05:16 -0800
+Subject: perf script python: Add Python3 support to export-to-postgresql.py
+Origin: https://git.kernel.org/linus/1937b0560c3ea43b1b0f7d3617949ca50de8f8c0
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the export-to-postgresql.py script.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Link: http://lkml.kernel.org/r/20190309000518.2438-3-tonyj@suse.de
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/export-to-postgresql.py | 58 +++++++++++++++-------
+ 1 file changed, 41 insertions(+), 17 deletions(-)
+
+--- a/tools/perf/scripts/python/export-to-postgresql.py
++++ b/tools/perf/scripts/python/export-to-postgresql.py
+@@ -10,6 +10,8 @@
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ # more details.
+
++from __future__ import print_function
++
+ import os
+ import sys
+ import struct
+@@ -199,6 +201,18 @@ import datetime
+
+ from PySide.QtSql import *
+
++if sys.version_info < (3, 0):
++ def toserverstr(str):
++ return str
++ def toclientstr(str):
++ return str
++else:
++ # Assume UTF-8 server_encoding and client_encoding
++ def toserverstr(str):
++ return bytes(str, "UTF_8")
++ def toclientstr(str):
++ return bytes(str, "UTF_8")
++
+ # Need to access PostgreSQL C library directly to use COPY FROM STDIN
+ from ctypes import *
+ libpq = CDLL("libpq.so.5")
+@@ -234,12 +248,14 @@ perf_db_export_mode = True
+ perf_db_export_calls = False
+ perf_db_export_callchains = False
+
++def printerr(*args, **kw_args):
++ print(*args, file=sys.stderr, **kw_args)
+
+ def usage():
+- print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]"
+- print >> sys.stderr, "where: columns 'all' or 'branches'"
+- print >> sys.stderr, " calls 'calls' => create calls and call_paths table"
+- print >> sys.stderr, " callchains 'callchains' => create call_paths table"
++ printerr("Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]")
++ printerr("where: columns 'all' or 'branches'")
++ printerr(" calls 'calls' => create calls and call_paths table")
++ printerr(" callchains 'callchains' => create call_paths table")
+ raise Exception("Too few arguments")
+
+ if (len(sys.argv) < 2):
+@@ -273,7 +289,7 @@ def do_query(q, s):
+ return
+ raise Exception("Query failed: " + q.lastError().text())
+
+-print datetime.datetime.today(), "Creating database..."
++print(datetime.datetime.today(), "Creating database...")
+
+ db = QSqlDatabase.addDatabase('QPSQL')
+ query = QSqlQuery(db)
+@@ -504,12 +520,12 @@ do_query(query, 'CREATE VIEW samples_vie
+ ' FROM samples')
+
+
+-file_header = struct.pack("!11sii", "PGCOPY\n\377\r\n\0", 0, 0)
+-file_trailer = "\377\377"
++file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0)
++file_trailer = b"\377\377"
+
+ def open_output_file(file_name):
+ path_name = output_dir_name + "/" + file_name
+- file = open(path_name, "w+")
++ file = open(path_name, "wb+")
+ file.write(file_header)
+ return file
+
+@@ -524,13 +540,13 @@ def copy_output_file_direct(file, table_
+
+ # Use COPY FROM STDIN because security may prevent postgres from accessing the files directly
+ def copy_output_file(file, table_name):
+- conn = PQconnectdb("dbname = " + dbname)
++ conn = PQconnectdb(toclientstr("dbname = " + dbname))
+ if (PQstatus(conn)):
+ raise Exception("COPY FROM STDIN PQconnectdb failed")
+ file.write(file_trailer)
+ file.seek(0)
+ sql = "COPY " + table_name + " FROM STDIN (FORMAT 'binary')"
+- res = PQexec(conn, sql)
++ res = PQexec(conn, toclientstr(sql))
+ if (PQresultStatus(res) != 4):
+ raise Exception("COPY FROM STDIN PQexec failed")
+ data = file.read(65536)
+@@ -564,7 +580,7 @@ if perf_db_export_calls:
+ call_file = open_output_file("call_table.bin")
+
+ def trace_begin():
+- print datetime.datetime.today(), "Writing to intermediate files..."
++ print(datetime.datetime.today(), "Writing to intermediate files...")
+ # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs
+ evsel_table(0, "unknown")
+ machine_table(0, 0, "unknown")
+@@ -579,7 +595,7 @@ def trace_begin():
+ unhandled_count = 0
+
+ def trace_end():
+- print datetime.datetime.today(), "Copying to database..."
++ print(datetime.datetime.today(), "Copying to database...")
+ copy_output_file(evsel_file, "selected_events")
+ copy_output_file(machine_file, "machines")
+ copy_output_file(thread_file, "threads")
+@@ -594,7 +610,7 @@ def trace_end():
+ if perf_db_export_calls:
+ copy_output_file(call_file, "calls")
+
+- print datetime.datetime.today(), "Removing intermediate files..."
++ print(datetime.datetime.today(), "Removing intermediate files...")
+ remove_output_file(evsel_file)
+ remove_output_file(machine_file)
+ remove_output_file(thread_file)
+@@ -609,7 +625,7 @@ def trace_end():
+ if perf_db_export_calls:
+ remove_output_file(call_file)
+ os.rmdir(output_dir_name)
+- print datetime.datetime.today(), "Adding primary keys"
++ print(datetime.datetime.today(), "Adding primary keys")
+ do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)')
+ do_query(query, 'ALTER TABLE machines ADD PRIMARY KEY (id)')
+ do_query(query, 'ALTER TABLE threads ADD PRIMARY KEY (id)')
+@@ -624,7 +640,7 @@ def trace_end():
+ if perf_db_export_calls:
+ do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)')
+
+- print datetime.datetime.today(), "Adding foreign keys"
++ print(datetime.datetime.today(), "Adding foreign keys")
+ do_query(query, 'ALTER TABLE threads '
+ 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),'
+ 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)')
+@@ -659,8 +675,8 @@ def trace_end():
+ do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
+
+ if (unhandled_count):
+- print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events"
+- print datetime.datetime.today(), "Done"
++ print(datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events")
++ print(datetime.datetime.today(), "Done")
+
+ def trace_unhandled(event_name, context, event_fields_dict):
+ global unhandled_count
+@@ -670,12 +686,14 @@ def sched__sched_switch(*x):
+ pass
+
+ def evsel_table(evsel_id, evsel_name, *x):
++ evsel_name = toserverstr(evsel_name)
+ n = len(evsel_name)
+ fmt = "!hiqi" + str(n) + "s"
+ value = struct.pack(fmt, 2, 8, evsel_id, n, evsel_name)
+ evsel_file.write(value)
+
+ def machine_table(machine_id, pid, root_dir, *x):
++ root_dir = toserverstr(root_dir)
+ n = len(root_dir)
+ fmt = "!hiqiii" + str(n) + "s"
+ value = struct.pack(fmt, 3, 8, machine_id, 4, pid, n, root_dir)
+@@ -686,6 +704,7 @@ def thread_table(thread_id, machine_id,
+ thread_file.write(value)
+
+ def comm_table(comm_id, comm_str, *x):
++ comm_str = toserverstr(comm_str)
+ n = len(comm_str)
+ fmt = "!hiqi" + str(n) + "s"
+ value = struct.pack(fmt, 2, 8, comm_id, n, comm_str)
+@@ -697,6 +716,9 @@ def comm_thread_table(comm_thread_id, co
+ comm_thread_file.write(value)
+
+ def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x):
++ short_name = toserverstr(short_name)
++ long_name = toserverstr(long_name)
++ build_id = toserverstr(build_id)
+ n1 = len(short_name)
+ n2 = len(long_name)
+ n3 = len(build_id)
+@@ -705,12 +727,14 @@ def dso_table(dso_id, machine_id, short_
+ dso_file.write(value)
+
+ def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x):
++ symbol_name = toserverstr(symbol_name)
+ n = len(symbol_name)
+ fmt = "!hiqiqiqiqiii" + str(n) + "s"
+ value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name)
+ symbol_file.write(value)
+
+ def branch_type_table(branch_type, name, *x):
++ name = toserverstr(name)
+ n = len(name)
+ fmt = "!hiii" + str(n) + "s"
+ value = struct.pack(fmt, 2, 4, branch_type, n, name)
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch
new file mode 100644
index 000000000..4301e54b6
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch
@@ -0,0 +1,85 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 8 Mar 2019 16:05:17 -0800
+Subject: perf script python: Add Python3 support to export-to-sqlite.py
+Origin: https://git.kernel.org/linus/ebf6c5c181abe9309788c6241d39602a1ce18723
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the export-to-sqlite.py script
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: http://lkml.kernel.org/r/20190309000518.2438-4-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/export-to-sqlite.py | 23 ++++++++++++++---------
+ 1 file changed, 14 insertions(+), 9 deletions(-)
+
+--- a/tools/perf/scripts/python/export-to-sqlite.py
++++ b/tools/perf/scripts/python/export-to-sqlite.py
+@@ -10,6 +10,8 @@
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ # more details.
+
++from __future__ import print_function
++
+ import os
+ import sys
+ import struct
+@@ -60,11 +62,14 @@ perf_db_export_mode = True
+ perf_db_export_calls = False
+ perf_db_export_callchains = False
+
++def printerr(*args, **keyword_args):
++ print(*args, file=sys.stderr, **keyword_args)
++
+ def usage():
+- print >> sys.stderr, "Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>]"
+- print >> sys.stderr, "where: columns 'all' or 'branches'"
+- print >> sys.stderr, " calls 'calls' => create calls and call_paths table"
+- print >> sys.stderr, " callchains 'callchains' => create call_paths table"
++ printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>]");
++ printerr("where: columns 'all' or 'branches'");
++ printerr(" calls 'calls' => create calls and call_paths table");
++ printerr(" callchains 'callchains' => create call_paths table");
+ raise Exception("Too few arguments")
+
+ if (len(sys.argv) < 2):
+@@ -100,7 +105,7 @@ def do_query_(q):
+ return
+ raise Exception("Query failed: " + q.lastError().text())
+
+-print datetime.datetime.today(), "Creating database..."
++print(datetime.datetime.today(), "Creating database ...")
+
+ db_exists = False
+ try:
+@@ -376,7 +381,7 @@ if perf_db_export_calls:
+ call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)")
+
+ def trace_begin():
+- print datetime.datetime.today(), "Writing records..."
++ print(datetime.datetime.today(), "Writing records...")
+ do_query(query, 'BEGIN TRANSACTION')
+ # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs
+ evsel_table(0, "unknown")
+@@ -394,13 +399,13 @@ unhandled_count = 0
+ def trace_end():
+ do_query(query, 'END TRANSACTION')
+
+- print datetime.datetime.today(), "Adding indexes"
++ print(datetime.datetime.today(), "Adding indexes")
+ if perf_db_export_calls:
+ do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)')
+
+ if (unhandled_count):
+- print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events"
+- print datetime.datetime.today(), "Done"
++ print(datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events")
++ print(datetime.datetime.today(), "Done")
+
+ def trace_unhandled(event_name, context, event_fields_dict):
+ global unhandled_count
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch
new file mode 100644
index 000000000..617145de6
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch
@@ -0,0 +1,76 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:08 -0800
+Subject: perf script python: Add Python3 support to
+ failed-syscalls-by-pid.py
+Origin: https://git.kernel.org/linus/9b2700efc57f46fe63beee5f64fcfe2746936b4e
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the failed-syscalls-by-pid.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Cc: Tom Zanussi <tzanussi@gmail.com>
+Link: http://lkml.kernel.org/r/20190222230619.17887-5-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/failed-syscalls-by-pid.py | 21 ++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/tools/perf/scripts/python/failed-syscalls-by-pid.py
++++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py
+@@ -5,6 +5,8 @@
+ # Displays system-wide failed system call totals, broken down by pid.
+ # If a [comm] arg is specified, only syscalls called by [comm] are displayed.
+
++from __future__ import print_function
++
+ import os
+ import sys
+
+@@ -32,7 +34,7 @@ if len(sys.argv) > 1:
+ syscalls = autodict()
+
+ def trace_begin():
+- print "Press control+C to stop and show the summary"
++ print("Press control+C to stop and show the summary")
+
+ def trace_end():
+ print_error_totals()
+@@ -57,22 +59,21 @@ def syscalls__sys_exit(event_name, conte
+
+ def print_error_totals():
+ if for_comm is not None:
+- print "\nsyscall errors for %s:\n\n" % (for_comm),
++ print("\nsyscall errors for %s:\n" % (for_comm))
+ else:
+- print "\nsyscall errors:\n\n",
++ print("\nsyscall errors:\n")
+
+- print "%-30s %10s\n" % ("comm [pid]", "count"),
+- print "%-30s %10s\n" % ("------------------------------", \
+- "----------"),
++ print("%-30s %10s" % ("comm [pid]", "count"))
++ print("%-30s %10s" % ("------------------------------", "----------"))
+
+ comm_keys = syscalls.keys()
+ for comm in comm_keys:
+ pid_keys = syscalls[comm].keys()
+ for pid in pid_keys:
+- print "\n%s [%d]\n" % (comm, pid),
++ print("\n%s [%d]" % (comm, pid))
+ id_keys = syscalls[comm][pid].keys()
+ for id in id_keys:
+- print " syscall: %-16s\n" % syscall_name(id),
++ print(" syscall: %-16s" % syscall_name(id))
+ ret_keys = syscalls[comm][pid][id].keys()
+- for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k), reverse = True):
+- print " err = %-20s %10d\n" % (strerror(ret), val),
++ for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True):
++ print(" err = %-20s %10d" % (strerror(ret), val))
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch
new file mode 100644
index 000000000..3fb8f1baf
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch
@@ -0,0 +1,57 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 1 Mar 2019 17:18:58 -0800
+Subject: perf script python: Add Python3 support to futex-contention.py
+Origin: https://git.kernel.org/linus/de2ec16bd438945813198d4de2339a396904c206
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the futex-contention.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Link: http://lkml.kernel.org/r/20190302011903.2416-3-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/futex-contention.py | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/tools/perf/scripts/python/futex-contention.py
++++ b/tools/perf/scripts/python/futex-contention.py
+@@ -10,6 +10,8 @@
+ #
+ # Measures futex contention
+
++from __future__ import print_function
++
+ import os, sys
+ sys.path.append(os.environ['PERF_EXEC_PATH'] + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+ from Util import *
+@@ -33,18 +35,18 @@ def syscalls__sys_enter_futex(event, ctx
+
+ def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, callchain,
+ nr, ret):
+- if thread_blocktime.has_key(tid):
++ if tid in thread_blocktime:
+ elapsed = nsecs(s, ns) - thread_blocktime[tid]
+ add_stats(lock_waits, (tid, thread_thislock[tid]), elapsed)
+ del thread_blocktime[tid]
+ del thread_thislock[tid]
+
+ def trace_begin():
+- print "Press control+C to stop and show the summary"
++ print("Press control+C to stop and show the summary")
+
+ def trace_end():
+ for (tid, lock) in lock_waits:
+ min, max, avg, count = lock_waits[tid, lock]
+- print "%s[%d] lock %x contended %d times, %d avg ns" % \
+- (process_names[tid], tid, lock, count, avg)
++ print("%s[%d] lock %x contended %d times, %d avg ns" %
++ (process_names[tid], tid, lock, count, avg))
+
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch
new file mode 100644
index 000000000..c9dd3a189
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch
@@ -0,0 +1,133 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Tue, 5 Mar 2019 08:19:02 -0800
+Subject: perf script python: Add Python3 support to intel-pt-events.py
+Origin: https://git.kernel.org/linus/fdf2460c297f1bb2f3bd20b3b52903b267af9050
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the intel-pt-events.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Acked-by: Adrian Hunter <adrian.hunter@intel.com>
+Link: http://lkml.kernel.org/r/fd26acf9-0c0f-717f-9664-a3c33043ce19@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/intel-pt-events.py | 32 ++++++++++++++++-----------
+ 1 file changed, 19 insertions(+), 13 deletions(-)
+
+--- a/tools/perf/scripts/python/intel-pt-events.py
++++ b/tools/perf/scripts/python/intel-pt-events.py
+@@ -10,6 +10,8 @@
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ # more details.
+
++from __future__ import print_function
++
+ import os
+ import sys
+ import struct
+@@ -22,34 +24,34 @@ sys.path.append(os.environ['PERF_EXEC_PA
+ #from Core import *
+
+ def trace_begin():
+- print "Intel PT Power Events and PTWRITE"
++ print("Intel PT Power Events and PTWRITE")
+
+ def trace_end():
+- print "End"
++ print("End")
+
+ def trace_unhandled(event_name, context, event_fields_dict):
+- print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
++ print(' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]))
+
+ def print_ptwrite(raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+ flags = data[0]
+ payload = data[1]
+ exact_ip = flags & 1
+- print "IP: %u payload: %#x" % (exact_ip, payload),
++ print("IP: %u payload: %#x" % (exact_ip, payload), end=' ')
+
+ def print_cbr(raw_buf):
+ data = struct.unpack_from("<BBBBII", raw_buf)
+ cbr = data[0]
+ f = (data[4] + 500) / 1000
+ p = ((cbr * 1000 / data[2]) + 5) / 10
+- print "%3u freq: %4u MHz (%3u%%)" % (cbr, f, p),
++ print("%3u freq: %4u MHz (%3u%%)" % (cbr, f, p), end=' ')
+
+ def print_mwait(raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+ payload = data[1]
+ hints = payload & 0xff
+ extensions = (payload >> 32) & 0x3
+- print "hints: %#x extensions: %#x" % (hints, extensions),
++ print("hints: %#x extensions: %#x" % (hints, extensions), end=' ')
+
+ def print_pwre(raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+@@ -57,13 +59,14 @@ def print_pwre(raw_buf):
+ hw = (payload >> 7) & 1
+ cstate = (payload >> 12) & 0xf
+ subcstate = (payload >> 8) & 0xf
+- print "hw: %u cstate: %u sub-cstate: %u" % (hw, cstate, subcstate),
++ print("hw: %u cstate: %u sub-cstate: %u" % (hw, cstate, subcstate),
++ end=' ')
+
+ def print_exstop(raw_buf):
+ data = struct.unpack_from("<I", raw_buf)
+ flags = data[0]
+ exact_ip = flags & 1
+- print "IP: %u" % (exact_ip),
++ print("IP: %u" % (exact_ip), end=' ')
+
+ def print_pwrx(raw_buf):
+ data = struct.unpack_from("<IQ", raw_buf)
+@@ -71,18 +74,21 @@ def print_pwrx(raw_buf):
+ deepest_cstate = payload & 0xf
+ last_cstate = (payload >> 4) & 0xf
+ wake_reason = (payload >> 8) & 0xf
+- print "deepest cstate: %u last cstate: %u wake reason: %#x" % (deepest_cstate, last_cstate, wake_reason),
++ print("deepest cstate: %u last cstate: %u wake reason: %#x" %
++ (deepest_cstate, last_cstate, wake_reason), end=' ')
+
+ def print_common_start(comm, sample, name):
+ ts = sample["time"]
+ cpu = sample["cpu"]
+ pid = sample["pid"]
+ tid = sample["tid"]
+- print "%16s %5u/%-5u [%03u] %9u.%09u %7s:" % (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name),
++ print("%16s %5u/%-5u [%03u] %9u.%09u %7s:" %
++ (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name),
++ end=' ')
+
+ def print_common_ip(sample, symbol, dso):
+ ip = sample["ip"]
+- print "%16x %s (%s)" % (ip, symbol, dso)
++ print("%16x %s (%s)" % (ip, symbol, dso))
+
+ def process_event(param_dict):
+ event_attr = param_dict["attr"]
+@@ -92,12 +98,12 @@ def process_event(param_dict):
+ name = param_dict["ev_name"]
+
+ # Symbol and dso info are not always resolved
+- if (param_dict.has_key("dso")):
++ if "dso" in param_dict:
+ dso = param_dict["dso"]
+ else:
+ dso = "[unknown]"
+
+- if (param_dict.has_key("symbol")):
++ if "symbol" in param_dict:
+ symbol = param_dict["symbol"]
+ else:
+ symbol = "[unknown]"
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch
new file mode 100644
index 000000000..3b9e39cc9
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch
@@ -0,0 +1,76 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:11 -0800
+Subject: perf script python: Add Python3 support to mem-phys-addr.py
+Origin: https://git.kernel.org/linus/e4d053ddb4c48cbde27b4c5edd3cc8f957684e4f
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the mem-phys-addr.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Link: http://lkml.kernel.org/r/20190222230619.17887-8-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/mem-phys-addr.py | 24 ++++++++++++++----------
+ 1 file changed, 14 insertions(+), 10 deletions(-)
+
+--- a/tools/perf/scripts/python/mem-phys-addr.py
++++ b/tools/perf/scripts/python/mem-phys-addr.py
+@@ -4,6 +4,8 @@
+ # Copyright (c) 2018, Intel Corporation.
+
+ from __future__ import division
++from __future__ import print_function
++
+ import os
+ import sys
+ import struct
+@@ -31,21 +33,23 @@ def parse_iomem():
+ for i, j in enumerate(f):
+ m = re.split('-|:',j,2)
+ if m[2].strip() == 'System RAM':
+- system_ram.append(long(m[0], 16))
+- system_ram.append(long(m[1], 16))
++ system_ram.append(int(m[0], 16))
++ system_ram.append(int(m[1], 16))
+ if m[2].strip() == 'Persistent Memory':
+- pmem.append(long(m[0], 16))
+- pmem.append(long(m[1], 16))
++ pmem.append(int(m[0], 16))
++ pmem.append(int(m[1], 16))
+
+ def print_memory_type():
+- print "Event: %s" % (event_name)
+- print "%-40s %10s %10s\n" % ("Memory type", "count", "percentage"),
+- print "%-40s %10s %10s\n" % ("----------------------------------------", \
++ print("Event: %s" % (event_name))
++ print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='')
++ print("%-40s %10s %10s\n" % ("----------------------------------------",
+ "-----------", "-----------"),
++ end='');
+ total = sum(load_mem_type_cnt.values())
+ for mem_type, count in sorted(load_mem_type_cnt.most_common(), \
+- key = lambda(k, v): (v, k), reverse = True):
+- print "%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total),
++ key = lambda kv: (kv[1], kv[0]), reverse = True):
++ print("%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total),
++ end='')
+
+ def trace_begin():
+ parse_iomem()
+@@ -80,7 +84,7 @@ def find_memory_type(phys_addr):
+ f.seek(0, 0)
+ for j in f:
+ m = re.split('-|:',j,2)
+- if long(m[0], 16) <= phys_addr <= long(m[1], 16):
++ if int(m[0], 16) <= phys_addr <= int(m[1], 16):
+ return m[2]
+ return "N/A"
+
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch
new file mode 100644
index 000000000..631a94449
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch
@@ -0,0 +1,59 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:12 -0800
+Subject: perf script python: Add Python3 support to net_dropmonitor.py
+Origin: https://git.kernel.org/linus/8c42b9600e561666233b9c557a5209d0dc853ba1
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the net_dropmonitor.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Link: http://lkml.kernel.org/r/20190222230619.17887-9-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/net_dropmonitor.py | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/tools/perf/scripts/python/net_dropmonitor.py
++++ b/tools/perf/scripts/python/net_dropmonitor.py
+@@ -1,6 +1,8 @@
+ # Monitor the system for dropped packets and proudce a report of drop locations and counts
+ # SPDX-License-Identifier: GPL-2.0
+
++from __future__ import print_function
++
+ import os
+ import sys
+
+@@ -50,19 +52,19 @@ def get_sym(sloc):
+ return (None, 0)
+
+ def print_drop_table():
+- print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT")
++ print("%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT"))
+ for i in drop_log.keys():
+ (sym, off) = get_sym(i)
+ if sym == None:
+ sym = i
+- print "%25s %25s %25s" % (sym, off, drop_log[i])
++ print("%25s %25s %25s" % (sym, off, drop_log[i]))
+
+
+ def trace_begin():
+- print "Starting trace (Ctrl-C to dump results)"
++ print("Starting trace (Ctrl-C to dump results)")
+
+ def trace_end():
+- print "Gathering kallsyms data"
++ print("Gathering kallsyms data")
+ get_kallsyms_table()
+ print_drop_table()
+
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch
new file mode 100644
index 000000000..2d501dd4c
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch
@@ -0,0 +1,180 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:05 -0800
+Subject: perf script python: Add Python3 support to netdev-times.py
+Origin: https://git.kernel.org/linus/02b03ec383e0c79d73aa4b402b3427a8b490ef9f
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the netdev-times.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2
+version is now v2.6.
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Cc: Sanagi Koki <sanagi.koki@jp.fujitsu.com>
+Link: http://lkml.kernel.org/r/20190222230619.17887-2-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/netdev-times.py | 82 +++++++++++++++---------------
+ 1 file changed, 42 insertions(+), 40 deletions(-)
+
+--- a/tools/perf/scripts/python/netdev-times.py
++++ b/tools/perf/scripts/python/netdev-times.py
+@@ -8,6 +8,8 @@
+ # dev=: show only thing related to specified device
+ # debug: work with debug mode. It shows buffer status.
+
++from __future__ import print_function
++
+ import os
+ import sys
+
+@@ -17,6 +19,7 @@ sys.path.append(os.environ['PERF_EXEC_PA
+ from perf_trace_context import *
+ from Core import *
+ from Util import *
++from functools import cmp_to_key
+
+ all_event_list = []; # insert all tracepoint event related with this script
+ irq_dic = {}; # key is cpu and value is a list which stacks irqs
+@@ -61,12 +64,12 @@ def diff_msec(src, dst):
+ def print_transmit(hunk):
+ if dev != 0 and hunk['dev'].find(dev) < 0:
+ return
+- print "%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" % \
++ print("%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" %
+ (hunk['dev'], hunk['len'],
+ nsecs_secs(hunk['queue_t']),
+ nsecs_nsecs(hunk['queue_t'])/1000,
+ diff_msec(hunk['queue_t'], hunk['xmit_t']),
+- diff_msec(hunk['xmit_t'], hunk['free_t']))
++ diff_msec(hunk['xmit_t'], hunk['free_t'])))
+
+ # Format for displaying rx packet processing
+ PF_IRQ_ENTRY= " irq_entry(+%.3fmsec irq=%d:%s)"
+@@ -98,55 +101,55 @@ def print_receive(hunk):
+ if show_hunk == 0:
+ return
+
+- print "%d.%06dsec cpu=%d" % \
+- (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu)
++ print("%d.%06dsec cpu=%d" %
++ (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu))
+ for i in range(len(irq_list)):
+- print PF_IRQ_ENTRY % \
++ print(PF_IRQ_ENTRY %
+ (diff_msec(base_t, irq_list[i]['irq_ent_t']),
+- irq_list[i]['irq'], irq_list[i]['name'])
+- print PF_JOINT
++ irq_list[i]['irq'], irq_list[i]['name']))
++ print(PF_JOINT)
+ irq_event_list = irq_list[i]['event_list']
+ for j in range(len(irq_event_list)):
+ irq_event = irq_event_list[j]
+ if irq_event['event'] == 'netif_rx':
+- print PF_NET_RX % \
++ print(PF_NET_RX %
+ (diff_msec(base_t, irq_event['time']),
+- irq_event['skbaddr'])
+- print PF_JOINT
+- print PF_SOFT_ENTRY % \
+- diff_msec(base_t, hunk['sirq_ent_t'])
+- print PF_JOINT
++ irq_event['skbaddr']))
++ print(PF_JOINT)
++ print(PF_SOFT_ENTRY %
++ diff_msec(base_t, hunk['sirq_ent_t']))
++ print(PF_JOINT)
+ event_list = hunk['event_list']
+ for i in range(len(event_list)):
+ event = event_list[i]
+ if event['event_name'] == 'napi_poll':
+- print PF_NAPI_POLL % \
+- (diff_msec(base_t, event['event_t']), event['dev'])
++ print(PF_NAPI_POLL %
++ (diff_msec(base_t, event['event_t']), event['dev']))
+ if i == len(event_list) - 1:
+- print ""
++ print("")
+ else:
+- print PF_JOINT
++ print(PF_JOINT)
+ else:
+- print PF_NET_RECV % \
++ print(PF_NET_RECV %
+ (diff_msec(base_t, event['event_t']), event['skbaddr'],
+- event['len'])
++ event['len']))
+ if 'comm' in event.keys():
+- print PF_WJOINT
+- print PF_CPY_DGRAM % \
++ print(PF_WJOINT)
++ print(PF_CPY_DGRAM %
+ (diff_msec(base_t, event['comm_t']),
+- event['pid'], event['comm'])
++ event['pid'], event['comm']))
+ elif 'handle' in event.keys():
+- print PF_WJOINT
++ print(PF_WJOINT)
+ if event['handle'] == "kfree_skb":
+- print PF_KFREE_SKB % \
++ print(PF_KFREE_SKB %
+ (diff_msec(base_t,
+ event['comm_t']),
+- event['location'])
++ event['location']))
+ elif event['handle'] == "consume_skb":
+- print PF_CONS_SKB % \
++ print(PF_CONS_SKB %
+ diff_msec(base_t,
+- event['comm_t'])
+- print PF_JOINT
++ event['comm_t']))
++ print(PF_JOINT)
+
+ def trace_begin():
+ global show_tx
+@@ -172,8 +175,7 @@ def trace_begin():
+
+ def trace_end():
+ # order all events in time
+- all_event_list.sort(lambda a,b :cmp(a[EINFO_IDX_TIME],
+- b[EINFO_IDX_TIME]))
++ all_event_list.sort(key=cmp_to_key(lambda a,b :a[EINFO_IDX_TIME] < b[EINFO_IDX_TIME]))
+ # process all events
+ for i in range(len(all_event_list)):
+ event_info = all_event_list[i]
+@@ -210,19 +212,19 @@ def trace_end():
+ print_receive(receive_hunk_list[i])
+ # display transmit hunks
+ if show_tx:
+- print " dev len Qdisc " \
+- " netdevice free"
++ print(" dev len Qdisc "
++ " netdevice free")
+ for i in range(len(tx_free_list)):
+ print_transmit(tx_free_list[i])
+ if debug:
+- print "debug buffer status"
+- print "----------------------------"
+- print "xmit Qdisc:remain:%d overflow:%d" % \
+- (len(tx_queue_list), of_count_tx_queue_list)
+- print "xmit netdevice:remain:%d overflow:%d" % \
+- (len(tx_xmit_list), of_count_tx_xmit_list)
+- print "receive:remain:%d overflow:%d" % \
+- (len(rx_skb_list), of_count_rx_skb_list)
++ print("debug buffer status")
++ print("----------------------------")
++ print("xmit Qdisc:remain:%d overflow:%d" %
++ (len(tx_queue_list), of_count_tx_queue_list))
++ print("xmit netdevice:remain:%d overflow:%d" %
++ (len(tx_xmit_list), of_count_tx_xmit_list))
++ print("receive:remain:%d overflow:%d" %
++ (len(rx_skb_list), of_count_rx_skb_list))
+
+ # called from perf, when it finds a correspoinding event
+ def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec):
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch
new file mode 100644
index 000000000..1c8fdc5a1
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch
@@ -0,0 +1,87 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:13 -0800
+Subject: perf script python: Add Python3 support to powerpc-hcalls.py
+Origin: https://git.kernel.org/linus/118af5bf799bd1876c3999766d1d2f845d45f019
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the powerpc-hcalls.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
+Link: http://lkml.kernel.org/r/20190222230619.17887-10-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/powerpc-hcalls.py | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/tools/perf/scripts/python/powerpc-hcalls.py
++++ b/tools/perf/scripts/python/powerpc-hcalls.py
+@@ -4,6 +4,8 @@
+ #
+ # Hypervisor call statisics
+
++from __future__ import print_function
++
+ import os
+ import sys
+
+@@ -149,7 +151,7 @@ hcall_table = {
+ }
+
+ def hcall_table_lookup(opcode):
+- if (hcall_table.has_key(opcode)):
++ if (opcode in hcall_table):
+ return hcall_table[opcode]
+ else:
+ return opcode
+@@ -157,8 +159,8 @@ def hcall_table_lookup(opcode):
+ print_ptrn = '%-28s%10s%10s%10s%10s'
+
+ def trace_end():
+- print print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)')
+- print '-' * 68
++ print(print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)'))
++ print('-' * 68)
+ for opcode in output:
+ h_name = hcall_table_lookup(opcode)
+ time = output[opcode]['time']
+@@ -166,14 +168,14 @@ def trace_end():
+ min_t = output[opcode]['min']
+ max_t = output[opcode]['max']
+
+- print print_ptrn % (h_name, cnt, min_t, max_t, time/cnt)
++ print(print_ptrn % (h_name, cnt, min_t, max_t, time//cnt))
+
+ def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain,
+ opcode, retval):
+- if (d_enter.has_key(cpu) and d_enter[cpu].has_key(opcode)):
++ if (cpu in d_enter and opcode in d_enter[cpu]):
+ diff = nsecs(sec, nsec) - d_enter[cpu][opcode]
+
+- if (output.has_key(opcode)):
++ if (opcode in output):
+ output[opcode]['time'] += diff
+ output[opcode]['cnt'] += 1
+ if (output[opcode]['min'] > diff):
+@@ -190,11 +192,11 @@ def powerpc__hcall_exit(name, context, c
+
+ del d_enter[cpu][opcode]
+ # else:
+-# print "Can't find matching hcall_enter event. Ignoring sample"
++# print("Can't find matching hcall_enter event. Ignoring sample")
+
+ def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm,
+ callchain, opcode):
+- if (d_enter.has_key(cpu)):
++ if (cpu in d_enter):
+ d_enter[cpu][opcode] = nsecs(sec, nsec)
+ else:
+ d_enter[cpu] = {opcode: nsecs(sec, nsec)}
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch
new file mode 100644
index 000000000..fa90ed99a
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch
@@ -0,0 +1,69 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:14 -0800
+Subject: perf script python: Add Python3 support to sctop.py
+Origin: https://git.kernel.org/linus/ee75a896ae535d4219a82cc361be96394536f3ba
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the sctop.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Cc: Tom Zanussi <tzanussi@gmail.com>
+Link: http://lkml.kernel.org/r/20190222230619.17887-11-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/sctop.py | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+--- a/tools/perf/scripts/python/sctop.py
++++ b/tools/perf/scripts/python/sctop.py
+@@ -8,7 +8,14 @@
+ # will be refreshed every [interval] seconds. The default interval is
+ # 3 seconds.
+
+-import os, sys, thread, time
++from __future__ import print_function
++
++import os, sys, time
++
++try:
++ import thread
++except ImportError:
++ import _thread as thread
+
+ sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+@@ -62,18 +69,19 @@ def print_syscall_totals(interval):
+ while 1:
+ clear_term()
+ if for_comm is not None:
+- print "\nsyscall events for %s:\n\n" % (for_comm),
++ print("\nsyscall events for %s:\n" % (for_comm))
+ else:
+- print "\nsyscall events:\n\n",
++ print("\nsyscall events:\n")
+
+- print "%-40s %10s\n" % ("event", "count"),
+- print "%-40s %10s\n" % ("----------------------------------------", \
+- "----------"),
++ print("%-40s %10s" % ("event", "count"))
++ print("%-40s %10s" %
++ ("----------------------------------------",
++ "----------"))
+
+- for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \
++ for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \
+ reverse = True):
+ try:
+- print "%-40s %10d\n" % (syscall_name(id), val),
++ print("%-40s %10d" % (syscall_name(id), val))
+ except TypeError:
+ pass
+ syscalls.clear()
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch
new file mode 100644
index 000000000..ff41b4a20
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch
@@ -0,0 +1,45 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:15 -0800
+Subject: perf script python: Add Python3 support to stackcollapse.py
+Origin: https://git.kernel.org/linus/6d22d9991cf37edfe861569e2433342ad56206a7
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the stackcollapse.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Cc: Paolo Bonzini <pbonzini@redhat.com> <pbonzini@redhat.com>
+Link: http://lkml.kernel.org/r/20190222230619.17887-12-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/stackcollapse.py | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/tools/perf/scripts/python/stackcollapse.py
++++ b/tools/perf/scripts/python/stackcollapse.py
+@@ -19,6 +19,8 @@
+ # Written by Paolo Bonzini <pbonzini@redhat.com>
+ # Based on Brendan Gregg's stackcollapse-perf.pl script.
+
++from __future__ import print_function
++
+ import os
+ import sys
+ from collections import defaultdict
+@@ -120,7 +122,6 @@ def process_event(param_dict):
+ lines[stack_string] = lines[stack_string] + 1
+
+ def trace_end():
+- list = lines.keys()
+- list.sort()
++ list = sorted(lines)
+ for stack in list:
+- print "%s %d" % (stack, lines[stack])
++ print("%s %d" % (stack, lines[stack]))
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch
new file mode 100644
index 000000000..8ef6fa8b5
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch
@@ -0,0 +1,61 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:16 -0800
+Subject: perf script python: Add Python3 support to stat-cpi.py
+Origin: https://git.kernel.org/linus/e985bf761db7646cebcd236249da08bd264069de
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the stat-cpi.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Link: http://lkml.kernel.org/r/20190222230619.17887-13-tonyj@suse.de
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/stat-cpi.py | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/tools/perf/scripts/python/stat-cpi.py
++++ b/tools/perf/scripts/python/stat-cpi.py
+@@ -1,6 +1,8 @@
+ #!/usr/bin/env python
+ # SPDX-License-Identifier: GPL-2.0
+
++from __future__ import print_function
++
+ data = {}
+ times = []
+ threads = []
+@@ -20,8 +22,8 @@ def store_key(time, cpu, thread):
+ threads.append(thread)
+
+ def store(time, event, cpu, thread, val, ena, run):
+- #print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \
+- # (event, cpu, thread, time, val, ena, run)
++ #print("event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" %
++ # (event, cpu, thread, time, val, ena, run))
+
+ store_key(time, cpu, thread)
+ key = get_key(time, event, cpu, thread)
+@@ -59,7 +61,7 @@ def stat__interval(time):
+ if ins != 0:
+ cpi = cyc/float(ins)
+
+- print "%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins)
++ print("%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins))
+
+ def trace_end():
+ pass
+@@ -75,4 +77,4 @@ def trace_end():
+ # if ins != 0:
+ # cpi = cyc/float(ins)
+ #
+-# print "time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi)
++# print("time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi))
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch
new file mode 100644
index 000000000..9dc84ceac
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch
@@ -0,0 +1,74 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:18 -0800
+Subject: perf script python: Add Python3 support to
+ syscall-counts-by-pid.py
+Origin: https://git.kernel.org/linus/de667cce7f4f96b6e22da8fd9c065b961f355080
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the syscall-counts-by-pid.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Link: http://lkml.kernel.org/r/20190222230619.17887-15-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/syscall-counts-by-pid.py | 22 +++++++++++----------
+ 1 file changed, 12 insertions(+), 10 deletions(-)
+
+--- a/tools/perf/scripts/python/syscall-counts-by-pid.py
++++ b/tools/perf/scripts/python/syscall-counts-by-pid.py
+@@ -5,6 +5,8 @@
+ # Displays system-wide system call totals, broken down by syscall.
+ # If a [comm] arg is specified, only syscalls called by [comm] are displayed.
+
++from __future__ import print_function
++
+ import os, sys
+
+ sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+@@ -31,7 +33,7 @@ if len(sys.argv) > 1:
+ syscalls = autodict()
+
+ def trace_begin():
+- print "Press control+C to stop and show the summary"
++ print("Press control+C to stop and show the summary")
+
+ def trace_end():
+ print_syscall_totals()
+@@ -55,20 +57,20 @@ def syscalls__sys_enter(event_name, cont
+
+ def print_syscall_totals():
+ if for_comm is not None:
+- print "\nsyscall events for %s:\n\n" % (for_comm),
++ print("\nsyscall events for %s:\n" % (for_comm))
+ else:
+- print "\nsyscall events by comm/pid:\n\n",
++ print("\nsyscall events by comm/pid:\n")
+
+- print "%-40s %10s\n" % ("comm [pid]/syscalls", "count"),
+- print "%-40s %10s\n" % ("----------------------------------------", \
+- "----------"),
++ print("%-40s %10s" % ("comm [pid]/syscalls", "count"))
++ print("%-40s %10s" % ("----------------------------------------",
++ "----------"))
+
+ comm_keys = syscalls.keys()
+ for comm in comm_keys:
+ pid_keys = syscalls[comm].keys()
+ for pid in pid_keys:
+- print "\n%s [%d]\n" % (comm, pid),
++ print("\n%s [%d]" % (comm, pid))
+ id_keys = syscalls[comm][pid].keys()
+- for id, val in sorted(syscalls[comm][pid].iteritems(), \
+- key = lambda(k, v): (v, k), reverse = True):
+- print " %-38s %10d\n" % (syscall_name(id), val),
++ for id, val in sorted(syscalls[comm][pid].items(), \
++ key = lambda kv: (kv[1], kv[0]), reverse = True):
++ print(" %-38s %10d" % (syscall_name(id), val))
diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch
new file mode 100644
index 000000000..59c654479
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch
@@ -0,0 +1,65 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 22 Feb 2019 15:06:17 -0800
+Subject: perf script python: Add Python3 support to syscall-counts.py
+Origin: https://git.kernel.org/linus/1d1b0dbb859d175eb512a9f0e1ca7e44bd0192cd
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python2 and Python3 in the syscall-counts.py script
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of 'from __future__' implies the minimum supported Python2 version
+is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Link: http://lkml.kernel.org/r/20190222230619.17887-14-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/syscall-counts.py | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/tools/perf/scripts/python/syscall-counts.py
++++ b/tools/perf/scripts/python/syscall-counts.py
+@@ -5,6 +5,8 @@
+ # Displays system-wide system call totals, broken down by syscall.
+ # If a [comm] arg is specified, only syscalls called by [comm] are displayed.
+
++from __future__ import print_function
++
+ import os
+ import sys
+
+@@ -28,7 +30,7 @@ if len(sys.argv) > 1:
+ syscalls = autodict()
+
+ def trace_begin():
+- print "Press control+C to stop and show the summary"
++ print("Press control+C to stop and show the summary")
+
+ def trace_end():
+ print_syscall_totals()
+@@ -51,14 +53,14 @@ def syscalls__sys_enter(event_name, cont
+
+ def print_syscall_totals():
+ if for_comm is not None:
+- print "\nsyscall events for %s:\n\n" % (for_comm),
++ print("\nsyscall events for %s:\n" % (for_comm))
+ else:
+- print "\nsyscall events:\n\n",
++ print("\nsyscall events:\n")
+
+- print "%-40s %10s\n" % ("event", "count"),
+- print "%-40s %10s\n" % ("----------------------------------------", \
+- "-----------"),
++ print("%-40s %10s" % ("event", "count"))
++ print("%-40s %10s" % ("----------------------------------------",
++ "-----------"))
+
+- for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \
++ for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \
+ reverse = True):
+- print "%-40s %10d\n" % (syscall_name(id), val),
++ print("%-40s %10d" % (syscall_name(id), val))
diff --git a/debian/patches/bugfix/all/perf-script-python-Remove-mixed-indentation.patch b/debian/patches/bugfix/all/perf-script-python-Remove-mixed-indentation.patch
new file mode 100644
index 000000000..b18ceaea8
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-Remove-mixed-indentation.patch
@@ -0,0 +1,511 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 1 Mar 2019 17:18:57 -0800
+Subject: perf script python: Remove mixed indentation
+Origin: https://git.kernel.org/linus/b504d7f6876515b74c8e27a44ccdb22372616d97
+Bug-Debian: https://bugs.debian.org/944641
+
+Remove mixed indentation in Python scripts. Revert to either all tabs
+(most common form) or all spaces (4 or 8) depending on what was the
+intent of the original commit. This is necessary to complete Python3
+support as it will flag an error if it encounters mixed indentation.
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Link: http://lkml.kernel.org/r/20190302011903.2416-2-tonyj@suse.de
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/check-perf-trace.py | 69 +++++++++-----------
+ tools/perf/scripts/python/compaction-times.py | 8 +-
+ tools/perf/scripts/python/event_analyzing_sample.py | 6 -
+ tools/perf/scripts/python/failed-syscalls-by-pid.py | 34 ++++-----
+ tools/perf/scripts/python/futex-contention.py | 2
+ tools/perf/scripts/python/intel-pt-events.py | 28 ++++----
+ tools/perf/scripts/python/mem-phys-addr.py | 7 +-
+ tools/perf/scripts/python/net_dropmonitor.py | 2
+ tools/perf/scripts/python/netdev-times.py | 12 ++-
+ tools/perf/scripts/python/sched-migration.py | 6 -
+ tools/perf/scripts/python/sctop.py | 13 ++-
+ tools/perf/scripts/python/stackcollapse.py | 2
+ tools/perf/scripts/python/syscall-counts-by-pid.py | 47 ++++++-------
+ tools/perf/scripts/python/syscall-counts.py | 27 +++----
+ 14 files changed, 132 insertions(+), 131 deletions(-)
+
+--- a/tools/perf/scripts/python/check-perf-trace.py
++++ b/tools/perf/scripts/python/check-perf-trace.py
+@@ -23,60 +23,59 @@ def trace_begin():
+ pass
+
+ def trace_end():
+- print_unhandled()
++ print_unhandled()
+
+ def irq__softirq_entry(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- common_callchain, vec):
+- print_header(event_name, common_cpu, common_secs, common_nsecs,
+- common_pid, common_comm)
++ common_secs, common_nsecs, common_pid, common_comm,
++ common_callchain, vec):
++ print_header(event_name, common_cpu, common_secs, common_nsecs,
++ common_pid, common_comm)
+
+- print_uncommon(context)
++ print_uncommon(context)
+
+- print "vec=%s\n" % \
+- (symbol_str("irq__softirq_entry", "vec", vec)),
++ print "vec=%s\n" % (symbol_str("irq__softirq_entry", "vec", vec)),
+
+ def kmem__kmalloc(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- common_callchain, call_site, ptr, bytes_req, bytes_alloc,
+- gfp_flags):
+- print_header(event_name, common_cpu, common_secs, common_nsecs,
+- common_pid, common_comm)
++ common_secs, common_nsecs, common_pid, common_comm,
++ common_callchain, call_site, ptr, bytes_req, bytes_alloc,
++ gfp_flags):
++ print_header(event_name, common_cpu, common_secs, common_nsecs,
++ common_pid, common_comm)
+
+- print_uncommon(context)
++ print_uncommon(context)
+
+- print "call_site=%u, ptr=%u, bytes_req=%u, " \
++ print "call_site=%u, ptr=%u, bytes_req=%u, " \
+ "bytes_alloc=%u, gfp_flags=%s\n" % \
+ (call_site, ptr, bytes_req, bytes_alloc,
+-
+ flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)),
+
+ def trace_unhandled(event_name, context, event_fields_dict):
+- try:
+- unhandled[event_name] += 1
+- except TypeError:
+- unhandled[event_name] = 1
++ try:
++ unhandled[event_name] += 1
++ except TypeError:
++ unhandled[event_name] = 1
+
+ def print_header(event_name, cpu, secs, nsecs, pid, comm):
+ print "%-20s %5u %05u.%09u %8u %-20s " % \
+- (event_name, cpu, secs, nsecs, pid, comm),
++ (event_name, cpu, secs, nsecs, pid, comm),
+
+ # print trace fields not included in handler args
+ def print_uncommon(context):
+- print "common_preempt_count=%d, common_flags=%s, common_lock_depth=%d, " \
+- % (common_pc(context), trace_flag_str(common_flags(context)), \
+- common_lock_depth(context))
++ print "common_preempt_count=%d, common_flags=%s, " \
++ "common_lock_depth=%d, " % \
++ (common_pc(context), trace_flag_str(common_flags(context)),
++ common_lock_depth(context))
+
+ def print_unhandled():
+- keys = unhandled.keys()
+- if not keys:
+- return
+-
+- print "\nunhandled events:\n\n",
+-
+- print "%-40s %10s\n" % ("event", "count"),
+- print "%-40s %10s\n" % ("----------------------------------------", \
+- "-----------"),
++ keys = unhandled.keys()
++ if not keys:
++ return
++
++ print "\nunhandled events:\n\n",
++
++ print "%-40s %10s\n" % ("event", "count"),
++ print "%-40s %10s\n" % ("----------------------------------------", \
++ "-----------"),
+
+- for event_name in keys:
+- print "%-40s %10d\n" % (event_name, unhandled[event_name])
++ for event_name in keys:
++ print "%-40s %10d\n" % (event_name, unhandled[event_name])
+--- a/tools/perf/scripts/python/compaction-times.py
++++ b/tools/perf/scripts/python/compaction-times.py
+@@ -216,15 +216,15 @@ def compaction__mm_compaction_migratepag
+ pair(nr_migrated, nr_failed), None, None)
+
+ def compaction__mm_compaction_isolate_freepages(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken):
++ common_secs, common_nsecs, common_pid, common_comm,
++ common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken):
+
+ chead.increment_pending(common_pid,
+ None, pair(nr_scanned, nr_taken), None)
+
+ def compaction__mm_compaction_isolate_migratepages(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken):
++ common_secs, common_nsecs, common_pid, common_comm,
++ common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken):
+
+ chead.increment_pending(common_pid,
+ None, None, pair(nr_scanned, nr_taken))
+--- a/tools/perf/scripts/python/event_analyzing_sample.py
++++ b/tools/perf/scripts/python/event_analyzing_sample.py
+@@ -37,7 +37,7 @@ con = sqlite3.connect("/dev/shm/perf.db"
+ con.isolation_level = None
+
+ def trace_begin():
+- print "In trace_begin:\n"
++ print "In trace_begin:\n"
+
+ #
+ # Will create several tables at the start, pebs_ll is for PEBS data with
+@@ -102,7 +102,7 @@ def insert_db(event):
+ event.ip, event.status, event.dse, event.dla, event.lat))
+
+ def trace_end():
+- print "In trace_end:\n"
++ print "In trace_end:\n"
+ # We show the basic info for the 2 type of event classes
+ show_general_events()
+ show_pebs_ll()
+@@ -187,4 +187,4 @@ def show_pebs_ll():
+ print "%32s %8d %s" % (row[0], row[1], num2sym(row[1]))
+
+ def trace_unhandled(event_name, context, event_fields_dict):
+- print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
++ print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])
+--- a/tools/perf/scripts/python/failed-syscalls-by-pid.py
++++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py
+@@ -58,22 +58,22 @@ def syscalls__sys_exit(event_name, conte
+ raw_syscalls__sys_exit(**locals())
+
+ def print_error_totals():
+- if for_comm is not None:
+- print("\nsyscall errors for %s:\n" % (for_comm))
+- else:
+- print("\nsyscall errors:\n")
++ if for_comm is not None:
++ print("\nsyscall errors for %s:\n" % (for_comm))
++ else:
++ print("\nsyscall errors:\n")
+
+- print("%-30s %10s" % ("comm [pid]", "count"))
+- print("%-30s %10s" % ("------------------------------", "----------"))
++ print("%-30s %10s" % ("comm [pid]", "count"))
++ print("%-30s %10s" % ("------------------------------", "----------"))
+
+- comm_keys = syscalls.keys()
+- for comm in comm_keys:
+- pid_keys = syscalls[comm].keys()
+- for pid in pid_keys:
+- print("\n%s [%d]" % (comm, pid))
+- id_keys = syscalls[comm][pid].keys()
+- for id in id_keys:
+- print(" syscall: %-16s" % syscall_name(id))
+- ret_keys = syscalls[comm][pid][id].keys()
+- for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True):
+- print(" err = %-20s %10d" % (strerror(ret), val))
++ comm_keys = syscalls.keys()
++ for comm in comm_keys:
++ pid_keys = syscalls[comm].keys()
++ for pid in pid_keys:
++ print("\n%s [%d]" % (comm, pid))
++ id_keys = syscalls[comm][pid].keys()
++ for id in id_keys:
++ print(" syscall: %-16s" % syscall_name(id))
++ ret_keys = syscalls[comm][pid][id].keys()
++ for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True):
++ print(" err = %-20s %10d" % (strerror(ret), val))
+--- a/tools/perf/scripts/python/futex-contention.py
++++ b/tools/perf/scripts/python/futex-contention.py
+@@ -46,5 +46,5 @@ def trace_end():
+ for (tid, lock) in lock_waits:
+ min, max, avg, count = lock_waits[tid, lock]
+ print "%s[%d] lock %x contended %d times, %d avg ns" % \
+- (process_names[tid], tid, lock, count, avg)
++ (process_names[tid], tid, lock, count, avg)
+
+--- a/tools/perf/scripts/python/intel-pt-events.py
++++ b/tools/perf/scripts/python/intel-pt-events.py
+@@ -85,22 +85,22 @@ def print_common_ip(sample, symbol, dso)
+ print "%16x %s (%s)" % (ip, symbol, dso)
+
+ def process_event(param_dict):
+- event_attr = param_dict["attr"]
+- sample = param_dict["sample"]
+- raw_buf = param_dict["raw_buf"]
+- comm = param_dict["comm"]
+- name = param_dict["ev_name"]
++ event_attr = param_dict["attr"]
++ sample = param_dict["sample"]
++ raw_buf = param_dict["raw_buf"]
++ comm = param_dict["comm"]
++ name = param_dict["ev_name"]
+
+- # Symbol and dso info are not always resolved
+- if (param_dict.has_key("dso")):
+- dso = param_dict["dso"]
+- else:
+- dso = "[unknown]"
++ # Symbol and dso info are not always resolved
++ if (param_dict.has_key("dso")):
++ dso = param_dict["dso"]
++ else:
++ dso = "[unknown]"
+
+- if (param_dict.has_key("symbol")):
+- symbol = param_dict["symbol"]
+- else:
+- symbol = "[unknown]"
++ if (param_dict.has_key("symbol")):
++ symbol = param_dict["symbol"]
++ else:
++ symbol = "[unknown]"
+
+ if name == "ptwrite":
+ print_common_start(comm, sample, name)
+--- a/tools/perf/scripts/python/mem-phys-addr.py
++++ b/tools/perf/scripts/python/mem-phys-addr.py
+@@ -44,12 +44,13 @@ def print_memory_type():
+ print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='')
+ print("%-40s %10s %10s\n" % ("----------------------------------------",
+ "-----------", "-----------"),
+- end='');
++ end='');
+ total = sum(load_mem_type_cnt.values())
+ for mem_type, count in sorted(load_mem_type_cnt.most_common(), \
+ key = lambda kv: (kv[1], kv[0]), reverse = True):
+- print("%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total),
+- end='')
++ print("%-40s %10d %10.1f%%\n" %
++ (mem_type, count, 100 * count / total),
++ end='')
+
+ def trace_begin():
+ parse_iomem()
+--- a/tools/perf/scripts/python/net_dropmonitor.py
++++ b/tools/perf/scripts/python/net_dropmonitor.py
+@@ -7,7 +7,7 @@ import os
+ import sys
+
+ sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+- '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
++ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+
+ from perf_trace_context import *
+ from Core import *
+--- a/tools/perf/scripts/python/netdev-times.py
++++ b/tools/perf/scripts/python/netdev-times.py
+@@ -124,14 +124,16 @@ def print_receive(hunk):
+ event = event_list[i]
+ if event['event_name'] == 'napi_poll':
+ print(PF_NAPI_POLL %
+- (diff_msec(base_t, event['event_t']), event['dev']))
++ (diff_msec(base_t, event['event_t']),
++ event['dev']))
+ if i == len(event_list) - 1:
+ print("")
+ else:
+ print(PF_JOINT)
+ else:
+ print(PF_NET_RECV %
+- (diff_msec(base_t, event['event_t']), event['skbaddr'],
++ (diff_msec(base_t, event['event_t']),
++ event['skbaddr'],
+ event['len']))
+ if 'comm' in event.keys():
+ print(PF_WJOINT)
+@@ -256,7 +258,7 @@ def irq__irq_handler_exit(name, context,
+ all_event_list.append(event_info)
+
+ def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi,
+- dev_name, work=None, budget=None):
++ dev_name, work=None, budget=None):
+ event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm,
+ napi, dev_name, work, budget)
+ all_event_list.append(event_info)
+@@ -353,7 +355,7 @@ def handle_irq_softirq_exit(event_info):
+ if irq_list == [] or event_list == 0:
+ return
+ rec_data = {'sirq_ent_t':sirq_ent_t, 'sirq_ext_t':time,
+- 'irq_list':irq_list, 'event_list':event_list}
++ 'irq_list':irq_list, 'event_list':event_list}
+ # merge information realted to a NET_RX softirq
+ receive_hunk_list.append(rec_data)
+
+@@ -390,7 +392,7 @@ def handle_netif_receive_skb(event_info)
+ skbaddr, skblen, dev_name) = event_info
+ if cpu in net_rx_dic.keys():
+ rec_data = {'event_name':'netif_receive_skb',
+- 'event_t':time, 'skbaddr':skbaddr, 'len':skblen}
++ 'event_t':time, 'skbaddr':skbaddr, 'len':skblen}
+ event_list = net_rx_dic[cpu]['event_list']
+ event_list.append(rec_data)
+ rx_skb_list.insert(0, rec_data)
+--- a/tools/perf/scripts/python/sched-migration.py
++++ b/tools/perf/scripts/python/sched-migration.py
+@@ -16,10 +16,10 @@ import sys
+
+ from collections import defaultdict
+ try:
+- from UserList import UserList
++ from UserList import UserList
+ except ImportError:
+- # Python 3: UserList moved to the collections package
+- from collections import UserList
++ # Python 3: UserList moved to the collections package
++ from collections import UserList
+
+ sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+--- a/tools/perf/scripts/python/sctop.py
++++ b/tools/perf/scripts/python/sctop.py
+@@ -13,9 +13,9 @@ from __future__ import print_function
+ import os, sys, time
+
+ try:
+- import thread
++ import thread
+ except ImportError:
+- import _thread as thread
++ import _thread as thread
+
+ sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+@@ -75,11 +75,12 @@ def print_syscall_totals(interval):
+
+ print("%-40s %10s" % ("event", "count"))
+ print("%-40s %10s" %
+- ("----------------------------------------",
+- "----------"))
++ ("----------------------------------------",
++ "----------"))
+
+- for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \
+- reverse = True):
++ for id, val in sorted(syscalls.items(),
++ key = lambda kv: (kv[1], kv[0]),
++ reverse = True):
+ try:
+ print("%-40s %10d" % (syscall_name(id), val))
+ except TypeError:
+--- a/tools/perf/scripts/python/stackcollapse.py
++++ b/tools/perf/scripts/python/stackcollapse.py
+@@ -27,7 +27,7 @@ from collections import defaultdict
+ from optparse import OptionParser, make_option
+
+ sys.path.append(os.environ['PERF_EXEC_PATH'] + \
+- '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
++ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+
+ from perf_trace_context import *
+ from Core import *
+--- a/tools/perf/scripts/python/syscall-counts-by-pid.py
++++ b/tools/perf/scripts/python/syscall-counts-by-pid.py
+@@ -39,11 +39,10 @@ def trace_end():
+ print_syscall_totals()
+
+ def raw_syscalls__sys_enter(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- common_callchain, id, args):
+-
++ common_secs, common_nsecs, common_pid, common_comm,
++ common_callchain, id, args):
+ if (for_comm and common_comm != for_comm) or \
+- (for_pid and common_pid != for_pid ):
++ (for_pid and common_pid != for_pid ):
+ return
+ try:
+ syscalls[common_comm][common_pid][id] += 1
+@@ -51,26 +50,26 @@ def raw_syscalls__sys_enter(event_name,
+ syscalls[common_comm][common_pid][id] = 1
+
+ def syscalls__sys_enter(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- id, args):
++ common_secs, common_nsecs, common_pid, common_comm,
++ id, args):
+ raw_syscalls__sys_enter(**locals())
+
+ def print_syscall_totals():
+- if for_comm is not None:
+- print("\nsyscall events for %s:\n" % (for_comm))
+- else:
+- print("\nsyscall events by comm/pid:\n")
+-
+- print("%-40s %10s" % ("comm [pid]/syscalls", "count"))
+- print("%-40s %10s" % ("----------------------------------------",
+- "----------"))
+-
+- comm_keys = syscalls.keys()
+- for comm in comm_keys:
+- pid_keys = syscalls[comm].keys()
+- for pid in pid_keys:
+- print("\n%s [%d]" % (comm, pid))
+- id_keys = syscalls[comm][pid].keys()
+- for id, val in sorted(syscalls[comm][pid].items(), \
+- key = lambda kv: (kv[1], kv[0]), reverse = True):
+- print(" %-38s %10d" % (syscall_name(id), val))
++ if for_comm is not None:
++ print("\nsyscall events for %s:\n" % (for_comm))
++ else:
++ print("\nsyscall events by comm/pid:\n")
++
++ print("%-40s %10s" % ("comm [pid]/syscalls", "count"))
++ print("%-40s %10s" % ("----------------------------------------",
++ "----------"))
++
++ comm_keys = syscalls.keys()
++ for comm in comm_keys:
++ pid_keys = syscalls[comm].keys()
++ for pid in pid_keys:
++ print("\n%s [%d]" % (comm, pid))
++ id_keys = syscalls[comm][pid].keys()
++ for id, val in sorted(syscalls[comm][pid].items(),
++ key = lambda kv: (kv[1], kv[0]), reverse = True):
++ print(" %-38s %10d" % (syscall_name(id), val))
+--- a/tools/perf/scripts/python/syscall-counts.py
++++ b/tools/perf/scripts/python/syscall-counts.py
+@@ -36,8 +36,8 @@ def trace_end():
+ print_syscall_totals()
+
+ def raw_syscalls__sys_enter(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- common_callchain, id, args):
++ common_secs, common_nsecs, common_pid, common_comm,
++ common_callchain, id, args):
+ if for_comm is not None:
+ if common_comm != for_comm:
+ return
+@@ -47,20 +47,19 @@ def raw_syscalls__sys_enter(event_name,
+ syscalls[id] = 1
+
+ def syscalls__sys_enter(event_name, context, common_cpu,
+- common_secs, common_nsecs, common_pid, common_comm,
+- id, args):
++ common_secs, common_nsecs, common_pid, common_comm, id, args):
+ raw_syscalls__sys_enter(**locals())
+
+ def print_syscall_totals():
+- if for_comm is not None:
+- print("\nsyscall events for %s:\n" % (for_comm))
+- else:
+- print("\nsyscall events:\n")
++ if for_comm is not None:
++ print("\nsyscall events for %s:\n" % (for_comm))
++ else:
++ print("\nsyscall events:\n")
+
+- print("%-40s %10s" % ("event", "count"))
+- print("%-40s %10s" % ("----------------------------------------",
+- "-----------"))
++ print("%-40s %10s" % ("event", "count"))
++ print("%-40s %10s" % ("----------------------------------------",
++ "-----------"))
+
+- for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \
+- reverse = True):
+- print("%-40s %10d" % (syscall_name(id), val))
++ for id, val in sorted(syscalls.items(),
++ key = lambda kv: (kv[1], kv[0]), reverse = True):
++ print("%-40s %10d" % (syscall_name(id), val))
diff --git a/debian/patches/bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch b/debian/patches/bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch
new file mode 100644
index 000000000..90c7aa835
--- /dev/null
+++ b/debian/patches/bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch
@@ -0,0 +1,104 @@
+From: Tony Jones <tonyj@suse.de>
+Date: Fri, 1 Mar 2019 17:18:59 -0800
+Subject: perf script python: add Python3 support to check-perf-trace.py
+Origin: https://git.kernel.org/linus/57e604b16362273af6a517abaa6cd1133a7fc732
+Bug-Debian: https://bugs.debian.org/944641
+
+Support both Python 2 and Python 3 in the check-perf-trace.py script.
+
+There may be differences in the ordering of output lines due to
+differences in dictionary ordering etc. However the format within lines
+should be unchanged.
+
+The use of from __future__ implies the minimum supported version of
+Python2 is now v2.6
+
+Signed-off-by: Tony Jones <tonyj@suse.de>
+Cc: Tom Zanussi <tzanussi@gmail.com>
+Link: http://lkml.kernel.org/r/20190302011903.2416-4-tonyj@suse.de
+Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com>
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/scripts/python/check-perf-trace.py | 31 ++++++++++++++------------
+ 1 file changed, 17 insertions(+), 14 deletions(-)
+
+--- a/tools/perf/scripts/python/check-perf-trace.py
++++ b/tools/perf/scripts/python/check-perf-trace.py
+@@ -7,6 +7,8 @@
+ # events, etc. Basically, if this script runs successfully and
+ # displays expected results, Python scripting support should be ok.
+
++from __future__ import print_function
++
+ import os
+ import sys
+
+@@ -19,7 +21,7 @@ from perf_trace_context import *
+ unhandled = autodict()
+
+ def trace_begin():
+- print "trace_begin"
++ print("trace_begin")
+ pass
+
+ def trace_end():
+@@ -33,7 +35,7 @@ def irq__softirq_entry(event_name, conte
+
+ print_uncommon(context)
+
+- print "vec=%s\n" % (symbol_str("irq__softirq_entry", "vec", vec)),
++ print("vec=%s" % (symbol_str("irq__softirq_entry", "vec", vec)))
+
+ def kmem__kmalloc(event_name, context, common_cpu,
+ common_secs, common_nsecs, common_pid, common_comm,
+@@ -44,10 +46,10 @@ def kmem__kmalloc(event_name, context, c
+
+ print_uncommon(context)
+
+- print "call_site=%u, ptr=%u, bytes_req=%u, " \
+- "bytes_alloc=%u, gfp_flags=%s\n" % \
++ print("call_site=%u, ptr=%u, bytes_req=%u, "
++ "bytes_alloc=%u, gfp_flags=%s" %
+ (call_site, ptr, bytes_req, bytes_alloc,
+- flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)),
++ flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)))
+
+ def trace_unhandled(event_name, context, event_fields_dict):
+ try:
+@@ -56,26 +58,27 @@ def trace_unhandled(event_name, context,
+ unhandled[event_name] = 1
+
+ def print_header(event_name, cpu, secs, nsecs, pid, comm):
+- print "%-20s %5u %05u.%09u %8u %-20s " % \
++ print("%-20s %5u %05u.%09u %8u %-20s " %
+ (event_name, cpu, secs, nsecs, pid, comm),
++ end=' ')
+
+ # print trace fields not included in handler args
+ def print_uncommon(context):
+- print "common_preempt_count=%d, common_flags=%s, " \
+- "common_lock_depth=%d, " % \
++ print("common_preempt_count=%d, common_flags=%s, "
++ "common_lock_depth=%d, " %
+ (common_pc(context), trace_flag_str(common_flags(context)),
+- common_lock_depth(context))
++ common_lock_depth(context)))
+
+ def print_unhandled():
+ keys = unhandled.keys()
+ if not keys:
+ return
+
+- print "\nunhandled events:\n\n",
++ print("\nunhandled events:\n")
+
+- print "%-40s %10s\n" % ("event", "count"),
+- print "%-40s %10s\n" % ("----------------------------------------", \
+- "-----------"),
++ print("%-40s %10s" % ("event", "count"))
++ print("%-40s %10s" % ("----------------------------------------",
++ "-----------"))
+
+ for event_name in keys:
+- print "%-40s %10d\n" % (event_name, unhandled[event_name])
++ print("%-40s %10d\n" % (event_name, unhandled[event_name]))
diff --git a/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch
new file mode 100644
index 000000000..cd2ba2e9e
--- /dev/null
+++ b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch
@@ -0,0 +1,135 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: radeon, amdgpu: Firmware is required for DRM and KMS on R600 onward
+Date: Tue, 08 Jan 2013 03:25:52 +0000
+Bug-Debian: https://bugs.debian.org/607194
+Bug-Debian: https://bugs.debian.org/607471
+Bug-Debian: https://bugs.debian.org/610851
+Bug-Debian: https://bugs.debian.org/627497
+Bug-Debian: https://bugs.debian.org/632212
+Bug-Debian: https://bugs.debian.org/637943
+Bug-Debian: https://bugs.debian.org/649448
+Bug-Debian: https://bugs.debian.org/697229
+Forwarded: no
+
+radeon requires firmware/microcode for the GPU in all chips, but for
+newer chips (apparently R600 'Evergreen' onward) it also expects
+firmware for the memory controller and other sub-blocks.
+
+radeon attempts to gracefully fall back and disable some features if
+the firmware is not available, but becomes unstable - the framebuffer
+and/or system memory may be corrupted, or the display may stay black.
+
+Therefore, perform a basic check for the existence of
+/lib/firmware/{radeon,amdgpu} when a device is probed, and abort if it
+is missing, except for the pre-R600 case.
+
+---
+Index: linux/drivers/gpu/drm/radeon/radeon_drv.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/radeon/radeon_drv.c
++++ linux/drivers/gpu/drm/radeon/radeon_drv.c
+@@ -43,6 +43,8 @@
+ #include <drm/drm_fb_helper.h>
+
+ #include <drm/drm_crtc_helper.h>
++#include <linux/namei.h>
++#include <linux/path.h>
+
+ /*
+ * KMS wrapper.
+@@ -316,6 +318,28 @@ static struct drm_driver kms_driver;
+
+ bool radeon_device_is_virtual(void);
+
++/* Test that /lib/firmware/radeon is a directory (or symlink to a
++ * directory). We could try to match the udev search path, but let's
++ * keep it simple.
++ */
++static bool radeon_firmware_installed(void)
++{
++#if IS_BUILTIN(CONFIG_DRM_RADEON)
++ /* It may be too early to tell. Assume it's there. */
++ return true;
++#else
++ struct path path;
++
++ if (kern_path("/lib/firmware/radeon", LOOKUP_DIRECTORY | LOOKUP_FOLLOW,
++ &path) == 0) {
++ path_put(&path);
++ return true;
++ }
++
++ return false;
++#endif
++}
++
+ static int radeon_kick_out_firmware_fb(struct pci_dev *pdev)
+ {
+ struct apertures_struct *ap;
+@@ -376,6 +400,12 @@ static int radeon_pci_probe(struct pci_d
+ if (vga_switcheroo_client_probe_defer(pdev))
+ return -EPROBE_DEFER;
+
++ if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 &&
++ !radeon_firmware_installed()) {
++ DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware installed\n");
++ return -ENODEV;
++ }
++
+ /* Get rid of things like offb */
+ ret = radeon_kick_out_firmware_fb(pdev);
+ if (ret)
+Index: linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -33,6 +33,8 @@
+ #include <linux/pm_runtime.h>
+ #include <linux/vga_switcheroo.h>
+ #include <drm/drm_crtc_helper.h>
++#include <linux/namei.h>
++#include <linux/path.h>
+
+ #include "amdgpu.h"
+ #include "amdgpu_irq.h"
+@@ -793,6 +795,28 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
+
+ static struct drm_driver kms_driver;
+
++/* Test that /lib/firmware/amdgpu is a directory (or symlink to a
++ * directory). We could try to match the udev search path, but let's
++ * keep it simple.
++ */
++static bool amdgpu_firmware_installed(void)
++{
++#if IS_BUILTIN(CONFIG_DRM_AMDGPU)
++ /* It may be too early to tell. Assume it's there. */
++ return true;
++#else
++ struct path path;
++
++ if (kern_path("/lib/firmware/amdgpu", LOOKUP_DIRECTORY | LOOKUP_FOLLOW,
++ &path) == 0) {
++ path_put(&path);
++ return true;
++ }
++
++ return false;
++#endif
++}
++
+ static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev)
+ {
+ struct apertures_struct *ap;
+@@ -833,6 +857,11 @@ static int amdgpu_pci_probe(struct pci_d
+ return -ENODEV;
+ }
+
++ if (!amdgpu_firmware_installed()) {
++ DRM_ERROR("amdgpu requires firmware installed\n");
++ return -ENODEV;
++ }
++
+ /*
+ * Initialize amdkfd before starting radeon. If it was not loaded yet,
+ * defer radeon probing
diff --git a/debian/patches/bugfix/all/rtc-s35390a-set-uie_unsupported.patch b/debian/patches/bugfix/all/rtc-s35390a-set-uie_unsupported.patch
new file mode 100644
index 000000000..b3261d952
--- /dev/null
+++ b/debian/patches/bugfix/all/rtc-s35390a-set-uie_unsupported.patch
@@ -0,0 +1,40 @@
+From: Richard Leitner <richard.leitner@skidata.com>
+Date: Thu, 23 May 2019 13:54:49 +0200
+Subject: [PATCH] rtc: s35390a: set uie_unsupported
+Origin: https://git.kernel.org/linus/c0e12848be091e8410fb427f080f2e0149123443
+Bug-Debian: https://bugs.debian.org/932845
+
+Alarms are only supported on a per minute basis. This is why
+uie_unsupported is set. Furthermore issue a warning when a second based
+alarm is requested.
+
+Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+---
+ drivers/rtc/rtc-s35390a.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+Index: linux/drivers/rtc/rtc-s35390a.c
+===================================================================
+--- linux.orig/drivers/rtc/rtc-s35390a.c
++++ linux/drivers/rtc/rtc-s35390a.c
+@@ -288,6 +288,9 @@ static int s35390a_rtc_set_alarm(struct
+ alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
+ alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);
+
++ if (alm->time.tm_sec != 0)
++ dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n");
++
+ /* disable interrupt (which deasserts the irq line) */
+ err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
+ if (err < 0)
+@@ -502,6 +505,9 @@ static int s35390a_probe(struct i2c_clie
+ goto exit_dummy;
+ }
+
++ /* supports per-minute alarms only, therefore set uie_unsupported */
++ s35390a->rtc->uie_unsupported = 1;
++
+ if (status1 & S35390A_FLAG_INT2)
+ rtc_update_irq(s35390a->rtc, 1, RTC_AF);
+
diff --git a/debian/patches/bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch b/debian/patches/bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch
new file mode 100644
index 000000000..df77ca0b2
--- /dev/null
+++ b/debian/patches/bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch
@@ -0,0 +1,47 @@
+From: Liu Shixin <liushixin2@huawei.com>
+Date: Thu, 30 Jun 2022 19:33:31 +0800
+Subject: swiotlb: skip swiotlb_bounce when orig_addr is zero
+Origin: https://lore.kernel.org/stable/20220630113331.1544886-1-liushixin2@huawei.com/
+
+After patch ddbd89deb7d3 ("swiotlb: fix info leak with DMA_FROM_DEVICE"),
+swiotlb_bounce will be called in swiotlb_tbl_map_single unconditionally.
+This requires that the physical address must be valid, which is not always
+true on stable-4.19 or earlier version.
+On stable-4.19, swiotlb_alloc_buffer will call swiotlb_tbl_map_single with
+orig_addr equal to zero, which cause such a panic:
+
+Unable to handle kernel paging request at virtual address ffffb77a40000000
+...
+pc : __memcpy+0x100/0x180
+lr : swiotlb_bounce+0x74/0x88
+...
+Call trace:
+ __memcpy+0x100/0x180
+ swiotlb_tbl_map_single+0x2c8/0x338
+ swiotlb_alloc+0xb4/0x198
+ __dma_alloc+0x84/0x1d8
+ ...
+
+On stable-4.9 and stable-4.14, swiotlb_alloc_coherent wille call map_single
+with orig_addr equal to zero, which can cause same panic.
+
+Fix this by skipping swiotlb_bounce when orig_addr is zero.
+
+Fixes: ddbd89deb7d3 ("swiotlb: fix info leak with DMA_FROM_DEVICE")
+Signed-off-by: Liu Shixin <liushixin2@huawei.com>
+---
+ kernel/dma/swiotlb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kernel/dma/swiotlb.c
++++ b/kernel/dma/swiotlb.c
+@@ -594,7 +594,8 @@ found:
+ * unconditional bounce may prevent leaking swiotlb content (i.e.
+ * kernel memory) to user-space.
+ */
+- swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE);
++ if (orig_addr)
++ swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE);
+ return tlb_addr;
+ }
+
diff --git a/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch b/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch
new file mode 100644
index 000000000..39044c390
--- /dev/null
+++ b/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch
@@ -0,0 +1,29 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 21 Feb 2016 15:33:15 +0000
+Subject: tools/build: Remove bpf() run-time check at build time
+Forwarded: no
+
+It is not correct to test that a syscall works on the build system's
+kernel. We might be building on an earlier kernel version or with
+security restrictions that block bpf().
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/tools/build/feature/test-bpf.c
+===================================================================
+--- linux.orig/tools/build/feature/test-bpf.c
++++ linux/tools/build/feature/test-bpf.c
+@@ -35,8 +35,10 @@ int main(void)
+ attr.prog_flags = 0;
+
+ /*
+- * Test existence of __NR_bpf and BPF_PROG_LOAD.
+- * This call should fail if we run the testcase.
++ * bwh: Don't use the bpf() syscall as we might be building on a
++ * much older kernel. Do "use" the attr structure here to avoid
++ * a "set but not used" warning.
+ */
+- return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
++ (void)&attr;
++ return 0;
+ }
diff --git a/debian/patches/bugfix/all/tools-lib-traceevent-use-ldflags.patch b/debian/patches/bugfix/all/tools-lib-traceevent-use-ldflags.patch
new file mode 100644
index 000000000..ae303f360
--- /dev/null
+++ b/debian/patches/bugfix/all/tools-lib-traceevent-use-ldflags.patch
@@ -0,0 +1,29 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 25 Sep 2015 21:26:48 +0100
+Subject: tools/lib/traceevent: Use LDFLAGS
+Forwarded: no
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/tools/lib/traceevent/Makefile
+===================================================================
+--- linux.orig/tools/lib/traceevent/Makefile
++++ linux/tools/lib/traceevent/Makefile
+@@ -174,7 +174,7 @@ $(TE_IN): force
+ $(Q)$(MAKE) $(build)=libtraceevent
+
+ $(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN)
+- $(QUIET_LINK)$(CC) --shared $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@
++ $(QUIET_LINK)$(CC) $(LDFLAGS) --shared $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@
+ @ln -sf $(@F) $(OUTPUT)libtraceevent.so
+ @ln -sf $(@F) $(OUTPUT)libtraceevent.so.$(EP_VERSION)
+
+@@ -193,7 +193,7 @@ $(PLUGINS_IN): force
+ $(Q)$(MAKE) $(build)=$(plugin_obj)
+
+ $(OUTPUT)%.so: $(OUTPUT)%-in.o
+- $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $^
++ $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -shared -nostartfiles -o $@ $^
+
+ define make_version.h
+ (echo '/* This file is automatically generated. Do not modify. */'; \
diff --git a/debian/patches/bugfix/all/tools-perf-man-date.patch b/debian/patches/bugfix/all/tools-perf-man-date.patch
new file mode 100644
index 000000000..4515c703c
--- /dev/null
+++ b/debian/patches/bugfix/all/tools-perf-man-date.patch
@@ -0,0 +1,37 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 13 Jul 2015 20:29:20 +0100
+Subject: perf tools: Use $KBUILD_BUILD_TIMESTAMP as man page date
+Forwarded: http://mid.gmane.org/20160517132809.GE7555@decadent.org.uk
+
+This allows man pages to be built reproducibly.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/tools/perf/Documentation/Makefile
+===================================================================
+--- linux.orig/tools/perf/Documentation/Makefile
++++ linux/tools/perf/Documentation/Makefile
+@@ -131,6 +131,9 @@ endif
+ ifdef DOCBOOK_SUPPRESS_SP
+ XMLTO_EXTRA += -m manpage-suppress-sp.xsl
+ endif
++ifdef KBUILD_BUILD_TIMESTAMP
++ASCIIDOC_EXTRA += -a revdate=$(shell date -u -d '$(KBUILD_BUILD_TIMESTAMP)' +%Y-%m-%d)
++endif
+
+ SHELL_PATH ?= $(SHELL)
+ # Shell quote;
+Index: linux/tools/perf/Documentation/asciidoc.conf
+===================================================================
+--- linux.orig/tools/perf/Documentation/asciidoc.conf
++++ linux/tools/perf/Documentation/asciidoc.conf
+@@ -71,6 +71,9 @@ ifdef::backend-docbook[]
+ [header]
+ template::[header-declarations]
+ <refentry>
++<refentryinfo>
++template::[docinfo]
++</refentryinfo>
+ <refmeta>
+ <refentrytitle>{mantitle}</refentrytitle>
+ <manvolnum>{manvolnum}</manvolnum>
diff --git a/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch b/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch
new file mode 100644
index 000000000..d01140709
--- /dev/null
+++ b/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch
@@ -0,0 +1,47 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 25 Sep 2015 20:09:23 +0100
+Subject: tools/perf: Remove shebang lines from perf scripts
+Forwarded: no
+
+perf scripts need to be invoked through perf, not directly through
+perl (or other language interpreter). So including shebang lines in
+them is useless and possibly misleading.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/tools/perf/scripts/perl/rw-by-file.pl
+===================================================================
+--- linux.orig/tools/perf/scripts/perl/rw-by-file.pl
++++ linux/tools/perf/scripts/perl/rw-by-file.pl
+@@ -1,4 +1,3 @@
+-#!/usr/bin/perl -w
+ # (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+ # Licensed under the terms of the GNU GPL License version 2
+
+Index: linux/tools/perf/scripts/perl/rw-by-pid.pl
+===================================================================
+--- linux.orig/tools/perf/scripts/perl/rw-by-pid.pl
++++ linux/tools/perf/scripts/perl/rw-by-pid.pl
+@@ -1,4 +1,3 @@
+-#!/usr/bin/perl -w
+ # (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+ # Licensed under the terms of the GNU GPL License version 2
+
+Index: linux/tools/perf/scripts/perl/rwtop.pl
+===================================================================
+--- linux.orig/tools/perf/scripts/perl/rwtop.pl
++++ linux/tools/perf/scripts/perl/rwtop.pl
+@@ -1,4 +1,3 @@
+-#!/usr/bin/perl -w
+ # (c) 2010, Tom Zanussi <tzanussi@gmail.com>
+ # Licensed under the terms of the GNU GPL License version 2
+
+Index: linux/tools/perf/scripts/perl/wakeup-latency.pl
+===================================================================
+--- linux.orig/tools/perf/scripts/perl/wakeup-latency.pl
++++ linux/tools/perf/scripts/perl/wakeup-latency.pl
+@@ -1,4 +1,3 @@
+-#!/usr/bin/perl -w
+ # (c) 2009, Tom Zanussi <tzanussi@gmail.com>
+ # Licensed under the terms of the GNU GPL License version 2
+
diff --git a/debian/patches/bugfix/all/usb-add-a-hcd_uses_dma-helper.patch b/debian/patches/bugfix/all/usb-add-a-hcd_uses_dma-helper.patch
new file mode 100644
index 000000000..341018e58
--- /dev/null
+++ b/debian/patches/bugfix/all/usb-add-a-hcd_uses_dma-helper.patch
@@ -0,0 +1,110 @@
+From: Christoph Hellwig <hch@lst.de>
+Date: Sun, 11 Aug 2019 10:05:16 +0200
+Subject: usb: add a hcd_uses_dma helper
+Origin: https://git.kernel.org/linus/edfbcb321faf07ca970e4191abe061deeb7d3788
+
+The USB buffer allocation code is the only place in the usb core (and in
+fact the whole kernel) that uses is_device_dma_capable, while the URB
+mapping code uses the uses_dma flag in struct usb_bus. Switch the buffer
+allocation to use the uses_dma flag used by the rest of the USB code,
+and create a helper in hcd.h that checks this flag as well as the
+CONFIG_HAS_DMA to simplify the caller a bit.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20190811080520.21712-3-hch@lst.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/buffer.c | 10 +++-------
+ drivers/usb/core/hcd.c | 4 ++--
+ drivers/usb/dwc2/hcd.c | 2 +-
+ include/linux/usb.h | 2 +-
+ include/linux/usb/hcd.h | 3 +++
+ 5 files changed, 10 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/core/buffer.c
++++ b/drivers/usb/core/buffer.c
+@@ -66,9 +66,7 @@
+ char name[16];
+ int i, size;
+
+- if (hcd->localmem_pool ||
+- !IS_ENABLED(CONFIG_HAS_DMA) ||
+- !is_device_dma_capable(hcd->self.sysdev))
++ if (hcd->localmem_pool || !hcd_uses_dma(hcd))
+ return 0;
+
+ for (i = 0; i < HCD_BUFFER_POOLS; i++) {
+@@ -133,8 +131,7 @@
+ return gen_pool_dma_alloc(hcd->localmem_pool, size, dma);
+
+ /* some USB hosts just use PIO */
+- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+- !is_device_dma_capable(bus->sysdev)) {
++ if (!hcd_uses_dma(hcd)) {
+ *dma = ~(dma_addr_t) 0;
+ return kmalloc(size, mem_flags);
+ }
+@@ -164,8 +161,7 @@
+ return;
+ }
+
+- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+- !is_device_dma_capable(bus->sysdev)) {
++ if (!hcd_uses_dma(hcd)) {
+ kfree(addr);
+ return;
+ }
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1511,7 +1511,7 @@
+ if (usb_endpoint_xfer_control(&urb->ep->desc)) {
+ if (hcd->self.uses_pio_for_control)
+ return ret;
+- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
++ if (hcd_uses_dma(hcd)) {
+ if (is_vmalloc_addr(urb->setup_packet)) {
+ WARN_ONCE(1, "setup packet is not dma capable\n");
+ return -EAGAIN;
+@@ -1545,7 +1545,7 @@
+ dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ if (urb->transfer_buffer_length != 0
+ && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) {
++ if (hcd_uses_dma(hcd)) {
+ if (urb->num_sgs) {
+ int n;
+
+--- a/drivers/usb/dwc2/hcd.c
++++ b/drivers/usb/dwc2/hcd.c
+@@ -4770,7 +4770,7 @@
+
+ buf = urb->transfer_buffer;
+
+- if (hcd->self.uses_dma) {
++ if (hcd_uses_dma(hcd)) {
+ if (!buf && (urb->transfer_dma & 3)) {
+ dev_err(hsotg->dev,
+ "%s: unaligned transfer with no transfer_buffer",
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1455,7 +1455,7 @@
+ * field rather than determining a dma address themselves.
+ *
+ * Note that transfer_buffer must still be set if the controller
+- * does not support DMA (as indicated by bus.uses_dma) and when talking
++ * does not support DMA (as indicated by hcd_uses_dma()) and when talking
+ * to root hub. If you have to trasfer between highmem zone and the device
+ * on such controller, create a bounce buffer or bail out with an error.
+ * If transfer_buffer cannot be set (is in highmem) and the controller is DMA
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -422,6 +422,9 @@
+ return hcd->high_prio_bh.completing_ep == ep;
+ }
+
++#define hcd_uses_dma(hcd) \
++ (IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma)
++
+ extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb);
+ extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb,
+ int status);
diff --git a/debian/patches/bugfix/all/usb-dont-create-dma-pools-for-HCD.patch b/debian/patches/bugfix/all/usb-dont-create-dma-pools-for-HCD.patch
new file mode 100644
index 000000000..197a4fadb
--- /dev/null
+++ b/debian/patches/bugfix/all/usb-dont-create-dma-pools-for-HCD.patch
@@ -0,0 +1,31 @@
+From: Christoph Hellwig <hch@lst.de>
+Date: Sun, 11 Aug 2019 10:05:15 +0200
+Subject: usb: don't create dma pools for HCDs with a localmem_pool
+Origin: https://git.kernel.org/linus/dd3ecf17ba70a70d2c9ef9ba725281b84f8eef12
+
+If the HCD provides a localmem pool we will never use the DMA pools, so
+don't create them.
+
+Fixes: b0310c2f09bb ("USB: use genalloc for USB HCs with local memory")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Link: https://lore.kernel.org/r/20190811080520.21712-2-hch@lst.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/buffer.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/core/buffer.c
++++ b/drivers/usb/core/buffer.c
+@@ -66,9 +66,9 @@
+ char name[16];
+ int i, size;
+
+- if (!IS_ENABLED(CONFIG_HAS_DMA) ||
+- (!is_device_dma_capable(hcd->self.sysdev) &&
+- !hcd->localmem_pool))
++ if (hcd->localmem_pool ||
++ !IS_ENABLED(CONFIG_HAS_DMA) ||
++ !is_device_dma_capable(hcd->self.sysdev))
+ return 0;
+
+ for (i = 0; i < HCD_BUFFER_POOLS; i++) {
diff --git a/debian/patches/bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch b/debian/patches/bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch
new file mode 100644
index 000000000..920b0b780
--- /dev/null
+++ b/debian/patches/bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch
@@ -0,0 +1,35 @@
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Fri, 7 Jun 2019 16:57:09 +0300
+Subject: usb/hcd: Fix a NULL vs IS_ERR() bug in usb_hcd_setup_local_mem()
+Origin: https://git.kernel.org/linus/94b9a70d32db0d1e8eeaeb27d74a5ae712644da9
+
+The devm_memremap() function doesn't return NULL, it returns error
+pointers.
+
+Fixes: b0310c2f09bb ("USB: use genalloc for USB HCs with local memory")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lore.kernel.org/r/20190607135709.GC16718@mwanda
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hcd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 8b8ec0c7325d..a84b201dd844 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -3038,8 +3038,8 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr,
+
+ local_mem = devm_memremap(hcd->self.sysdev, phys_addr,
+ size, MEMREMAP_WC);
+- if (!local_mem)
+- return -ENOMEM;
++ if (IS_ERR(local_mem))
++ return PTR_ERR(local_mem);
+
+ /*
+ * Here we pass a dma_addr_t but the arg type is a phys_addr_t.
+--
+2.26.2
+
diff --git a/debian/patches/bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch b/debian/patches/bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch
new file mode 100644
index 000000000..39d46e009
--- /dev/null
+++ b/debian/patches/bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch
@@ -0,0 +1,105 @@
+From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Date: Wed, 29 May 2019 13:28:41 +0300
+Subject: usb: host: ohci-sm501: init genalloc for local memory
+Origin: https://git.kernel.org/linus/7d9e6f5aebe8c03f1a5199ca5c30f0c53042af23
+
+In preparation for dropping the existing "coherent" dma mem declaration
+APIs, replace the current dma_declare_coherent_memory() based mechanism
+with the creation of a genalloc pool that will be used in the OHCI
+subsystem as replacement for the DMA APIs.
+
+Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+---
+ drivers/usb/host/ohci-sm501.c | 47 +++++++++++++++--------------------
+ 1 file changed, 20 insertions(+), 27 deletions(-)
+
+--- a/drivers/usb/host/ohci-sm501.c
++++ b/drivers/usb/host/ohci-sm501.c
+@@ -110,41 +110,18 @@
+ goto err0;
+ }
+
+- /* The sm501 chip is equipped with local memory that may be used
+- * by on-chip devices such as the video controller and the usb host.
+- * This driver uses dma_declare_coherent_memory() to make sure
+- * usb allocations with dma_alloc_coherent() allocate from
+- * this local memory. The dma_handle returned by dma_alloc_coherent()
+- * will be an offset starting from 0 for the first local memory byte.
+- *
+- * So as long as data is allocated using dma_alloc_coherent() all is
+- * fine. This is however not always the case - buffers may be allocated
+- * using kmalloc() - so the usb core needs to be told that it must copy
+- * data into our local memory if the buffers happen to be placed in
+- * regular memory. The HCD_LOCAL_MEM flag does just that.
+- */
+-
+- retval = dma_declare_coherent_memory(dev, mem->start,
+- mem->start - mem->parent->start,
+- resource_size(mem),
+- DMA_MEMORY_EXCLUSIVE);
+- if (retval) {
+- dev_err(dev, "cannot declare coherent memory\n");
+- goto err1;
+- }
+-
+ /* allocate, reserve and remap resources for registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(dev, "no resource definition for registers\n");
+ retval = -ENOENT;
+- goto err2;
++ goto err1;
+ }
+
+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+ if (!hcd) {
+ retval = -ENOMEM;
+- goto err2;
++ goto err1;
+ }
+
+ hcd->rsrc_start = res->start;
+@@ -165,6 +142,24 @@
+
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
++ /* The sm501 chip is equipped with local memory that may be used
++ * by on-chip devices such as the video controller and the usb host.
++ * This driver uses genalloc so that usb allocations with
++ * gen_pool_dma_alloc() allocate from this local memory. The dma_handle
++ * returned by gen_pool_dma_alloc() will be an offset starting from 0
++ * for the first local memory byte.
++ *
++ * So as long as data is allocated using gen_pool_dma_alloc() all is
++ * fine. This is however not always the case - buffers may be allocated
++ * using kmalloc() - so the usb core needs to be told that it must copy
++ * data into our local memory if the buffers happen to be placed in
++ * regular memory. The HCD_LOCAL_MEM flag does just that.
++ */
++
++ if (usb_hcd_setup_local_mem(hcd, mem->start,
++ mem->start - mem->parent->start,
++ resource_size(mem)) < 0)
++ goto err5;
+ retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
+ if (retval)
+ goto err5;
+@@ -182,8 +177,6 @@
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ err3:
+ usb_put_hcd(hcd);
+-err2:
+- dma_release_declared_memory(dev);
+ err1:
+ release_mem_region(mem->start, resource_size(mem));
+ err0:
+@@ -199,7 +192,6 @@
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+- dma_release_declared_memory(&pdev->dev);
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (mem)
+ release_mem_region(mem->start, resource_size(mem));
diff --git a/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch b/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch
new file mode 100644
index 000000000..0943df590
--- /dev/null
+++ b/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 24 Jun 2012 02:51:39 +0100
+Subject: usbip: Document TCP wrappers
+Forwarded: no
+
+Add references to TCP wrappers configuration in the manual page.
+
+Index: linux/tools/usb/usbip/doc/usbipd.8
+===================================================================
+--- linux.orig/tools/usb/usbip/doc/usbipd.8
++++ linux/tools/usb/usbip/doc/usbipd.8
+@@ -14,7 +14,8 @@ Devices have to explicitly be exported u
+ before usbipd makes them available to other hosts.
+
+ The daemon accepts connections from USB/IP clients
+-on TCP port 3240 by default.
++on TCP port 3240 by default. The clients authorised to connect may be
++configured as documented in hosts_access(5).
+
+ .SH OPTIONS
+ .HP
+@@ -69,7 +70,8 @@ Show version.
+
+ .B usbipd
+ offers no authentication or authorization for USB/IP. Any
+-USB/IP client can connect and use exported devices.
++USB/IP client running on an authorised host can connect and
++use exported devices.
+
+ .SH EXAMPLES
+
diff --git a/debian/patches/bugfix/all/usbip-fix-misuse-of-strncpy.patch b/debian/patches/bugfix/all/usbip-fix-misuse-of-strncpy.patch
new file mode 100644
index 000000000..b98025b8a
--- /dev/null
+++ b/debian/patches/bugfix/all/usbip-fix-misuse-of-strncpy.patch
@@ -0,0 +1,61 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 20 Jul 2018 01:30:24 +0100
+Subject: usbip: Fix misuse of strncpy()
+Bug-Debian: https://bugs.debian.org/897802
+Forwarded: https://marc.info/?l=linux-usb&m=153213915806258
+
+gcc 8 reports:
+
+usbip_device_driver.c: In function ‘read_usb_vudc_device’:
+usbip_device_driver.c:106:2: error: ‘strncpy’ specified bound 256 equals destination size [-Werror=stringop-truncation]
+ strncpy(dev->path, path, SYSFS_PATH_MAX);
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+usbip_device_driver.c:125:2: error: ‘strncpy’ specified bound 32 equals destination size [-Werror=stringop-truncation]
+ strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE);
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+I'm not convinced it makes sense to truncate the copied strings here,
+but since we're already doing so let's ensure they're still null-
+terminated. We can't easily use strlcpy() here, so use snprintf().
+
+usbip_common.c has the same problem.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/tools/usb/usbip/libsrc/usbip_common.c
+===================================================================
+--- linux.orig/tools/usb/usbip/libsrc/usbip_common.c
++++ linux/tools/usb/usbip/libsrc/usbip_common.c
+@@ -226,8 +226,8 @@ int read_usb_device(struct udev_device *
+ path = udev_device_get_syspath(sdev);
+ name = udev_device_get_sysname(sdev);
+
+- strncpy(udev->path, path, SYSFS_PATH_MAX);
+- strncpy(udev->busid, name, SYSFS_BUS_ID_SIZE);
++ snprintf(udev->path, SYSFS_PATH_MAX, "%s", path);
++ snprintf(udev->busid, SYSFS_BUS_ID_SIZE, "%s", name);
+
+ sscanf(name, "%u-%u", &busnum, &devnum);
+ udev->busnum = busnum;
+Index: linux/tools/usb/usbip/libsrc/usbip_device_driver.c
+===================================================================
+--- linux.orig/tools/usb/usbip/libsrc/usbip_device_driver.c
++++ linux/tools/usb/usbip/libsrc/usbip_device_driver.c
+@@ -103,7 +103,7 @@ int read_usb_vudc_device(struct udev_dev
+ copy_descr_attr16(dev, &descr, idProduct);
+ copy_descr_attr16(dev, &descr, bcdDevice);
+
+- strncpy(dev->path, path, SYSFS_PATH_MAX);
++ snprintf(dev->path, SYSFS_PATH_MAX, "%s", path);
+
+ dev->speed = USB_SPEED_UNKNOWN;
+ speed = udev_device_get_sysattr_value(sdev, "current_speed");
+@@ -122,7 +122,7 @@ int read_usb_vudc_device(struct udev_dev
+ dev->busnum = 0;
+
+ name = udev_device_get_sysname(plat);
+- strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE);
++ snprintf(dev->busid, SYSFS_BUS_ID_SIZE, "%s", name);
+ return 0;
+ err:
+ fclose(fd);
diff --git a/debian/patches/bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch b/debian/patches/bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch
new file mode 100644
index 000000000..1329c9390
--- /dev/null
+++ b/debian/patches/bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch
@@ -0,0 +1,77 @@
+From: Jorik Jonker <jorik@kippendief.biz>
+Date: Sat, 29 Sep 2018 15:18:30 +0200
+Subject: ARM: dts: sun8i-h3: add sy8106a to orange pi plus
+Origin: https://git.kernel.org/linus/e98d72d98a25890308941080d3a17b4c77e3f460
+
+The Orange Pi Plus board lacks voltage scaling capabilities in its
+current form. This results in random freezes during boot when cpufreq is
+enabled, probably due to wrong voltages.
+
+This patch (more or less copy/paste from 06139c) does the following
+things on this board:
+- enable r_i2c
+- add sy8106a to the r_i2c bus
+- have the sy8106a regulate VDD of cpu
+
+Since the Orange Pi Plus has the same PMU setup as the Orange Pi PC, I
+simply took min/max/fixed/ramp from the latter DTS. In that file the
+origin of the values are described by the following comment:
+
+ "The datasheet uses 1.1V as the minimum value of VDD-CPUX,
+ however both the Armbian DVFS table and the official one
+ have operating points with voltage under 1.1V, and both
+ DVFS table are known to work properly at the lowest
+ operating point.
+ Use 1.0V as the minimum voltage instead."
+
+I have tested this on patch two Orange Pi Plus boards, by running a
+kernel with this patch and do intermettent runs of cpuburn while
+monitoring voltage, frequency and temperature. The board runs stable
+across its operatiing points while showing a reasonable (< 40C)
+temperature. My Orange Pi PC, when put to the same test, yields similar
+stable results.
+
+Signed-off-by: Jorik Jonker <jorik@kippendief.biz>
+Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
+---
+ arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+Index: linux/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
+===================================================================
+--- linux.orig/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
++++ linux/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts
+@@ -74,6 +74,10 @@
+ };
+ };
+
++&cpu0 {
++ cpu-supply = <&reg_vdd_cpux>;
++};
++
+ &ehci3 {
+ status = "okay";
+ };
+@@ -119,6 +123,22 @@
+ };
+ };
+
++&r_i2c {
++ status = "okay";
++
++ reg_vdd_cpux: regulator@65 {
++ compatible = "silergy,sy8106a";
++ reg = <0x65>;
++ regulator-name = "vdd-cpux";
++ silergy,fixed-microvolt = <1200000>;
++ regulator-min-microvolt = <1000000>;
++ regulator-max-microvolt = <1400000>;
++ regulator-ramp-delay = <200>;
++ regulator-boot-on;
++ regulator-always-on;
++ };
++};
++
+ &usbphy {
+ usb3_vbus-supply = <&reg_usb3_vbus>;
+ };
diff --git a/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch b/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch
new file mode 100644
index 000000000..a8fc875a3
--- /dev/null
+++ b/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch
@@ -0,0 +1,37 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 17 Feb 2017 01:30:30 +0000
+Subject: ARM: dts: kirkwood: Fix SATA pinmux-ing for TS419
+Forwarded: https://www.spinics.net/lists/arm-kernel/msg563610.html
+Bug-Debian: https://bugs.debian.org/855017
+
+The old board code for the TS419 assigns MPP pins 15 and 16 as SATA
+activity signals (and none as SATA presence signals). Currently the
+device tree assigns the SoC's default pinmux groups for SATA, which
+conflict with the second Ethernet port.
+
+Reported-by: gmbh@gazeta.pl
+Tested-by: gmbh@gazeta.pl
+References: https://bugs.debian.org/855017
+Cc: stable@vger.kernel.org # 3.15+
+Fixes: 934b524b3f49 ("ARM: Kirkwood: Add DT description of QNAP 419")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ arch/arm/boot/dts/kirkwood-ts419.dtsi | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+Index: linux/arch/arm/boot/dts/kirkwood-ts419.dtsi
+===================================================================
+--- linux.orig/arch/arm/boot/dts/kirkwood-ts419.dtsi
++++ linux/arch/arm/boot/dts/kirkwood-ts419.dtsi
+@@ -69,3 +69,11 @@
+ phy-handle = <&ethphy1>;
+ };
+ };
++
++&pmx_sata0 {
++ marvell,pins = "mpp15";
++};
++
++&pmx_sata1 {
++ marvell,pins = "mpp16";
++};
diff --git a/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch b/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch
new file mode 100644
index 000000000..2e8771b55
--- /dev/null
+++ b/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 11 Jul 2018 23:40:55 +0100
+Subject: ARM: mm: Export __sync_icache_dcache() for xen-privcmd
+Forwarded: https://marc.info/?l=linux-arm-kernel&m=153134944429241
+
+The xen-privcmd driver, which can be modular, calls set_pte_at()
+which in turn may call __sync_icache_dcache().
+
+The call to __sync_icache_dcache() may be optimised out because it is
+conditional on !pte_special(), and xen-privcmd calls pte_mkspecial().
+However, in a non-LPAE configuration there is no "special" bit and the
+call is really unconditional.
+
+Fixes: 3ad0876554ca ("xen/privcmd: add IOCTL_PRIVCMD_MMAP_RESOURCE")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ arch/arm/mm/flush.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: linux/arch/arm/mm/flush.c
+===================================================================
+--- linux.orig/arch/arm/mm/flush.c
++++ linux/arch/arm/mm/flush.c
+@@ -295,6 +295,7 @@ void __sync_icache_dcache(pte_t pteval)
+ if (pte_exec(pteval))
+ __flush_icache_all();
+ }
++EXPORT_SYMBOL_GPL(__sync_icache_dcache);
+ #endif
+
+ /*
diff --git a/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch b/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch
new file mode 100644
index 000000000..55fbe10b5
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch
@@ -0,0 +1,47 @@
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Sat, 15 Jun 2019 10:23:56 +1000
+Subject: [PATCH 3/4] arm64: PCI: Allow resource reallocation if necessary
+Origin: https://git.kernel.org/linus/3e8ba9686600e5f77e692126bf0293edf162989a
+
+Call pci_assign_unassigned_root_bus_resources() instead of the simpler:
+
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+
+pci_assign_unassigned_root_bus_resources() calls:
+
+ __pci_bus_size_bridges(bus, add_list);
+ __pci_bus_assign_resources(bus, add_list, &fail_head);
+
+so this should be equivalent as long as we're able to assign everything.
+If we were unable to assign something, previously we did nothing and left
+it unassigned, but after this patch, we will attempt to do some
+reallocation.
+
+Once we start honoring FW resource allocations, this will bring up the
+"reallocation" feature which can help making room for SR-IOV when
+necessary.
+
+Link: https://lore.kernel.org/r/20190615002359.29577-1-benh@kernel.crashing.org
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+---
+ arch/arm64/kernel/pci.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+Index: linux/arch/arm64/kernel/pci.c
+===================================================================
+--- linux.orig/arch/arm64/kernel/pci.c
++++ linux/arch/arm64/kernel/pci.c
+@@ -194,8 +194,7 @@ struct pci_bus *pci_acpi_scan_root(struc
+ if (!bus)
+ return NULL;
+
+- pci_bus_size_bridges(bus);
+- pci_bus_assign_resources(bus);
++ pci_assign_unassigned_root_bus_resources(bus);
+
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
diff --git a/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch b/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch
new file mode 100644
index 000000000..37bc6e0c8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch
@@ -0,0 +1,46 @@
+From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Date: Sat, 15 Jun 2019 10:23:59 +1000
+Subject: [PATCH 4/4] arm64: PCI: Preserve firmware configuration when desired
+Origin: https://git.kernel.org/linus/85dc04136e86680378546afb808357a58c06061c
+
+If we must preserve the firmware resource assignments, claim the existing
+resources rather than reassigning everything.
+
+Link: https://lore.kernel.org/r/20190615002359.29577-4-benh@kernel.crashing.org
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+[bhelgaas: commit log]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+---
+ arch/arm64/kernel/pci.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+Index: linux/arch/arm64/kernel/pci.c
+===================================================================
+--- linux.orig/arch/arm64/kernel/pci.c
++++ linux/arch/arm64/kernel/pci.c
+@@ -169,6 +169,7 @@ struct pci_bus *pci_acpi_scan_root(struc
+ struct acpi_pci_generic_root_info *ri;
+ struct pci_bus *bus, *child;
+ struct acpi_pci_root_ops *root_ops;
++ struct pci_host_bridge *host;
+
+ ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
+ if (!ri)
+@@ -194,6 +195,15 @@ struct pci_bus *pci_acpi_scan_root(struc
+ if (!bus)
+ return NULL;
+
++ /* If we must preserve the resource configuration, claim now */
++ host = pci_find_host_bridge(bus);
++ if (host->preserve_config)
++ pci_bus_claim_resources(bus);
++
++ /*
++ * Assign whatever was left unassigned. If we didn't claim above,
++ * this will reassign everything.
++ */
+ pci_assign_unassigned_root_bus_resources(bus);
+
+ list_for_each_entry(child, &bus->children, node)
diff --git a/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch
new file mode 100644
index 000000000..50098d001
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch
@@ -0,0 +1,92 @@
+From: Geoff Levand <geoff@infradead.org>
+Date: Wed, 13 Jun 2018 10:56:08 -0700
+Subject: arm64/acpi: Add fixup for HPE m400 quirks
+Forwarded: https://patchwork.codeaurora.org/patch/547277/
+
+Adds a new ACPI init routine acpi_fixup_m400_quirks that adds
+a work-around for HPE ProLiant m400 APEI firmware problems.
+
+The work-around disables APEI when CONFIG_ACPI_APEI is set and
+m400 firmware is detected. Without this fixup m400 systems
+experience errors like these on startup:
+
+ [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2
+ [Hardware Error]: event severity: fatal
+ [Hardware Error]: Error 0, type: fatal
+ [Hardware Error]: section_type: memory error
+ [Hardware Error]: error_status: 0x0000000000001300
+ [Hardware Error]: error_type: 10, invalid address
+ Kernel panic - not syncing: Fatal hardware error!
+
+Signed-off-by: Geoff Levand <geoff@infradead.org>
+[bwh: Adjust context to apply to Linux 4.19]
+---
+ arch/arm64/kernel/acpi.c | 40 ++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 36 insertions(+), 4 deletions(-)
+
+Index: linux/arch/arm64/kernel/acpi.c
+===================================================================
+--- linux.orig/arch/arm64/kernel/acpi.c
++++ linux/arch/arm64/kernel/acpi.c
+@@ -33,6 +33,8 @@
+ #include <asm/pgtable.h>
+ #include <asm/smp_plat.h>
+
++#include <acpi/apei.h>
++
+ int acpi_noirq = 1; /* skip ACPI IRQ initialization */
+ int acpi_disabled = 1;
+ EXPORT_SYMBOL(acpi_disabled);
+@@ -179,6 +181,33 @@ out:
+ }
+
+ /*
++ * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware
++ * problems.
++ */
++static void __init acpi_fixup_m400_quirks(void)
++{
++ acpi_status status;
++ struct acpi_table_header *header;
++#if !defined(CONFIG_ACPI_APEI)
++ int hest_disable = HEST_DISABLED;
++#endif
++
++ if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED)
++ return;
++
++ status = acpi_get_table(ACPI_SIG_HEST, 0, &header);
++
++ if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE ", 6) &&
++ !strncmp(header->oem_table_id, "ProLiant", 8) &&
++ MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) {
++ hest_disable = HEST_DISABLED;
++ pr_info("Disabled APEI for m400.\n");
++ }
++
++ acpi_put_table(header);
++}
++
++/*
+ * acpi_boot_table_init() called from setup_arch(), always.
+ * 1. find RSDP and get its address, and then find XSDT
+ * 2. extract all tables and checksums them all
+@@ -233,11 +262,14 @@ done:
+ if (acpi_disabled) {
+ if (earlycon_acpi_spcr_enable)
+ early_init_dt_scan_chosen_stdout();
+- } else {
+- acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
+- if (IS_ENABLED(CONFIG_ACPI_BGRT))
+- acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
++ return;
+ }
++
++ acpi_parse_spcr(earlycon_acpi_spcr_enable, true);
++ if (IS_ENABLED(CONFIG_ACPI_BGRT))
++ acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
++
++ acpi_fixup_m400_quirks();
+ }
+
+ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr)
diff --git a/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch b/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch
new file mode 100644
index 000000000..543364416
--- /dev/null
+++ b/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch
@@ -0,0 +1,28 @@
+From: Samuel Holland <samuel@sholland.org>
+Date: Sat, 12 Jan 2019 20:17:19 -0600
+Subject: arm64: dts: allwinner: a64: Enable A64 timer workaround
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/commit?id=55ec26d6a4241363fa94f15377ebd8f1116fbfd7
+
+As instability in the architectural timer has been observed on multiple
+devices using this SoC, inluding the Pine64 and the Orange Pi Win,
+enable the workaround in the SoC's device tree.
+
+Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
+Signed-off-by: Samuel Holland <samuel@sholland.org>
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: linux/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+===================================================================
+--- linux.orig/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
++++ linux/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+@@ -159,6 +159,7 @@
+
+ timer {
+ compatible = "arm,armv8-timer";
++ allwinner,erratum-unknown1;
+ interrupts = <GIC_PPI 13
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+ <GIC_PPI 14
diff --git a/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch
new file mode 100644
index 000000000..4116ab598
--- /dev/null
+++ b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch
@@ -0,0 +1,42 @@
+From: Heinrich Schuchardt <xypron.glpk@gmx.de>
+Date: Mon, 4 Jun 2018 19:15:23 +0200
+Subject: arm64: dts: rockchip: correct voltage selector on Firefly-RK3399
+Bug-Debian: https://bugs.debian.org/900799
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/patch/?id=710e8c4a54be82ee8a97324e7b4330bf191e08bf
+
+Without this patch the Firefly-RK3399 board boot process hangs after these
+lines:
+
+ fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1] Detected!
+ fan53555-reg: supplied by vcc_sys
+ vcc1v8_s3: supplied by vcc_1v8
+
+Blacklisting driver fan53555 allows booting.
+
+The device tree uses a value of fcs,suspend-voltage-selector different to
+any other board.
+
+Changing this setting to the usual value is sufficient to enable booting
+and also matches the value used in the vendor kernel.
+
+Fixes: 171582e00db1 ("arm64: dts: rockchip: add support for firefly-rk3399 board")
+Cc: stable@vger.kernel.org
+Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+---
+ arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
+===================================================================
+--- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
++++ linux/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
+@@ -455,7 +455,7 @@
+ vdd_cpu_b: regulator@40 {
+ compatible = "silergy,syr827";
+ reg = <0x40>;
+- fcs,suspend-voltage-selector = <0>;
++ fcs,suspend-voltage-selector = <1>;
+ regulator-name = "vdd_cpu_b";
+ regulator-min-microvolt = <712500>;
+ regulator-max-microvolt = <1500000>;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch b/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch
new file mode 100644
index 000000000..98b6e734e
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch
@@ -0,0 +1,47 @@
+From bbd24b8bdc501fb5dacb43e847b6eeb9a12829f5 Mon Sep 17 00:00:00 2001
+From: Luo Jiaxing <luojiaxing@huawei.com>
+Date: Mon, 24 Sep 2018 23:06:29 +0800
+Subject: [PATCH 02/31] scsi: hisi_sas: Move evaluation of hisi_hba in
+ hisi_sas_task_prep()
+Origin: https://git.kernel.org/linus/1668e3b6f8f8ed2ce685691c92b90dfadeaa3f2f
+
+In evaluating hisi_hba, the sas_port may be NULL, so for safety relocate
+the the check to value possible NULL deference.
+
+Signed-off-by: Luo Jiaxing <luojiaxing@huawei.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -288,13 +288,13 @@ static int hisi_sas_task_prep(struct sas
+ int *pass)
+ {
+ struct domain_device *device = task->dev;
+- struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
++ struct hisi_hba *hisi_hba;
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_sas_port *port;
+ struct hisi_sas_slot *slot;
+ struct hisi_sas_cmd_hdr *cmd_hdr_base;
+ struct asd_sas_port *sas_port = device->port;
+- struct device *dev = hisi_hba->dev;
++ struct device *dev;
+ int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
+ int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
+ struct hisi_sas_dq *dq;
+@@ -315,6 +315,9 @@ static int hisi_sas_task_prep(struct sas
+ return -ECOMM;
+ }
+
++ hisi_hba = dev_to_hisi_hba(device);
++ dev = hisi_hba->dev;
++
+ if (DEV_IS_GONE(sas_dev)) {
+ if (sas_dev)
+ dev_info(dev, "task prep: device %d not ready\n",
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch b/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch
new file mode 100644
index 000000000..a25ca7885
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch
@@ -0,0 +1,29 @@
+From de1d5713a20562acdb3f94466232432c9dd1d95c Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 24 Sep 2018 23:06:32 +0800
+Subject: [PATCH 05/31] scsi: hisi_sas: unmask interrupts ent72 and ent74
+Origin: https://git.kernel.org/linus/6ecf5ba13cd5959eb75f617ff32c93bb67790e48
+
+The interrupts of ent72 and ent74 are not processed by PCIe AER handling,
+so we need to unmask the interrupts and process them first in the driver.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -441,7 +441,7 @@ static void init_reg_v3_hw(struct hisi_h
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe);
+ if (pdev->revision >= 0x21)
+- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7fff);
++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7aff);
+ else
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff);
+ hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch b/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch
new file mode 100644
index 000000000..15a26a35a
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch
@@ -0,0 +1,308 @@
+From d35bf6fccf7d4064065c078d3d369ffeaad6c731 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 24 Sep 2018 23:06:33 +0800
+Subject: [PATCH 06/31] scsi: hisi_sas: Use block layer tag instead for IPTT
+Origin: https://git.kernel.org/linus/784b46b7cba0ae914dd293f23848c5057c6ba017
+
+Currently we use the IPTT defined in LLDD to identify IOs. Actually for
+IOs which are from the block layer, they have tags to identify them. So
+for those IOs, use tag of the block layer directly, and for IOs which is
+not from the block layer (such as internal IOs from libsas/LLDD), reserve
+96 IPTTs for them.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 3 +-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 89 +++++++++++++++++---------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 9 +--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 ++-
+ 5 files changed, 70 insertions(+), 40 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -34,6 +34,7 @@
+ #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES
+ #define HISI_SAS_RESET_BIT 0
+ #define HISI_SAS_REJECT_CMD_BIT 1
++#define HISI_SAS_RESERVED_IPTT_CNT 96
+
+ #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer))
+ #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table))
+@@ -217,7 +218,7 @@ struct hisi_sas_hw {
+ int (*hw_init)(struct hisi_hba *hisi_hba);
+ void (*setup_itct)(struct hisi_hba *hisi_hba,
+ struct hisi_sas_device *device);
+- int (*slot_index_alloc)(struct hisi_hba *hisi_hba, int *slot_idx,
++ int (*slot_index_alloc)(struct hisi_hba *hisi_hba,
+ struct domain_device *device);
+ struct hisi_sas_device *(*alloc_dev)(struct domain_device *device);
+ void (*sl_notify_ssp)(struct hisi_hba *hisi_hba, int phy_no);
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -184,7 +184,14 @@ static void hisi_sas_slot_index_clear(st
+
+ static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx)
+ {
+- hisi_sas_slot_index_clear(hisi_hba, slot_idx);
++ unsigned long flags;
++
++ if (hisi_hba->hw->slot_index_alloc || (slot_idx >=
++ hisi_hba->hw->max_command_entries - HISI_SAS_RESERVED_IPTT_CNT)) {
++ spin_lock_irqsave(&hisi_hba->lock, flags);
++ hisi_sas_slot_index_clear(hisi_hba, slot_idx);
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ }
+ }
+
+ static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx)
+@@ -194,24 +201,34 @@ static void hisi_sas_slot_index_set(stru
+ set_bit(slot_idx, bitmap);
+ }
+
+-static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx)
++static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba,
++ struct scsi_cmnd *scsi_cmnd)
+ {
+- unsigned int index;
++ int index;
+ void *bitmap = hisi_hba->slot_index_tags;
++ unsigned long flags;
+
++ if (scsi_cmnd)
++ return scsi_cmnd->request->tag;
++
++ spin_lock_irqsave(&hisi_hba->lock, flags);
+ index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
+- hisi_hba->last_slot_index + 1);
++ hisi_hba->last_slot_index + 1);
+ if (index >= hisi_hba->slot_index_count) {
+- index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count,
+- 0);
+- if (index >= hisi_hba->slot_index_count)
++ index = find_next_zero_bit(bitmap,
++ hisi_hba->slot_index_count,
++ hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT);
++ if (index >= hisi_hba->slot_index_count) {
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ return -SAS_QUEUE_FULL;
++ }
+ }
+ hisi_sas_slot_index_set(hisi_hba, index);
+- *slot_idx = index;
+ hisi_hba->last_slot_index = index;
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
+- return 0;
++ return index;
+ }
+
+ static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba)
+@@ -250,9 +267,7 @@ void hisi_sas_slot_task_free(struct hisi
+
+ memset(slot, 0, offsetof(struct hisi_sas_slot, buf));
+
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot->idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free);
+
+@@ -385,16 +400,27 @@ static int hisi_sas_task_prep(struct sas
+ goto err_out_dma_unmap;
+ }
+
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ if (hisi_hba->hw->slot_index_alloc)
+- rc = hisi_hba->hw->slot_index_alloc(hisi_hba, &slot_idx,
+- device);
+- else
+- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+- if (rc)
++ rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
++ else {
++ struct scsi_cmnd *scsi_cmnd = NULL;
++
++ if (task->uldd_task) {
++ struct ata_queued_cmd *qc;
++
++ if (dev_is_sata(device)) {
++ qc = task->uldd_task;
++ scsi_cmnd = qc->scsicmd;
++ } else {
++ scsi_cmnd = task->uldd_task;
++ }
++ }
++ rc = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd);
++ }
++ if (rc < 0)
+ goto err_out_dma_unmap;
+
++ slot_idx = rc;
+ slot = &hisi_hba->slot_info[slot_idx];
+
+ spin_lock_irqsave(&dq->lock, flags);
+@@ -455,9 +481,7 @@ static int hisi_sas_task_prep(struct sas
+ return 0;
+
+ err_out_tag:
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ err_out_dma_unmap:
+ if (!sas_protocol_ata(task->task_proto)) {
+ if (task->num_scatter) {
+@@ -1747,14 +1771,11 @@ hisi_sas_internal_abort_task_exec(struct
+ port = to_hisi_sas_port(sas_port);
+
+ /* simply get a slot and send abort command */
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx);
+- if (rc) {
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ rc = hisi_sas_slot_index_alloc(hisi_hba, NULL);
++ if (rc < 0)
+ goto err_out;
+- }
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+
++ slot_idx = rc;
+ slot = &hisi_hba->slot_info[slot_idx];
+
+ spin_lock_irqsave(&dq->lock, flags_dq);
+@@ -1790,7 +1811,6 @@ hisi_sas_internal_abort_task_exec(struct
+ spin_lock_irqsave(&task->task_state_lock, flags);
+ task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+ spin_unlock_irqrestore(&task->task_state_lock, flags);
+-
+ WRITE_ONCE(slot->ready, 1);
+ /* send abort command to the chip */
+ spin_lock_irqsave(&dq->lock, flags);
+@@ -1801,9 +1821,7 @@ hisi_sas_internal_abort_task_exec(struct
+ return 0;
+
+ err_out_tag:
+- spin_lock_irqsave(&hisi_hba->lock, flags);
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+- spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ err_out:
+ dev_err(dev, "internal abort task prep: failed[%d]!\n", rc);
+
+@@ -2179,6 +2197,8 @@ int hisi_sas_alloc(struct hisi_hba *hisi
+ hisi_sas_init_mem(hisi_hba);
+
+ hisi_sas_slot_index_init(hisi_hba);
++ hisi_hba->last_slot_index = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
+
+ hisi_hba->wq = create_singlethread_workqueue(dev_name(dev));
+ if (!hisi_hba->wq) {
+@@ -2382,8 +2402,15 @@ int hisi_sas_probe(struct platform_devic
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+ shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+- shost->can_queue = hisi_hba->hw->max_command_entries;
+- shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
++ if (hisi_hba->hw->slot_index_alloc) {
++ shost->can_queue = hisi_hba->hw->max_command_entries;
++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
++ } else {
++ shost->can_queue = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
++ }
+
+ sha->sas_ha_name = DRV_NAME;
+ sha->dev = hisi_hba->dev;
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1807,7 +1807,6 @@ static struct scsi_host_template sht_v1_
+ .scan_start = hisi_sas_scan_start,
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+- .can_queue = 1,
+ .this_id = -1,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -770,7 +770,7 @@ static u32 hisi_sas_phy_read32(struct hi
+
+ /* This function needs to be protected from pre-emption. */
+ static int
+-slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, int *slot_idx,
++slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba,
+ struct domain_device *device)
+ {
+ int sata_dev = dev_is_sata(device);
+@@ -778,6 +778,7 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ int sata_idx = sas_dev->sata_idx;
+ int start, end;
++ unsigned long flags;
+
+ if (!sata_dev) {
+ /*
+@@ -801,6 +802,7 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ end = 64 * (sata_idx + 2);
+ }
+
++ spin_lock_irqsave(&hisi_hba->lock, flags);
+ while (1) {
+ start = find_next_zero_bit(bitmap,
+ hisi_hba->slot_index_count, start);
+@@ -815,8 +817,8 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ }
+
+ set_bit(start, bitmap);
+- *slot_idx = start;
+- return 0;
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
++ return start;
+ }
+
+ static bool sata_index_alloc_v2_hw(struct hisi_hba *hisi_hba, int *idx)
+@@ -3558,7 +3560,6 @@ static struct scsi_host_template sht_v2_
+ .scan_start = hisi_sas_scan_start,
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+- .can_queue = 1,
+ .this_id = -1,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2108,7 +2108,6 @@ static struct scsi_host_template sht_v3_
+ .scan_start = hisi_sas_scan_start,
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+- .can_queue = 1,
+ .this_id = -1,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+@@ -2118,6 +2117,7 @@ static struct scsi_host_template sht_v3_
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+ .shost_attrs = host_attrs,
++ .tag_alloc_policy = BLK_TAG_ALLOC_RR,
+ };
+
+ static const struct hisi_sas_hw hisi_sas_v3_hw = {
+@@ -2255,8 +2255,10 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+ shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+- shost->can_queue = hisi_hba->hw->max_command_entries;
+- shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
++ shost->can_queue = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries -
++ HISI_SAS_RESERVED_IPTT_CNT;
+
+ sha->sas_ha_name = DRV_NAME;
+ sha->dev = dev;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch b/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch
new file mode 100644
index 000000000..440ad1a4a
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch
@@ -0,0 +1,54 @@
+From 4fdcfb8a09d75fbabf4454a60001224b89245c82 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Mon, 24 Sep 2018 23:06:34 +0800
+Subject: [PATCH 07/31] scsi: hisi_sas: Update v3 hw AIP_LIMIT and
+ CFG_AGING_TIME register values
+Origin: https://git.kernel.org/linus/3bccfba8312762becfb05b35d698ba8cffd440f2
+
+Update registers as follows:
+- Default value of AIP timer is 1ms, and it is easy for some expanders to
+ cause IO error. Change the value to max value 65ms to avoid IO error for
+ those expanders.
+
+- A CQ completion will be reported by HW when 4 CQs have occurred or the
+ aging timer expires, whichever happens first. Sor serial IO scenario, it
+ will still wait 8us for every IO before it is reported. So in the
+ situation, the performance is poor. So to improve it, change the limit
+ time to the least value.
+ For other scenario, it does little affect to the performance.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -127,6 +127,7 @@
+ #define PHY_CTRL_RESET_OFF 0
+ #define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF)
+ #define SL_CFG (PORT_BASE + 0x84)
++#define AIP_LIMIT (PORT_BASE + 0x90)
+ #define SL_CONTROL (PORT_BASE + 0x94)
+ #define SL_CONTROL_NOTIFY_EN_OFF 0
+ #define SL_CONTROL_NOTIFY_EN_MSK (0x1 << SL_CONTROL_NOTIFY_EN_OFF)
+@@ -431,6 +432,7 @@ static void init_reg_v3_hw(struct hisi_h
+ (u32)((1ULL << hisi_hba->queue_count) - 1));
+ hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400);
+ hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108);
++ hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1);
+ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
+@@ -495,6 +497,7 @@ static void init_reg_v3_hw(struct hisi_h
+ hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32);
+ /* used for 12G negotiate */
+ hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e);
++ hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff);
+ }
+
+ for (i = 0; i < hisi_hba->queue_count; i++) {
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch b/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch
new file mode 100644
index 000000000..1dbe7390b
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch
@@ -0,0 +1,33 @@
+From f27f6edaf4983b00a3c0e2f6ab720cfa3150a147 Mon Sep 17 00:00:00 2001
+From: John Garry <john.garry@huawei.com>
+Date: Tue, 16 Oct 2018 23:00:36 +0800
+Subject: [PATCH 08/31] scsi: hisi_sas: Fix spin lock management in
+ slot_index_alloc_quirk_v2_hw()
+Origin: https://git.kernel.org/linus/fe5fb42de36227c1c2dbb1e7403329ec8a915c20
+
+Currently a spin_unlock_irqrestore() call is missing on the error path,
+so add it.
+
+Reported-by: Julia Lawall <julia.lawall@lip6.fr>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -806,8 +806,10 @@ slot_index_alloc_quirk_v2_hw(struct hisi
+ while (1) {
+ start = find_next_zero_bit(bitmap,
+ hisi_hba->slot_index_count, start);
+- if (start >= end)
++ if (start >= end) {
++ spin_unlock_irqrestore(&hisi_hba->lock, flags);
+ return -SAS_QUEUE_FULL;
++ }
+ /*
+ * SAS IPTT bit0 should be 1, and SATA IPTT bit0 should be 0.
+ */
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch b/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch
new file mode 100644
index 000000000..9e466ba4c
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch
@@ -0,0 +1,40 @@
+From 59bc5f2f2492ef9949cd723fc98bafa7d8a6c287 Mon Sep 17 00:00:00 2001
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 18 Oct 2018 15:10:17 +0200
+Subject: [PATCH 09/31] scsi: hisi_sas: use dma_set_mask_and_coherent
+Origin: https://git.kernel.org/linus/e4db40e7a1a2cd6af3b6d5f8f3fba15533872398
+
+The driver currently uses pci_set_dma_mask despite otherwise using the
+generic DMA API. Switch it over to the better generic DMA API.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Acked-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 13 +++++--------
+ 1 file changed, 5 insertions(+), 8 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2199,14 +2199,11 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ if (rc)
+ goto err_out_disable_device;
+
+- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) ||
+- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) {
+- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) ||
+- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
+- dev_err(dev, "No usable DMA addressing method\n");
+- rc = -EIO;
+- goto err_out_regions;
+- }
++ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
++ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
++ dev_err(dev, "No usable DMA addressing method\n");
++ rc = -EIO;
++ goto err_out_regions;
+ }
+
+ shost = hisi_sas_shost_alloc_pci(pdev);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch b/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch
new file mode 100644
index 000000000..5bbf33aa2
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch
@@ -0,0 +1,116 @@
+From 4e63bca6e8c3a7fac800ee6c27f9afab13774fde Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:32 +0800
+Subject: [PATCH 10/31] scsi: hisi_sas: Create separate host attributes per HBA
+Origin: https://git.kernel.org/linus/c3566f9a617de3288739fd3b8e7539951bf2b04d
+
+Currently all the three HBA (v1/v2/v3 HW) share the same host attributes.
+
+To support each HBA having separate attributes in future, create per-HBA
+attributes.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ------
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 7 ++++++-
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 7 ++++++-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 ++++++-
+ 5 files changed, 18 insertions(+), 10 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas.h
++++ b/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -468,7 +468,6 @@ extern int hisi_sas_remove(struct platfo
+ extern int hisi_sas_slave_configure(struct scsi_device *sdev);
+ extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time);
+ extern void hisi_sas_scan_start(struct Scsi_Host *shost);
+-extern struct device_attribute *host_attrs[];
+ extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
+ extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
+ extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2021,12 +2021,6 @@ EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets
+ struct scsi_transport_template *hisi_sas_stt;
+ EXPORT_SYMBOL_GPL(hisi_sas_stt);
+
+-struct device_attribute *host_attrs[] = {
+- &dev_attr_phy_event_threshold,
+- NULL,
+-};
+-EXPORT_SYMBOL_GPL(host_attrs);
+-
+ static struct sas_domain_function_template hisi_sas_transport_ops = {
+ .lldd_dev_found = hisi_sas_dev_found,
+ .lldd_dev_gone = hisi_sas_dev_gone,
+--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1797,6 +1797,11 @@ static int hisi_sas_v1_init(struct hisi_
+ return 0;
+ }
+
++static struct device_attribute *host_attrs_v1_hw[] = {
++ &dev_attr_phy_event_threshold,
++ NULL
++};
++
+ static struct scsi_host_template sht_v1_hw = {
+ .name = DRV_NAME,
+ .module = THIS_MODULE,
+@@ -1816,7 +1821,7 @@ static struct scsi_host_template sht_v1_
+ .slave_alloc = sas_slave_alloc,
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+- .shost_attrs = host_attrs,
++ .shost_attrs = host_attrs_v1_hw,
+ };
+
+ static const struct hisi_sas_hw hisi_sas_v1_hw = {
+--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3552,6 +3552,11 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
++struct device_attribute *host_attrs_v2_hw[] = {
++ &dev_attr_phy_event_threshold,
++ NULL
++};
++
+ static struct scsi_host_template sht_v2_hw = {
+ .name = DRV_NAME,
+ .module = THIS_MODULE,
+@@ -3571,7 +3576,7 @@ static struct scsi_host_template sht_v2_
+ .slave_alloc = sas_slave_alloc,
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+- .shost_attrs = host_attrs,
++ .shost_attrs = host_attrs_v2_hw,
+ };
+
+ static const struct hisi_sas_hw hisi_sas_v2_hw = {
+--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2101,6 +2101,11 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
++struct device_attribute *host_attrs_v3_hw[] = {
++ &dev_attr_phy_event_threshold,
++ NULL
++};
++
+ static struct scsi_host_template sht_v3_hw = {
+ .name = DRV_NAME,
+ .module = THIS_MODULE,
+@@ -2120,7 +2125,7 @@ static struct scsi_host_template sht_v3_
+ .slave_alloc = sas_slave_alloc,
+ .target_destroy = sas_target_destroy,
+ .ioctl = sas_ioctl,
+- .shost_attrs = host_attrs,
++ .shost_attrs = host_attrs_v3_hw,
+ .tag_alloc_policy = BLK_TAG_ALLOC_RR,
+ };
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch b/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch
new file mode 100644
index 000000000..ae1b2d718
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch
@@ -0,0 +1,113 @@
+From 7e5e4c2dfd67e156956e46c4d503466726a5359c Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:33 +0800
+Subject: [PATCH 11/31] scsi: hisi_sas: Add support for interrupt converge for
+ v3 hw
+Origin: https://git.kernel.org/linus/488cf558e3d7c95daf737d9cae165019ee3f2840
+
+If CQ_INT_CONVERGE_EN is enabled, the interrupts of all the 16 CQ queues
+will be reported by CQ0.
+
+So we need to change the process of CQ tasklet for this situation.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 29 +++++++++++++++++++++-----
+ 1 file changed, 24 insertions(+), 5 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -42,6 +42,7 @@
+ #define MAX_CON_TIME_LIMIT_TIME 0xa4
+ #define BUS_INACTIVE_LIMIT_TIME 0xa8
+ #define REJECT_TO_OPEN_LIMIT_TIME 0xac
++#define CQ_INT_CONVERGE_EN 0xb0
+ #define CFG_AGING_TIME 0xbc
+ #define HGC_DFX_CFG2 0xc0
+ #define CFG_ABT_SET_QUERY_IPTT 0xd4
+@@ -371,6 +372,9 @@ struct hisi_sas_err_record_v3 {
+ ((fis.command == ATA_CMD_DEV_RESET) && \
+ ((fis.control & ATA_SRST) != 0)))
+
++static bool hisi_sas_intr_conv;
++MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)");
++
+ static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
+ {
+ void __iomem *regs = hisi_hba->regs + off;
+@@ -436,6 +440,8 @@ static void init_reg_v3_hw(struct hisi_h
+ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
+ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
++ hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN,
++ hisi_sas_intr_conv);
+ hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff);
+ hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff);
+@@ -1878,10 +1884,12 @@ static int interrupt_init_v3_hw(struct h
+ for (i = 0; i < hisi_hba->queue_count; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
+ struct tasklet_struct *t = &cq->tasklet;
++ int nr = hisi_sas_intr_conv ? 16 : 16 + i;
++ unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0;
+
+- rc = devm_request_irq(dev, pci_irq_vector(pdev, i+16),
+- cq_interrupt_v3_hw, 0,
+- DRV_NAME " cq", cq);
++ rc = devm_request_irq(dev, pci_irq_vector(pdev, nr),
++ cq_interrupt_v3_hw, irqflags,
++ DRV_NAME " cq", cq);
+ if (rc) {
+ dev_err(dev,
+ "could not request cq%d interrupt, rc=%d\n",
+@@ -1898,8 +1906,9 @@ static int interrupt_init_v3_hw(struct h
+ free_cq_irqs:
+ for (k = 0; k < i; k++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[k];
++ int nr = hisi_sas_intr_conv ? 16 : 16 + k;
+
+- free_irq(pci_irq_vector(pdev, k+16), cq);
++ free_irq(pci_irq_vector(pdev, nr), cq);
+ }
+ free_irq(pci_irq_vector(pdev, 11), hisi_hba);
+ free_chnl_interrupt:
+@@ -2089,8 +2098,16 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
++static ssize_t intr_conv_v3_hw_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ return scnprintf(buf, PAGE_SIZE, "%u\n", hisi_sas_intr_conv);
++}
++static DEVICE_ATTR_RO(intr_conv_v3_hw);
++
+ struct device_attribute *host_attrs_v3_hw[] = {
+ &dev_attr_phy_event_threshold,
++ &dev_attr_intr_conv_v3_hw,
+ NULL
+ };
+
+@@ -2303,8 +2320,9 @@ hisi_sas_v3_destroy_irqs(struct pci_dev
+ free_irq(pci_irq_vector(pdev, 11), hisi_hba);
+ for (i = 0; i < hisi_hba->queue_count; i++) {
+ struct hisi_sas_cq *cq = &hisi_hba->cq[i];
++ int nr = hisi_sas_intr_conv ? 16 : 16 + i;
+
+- free_irq(pci_irq_vector(pdev, i+16), cq);
++ free_irq(pci_irq_vector(pdev, nr), cq);
+ }
+ pci_free_irq_vectors(pdev);
+ }
+@@ -2626,6 +2644,7 @@ static struct pci_driver sas_v3_pci_driv
+ };
+
+ module_pci_driver(sas_v3_pci_driver);
++module_param_named(intr_conv, hisi_sas_intr_conv, bool, 0444);
+
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("John Garry <john.garry@huawei.com>");
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch b/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch
new file mode 100644
index 000000000..4595633a2
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch
@@ -0,0 +1,150 @@
+From 20ca5e4f2c4a2c08340225f074c56f7be1c86f5b Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:34 +0800
+Subject: [PATCH 12/31] scsi: hisi_sas: Add support for interrupt coalescing
+ for v3 hw
+Origin: https://git.kernel.org/linus/37359798ec44ae03fab383a9bef3b7c9df819063
+
+If INT_COAL_EN is enabled, configure time and count of interrupt
+coalescing. Then if CQ collects count of CQ entries in time, it will
+report the interrupt. Or if CQ doesn't collect enough CQ entries in time,
+it will report the interrupt at timeout.
+
+As all the registers are not supported to be changed dynamically, we need
+to config those register between disable and enable PHYs.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 2 +
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 100 +++++++++++++++++++++++++
+ 2 files changed, 102 insertions(+)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas.h
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas.h
++++ linux/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -322,6 +322,8 @@ struct hisi_hba {
+ unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
+ struct work_struct rst_work;
+ u32 phy_state;
++ u32 intr_coal_ticks; /* Time of interrupt coalesce in us */
++ u32 intr_coal_count; /* Interrupt count to coalesce */
+ };
+
+ /* Generic HW DMA host memory structures */
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2105,9 +2105,109 @@ static ssize_t intr_conv_v3_hw_show(stru
+ }
+ static DEVICE_ATTR_RO(intr_conv_v3_hw);
+
++static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba)
++{
++ /* config those registers between enable and disable PHYs */
++ hisi_sas_stop_phys(hisi_hba);
++
++ if (hisi_hba->intr_coal_ticks == 0 ||
++ hisi_hba->intr_coal_count == 0) {
++ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
++ } else {
++ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME,
++ hisi_hba->intr_coal_ticks);
++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT,
++ hisi_hba->intr_coal_count);
++ }
++ phys_init_v3_hw(hisi_hba);
++}
++
++static ssize_t intr_coal_ticks_v3_hw_show(struct device *dev,
++ struct device_attribute *attr,
++ char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n",
++ hisi_hba->intr_coal_ticks);
++}
++
++static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++ u32 intr_coal_ticks;
++ int ret;
++
++ ret = kstrtou32(buf, 10, &intr_coal_ticks);
++ if (ret) {
++ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
++ return -EINVAL;
++ }
++
++ if (intr_coal_ticks >= BIT(24)) {
++ dev_err(dev, "intr_coal_ticks must be less than 2^24!\n");
++ return -EINVAL;
++ }
++
++ hisi_hba->intr_coal_ticks = intr_coal_ticks;
++
++ config_intr_coal_v3_hw(hisi_hba);
++
++ return count;
++}
++static DEVICE_ATTR_RW(intr_coal_ticks_v3_hw);
++
++static ssize_t intr_coal_count_v3_hw_show(struct device *dev,
++ struct device_attribute
++ *attr, char *buf)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++
++ return scnprintf(buf, PAGE_SIZE, "%u\n",
++ hisi_hba->intr_coal_count);
++}
++
++static ssize_t intr_coal_count_v3_hw_store(struct device *dev,
++ struct device_attribute
++ *attr, const char *buf, size_t count)
++{
++ struct Scsi_Host *shost = class_to_shost(dev);
++ struct hisi_hba *hisi_hba = shost_priv(shost);
++ u32 intr_coal_count;
++ int ret;
++
++ ret = kstrtou32(buf, 10, &intr_coal_count);
++ if (ret) {
++ dev_err(dev, "Input data of interrupt coalesce unmatch\n");
++ return -EINVAL;
++ }
++
++ if (intr_coal_count >= BIT(8)) {
++ dev_err(dev, "intr_coal_count must be less than 2^8!\n");
++ return -EINVAL;
++ }
++
++ hisi_hba->intr_coal_count = intr_coal_count;
++
++ config_intr_coal_v3_hw(hisi_hba);
++
++ return count;
++}
++static DEVICE_ATTR_RW(intr_coal_count_v3_hw);
++
+ struct device_attribute *host_attrs_v3_hw[] = {
+ &dev_attr_phy_event_threshold,
+ &dev_attr_intr_conv_v3_hw,
++ &dev_attr_intr_coal_ticks_v3_hw,
++ &dev_attr_intr_coal_count_v3_hw,
+ NULL
+ };
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch b/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch
new file mode 100644
index 000000000..060fbcfb8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch
@@ -0,0 +1,92 @@
+From 22834ed6cec2690817120e960d43bbf76ddfda17 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Fri, 9 Nov 2018 22:06:35 +0800
+Subject: [PATCH 13/31] scsi: hisi_sas: Relocate some codes to avoid an unused
+ check
+Origin: https://git.kernel.org/linus/745b6847634c11dda1079d0290781a443eddb4b7
+
+In function hisi_sas_task_prep(), we check asd_sas_port, but in function
+hisi_sas_task_exec(), we already refer to asd_sas_port by using function
+dev_to_hisi_hba() implicitly. So to avoid this possible invalid
+dereference, relocate the check to function hisi_sas_task_prep().
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 44 ++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 21 deletions(-)
+
+--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -303,36 +303,19 @@ static int hisi_sas_task_prep(struct sas
+ int *pass)
+ {
+ struct domain_device *device = task->dev;
+- struct hisi_hba *hisi_hba;
++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
+ struct hisi_sas_device *sas_dev = device->lldd_dev;
+ struct hisi_sas_port *port;
+ struct hisi_sas_slot *slot;
+ struct hisi_sas_cmd_hdr *cmd_hdr_base;
+ struct asd_sas_port *sas_port = device->port;
+- struct device *dev;
++ struct device *dev = hisi_hba->dev;
+ int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
+ int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
+ struct hisi_sas_dq *dq;
+ unsigned long flags;
+ int wr_q_index;
+
+- if (!sas_port) {
+- struct task_status_struct *ts = &task->task_status;
+-
+- ts->resp = SAS_TASK_UNDELIVERED;
+- ts->stat = SAS_PHY_DOWN;
+- /*
+- * libsas will use dev->port, should
+- * not call task_done for sata
+- */
+- if (device->dev_type != SAS_SATA_DEV)
+- task->task_done(task);
+- return -ECOMM;
+- }
+-
+- hisi_hba = dev_to_hisi_hba(device);
+- dev = hisi_hba->dev;
+-
+ if (DEV_IS_GONE(sas_dev)) {
+ if (sas_dev)
+ dev_info(dev, "task prep: device %d not ready\n",
+@@ -507,10 +490,29 @@ static int hisi_sas_task_exec(struct sas
+ u32 rc;
+ u32 pass = 0;
+ unsigned long flags;
+- struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev);
+- struct device *dev = hisi_hba->dev;
++ struct hisi_hba *hisi_hba;
++ struct device *dev;
++ struct domain_device *device = task->dev;
++ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_dq *dq = NULL;
+
++ if (!sas_port) {
++ struct task_status_struct *ts = &task->task_status;
++
++ ts->resp = SAS_TASK_UNDELIVERED;
++ ts->stat = SAS_PHY_DOWN;
++ /*
++ * libsas will use dev->port, should
++ * not call task_done for sata
++ */
++ if (device->dev_type != SAS_SATA_DEV)
++ task->task_done(task);
++ return -ECOMM;
++ }
++
++ hisi_hba = dev_to_hisi_hba(device);
++ dev = hisi_hba->dev;
++
+ if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) {
+ /*
+ * For IOs from upper layer, it may already disable preempt
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch b/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch
new file mode 100644
index 000000000..1f9ed71c0
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch
@@ -0,0 +1,429 @@
+From 13dda01985003ca1b930b42bb3927f7522f4ce69 Mon Sep 17 00:00:00 2001
+From: John Garry <john.garry@huawei.com>
+Date: Thu, 6 Dec 2018 21:34:40 +0800
+Subject: [PATCH 14/31] scsi: hisi_sas: Fix warnings detected by sparse
+Origin: https://git.kernel.org/linus/735bcc77e6ba83e464665cea9041072190ede37e
+
+This patchset fixes some warnings detected by the sparse tool, like these:
+drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: warning: incorrect type in assignment (different base types)
+drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: expected unsigned short [unsigned] [assigned] [usertype] tag_of_task_to_be_managed
+drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: got restricted __le16 [usertype] <noident>
+drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: warning: incorrect type in assignment (different base types)
+drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: expected unsigned short [unsigned] [assigned] [usertype] tag_of_task_to_be_managed
+drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: got restricted __le16 [usertype] <noident>
+
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas.h | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 6 +--
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 15 +++---
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 66 +++++++++++++++-----------
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 37 +++++++++------
+ 5 files changed, 71 insertions(+), 55 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas.h
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas.h
++++ linux/drivers/scsi/hisi_sas/hisi_sas.h
+@@ -211,7 +211,7 @@ struct hisi_sas_slot {
+ /* Do not reorder/change members after here */
+ void *buf;
+ dma_addr_t buf_dma;
+- int idx;
++ u16 idx;
+ };
+
+ struct hisi_sas_hw {
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -1463,12 +1463,12 @@ static int hisi_sas_abort_task(struct sa
+ if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
+ struct scsi_cmnd *cmnd = task->uldd_task;
+ struct hisi_sas_slot *slot = task->lldd_task;
+- u32 tag = slot->idx;
++ u16 tag = slot->idx;
+ int rc2;
+
+ int_to_scsilun(cmnd->device->lun, &lun);
+ tmf_task.tmf = TMF_ABORT_TASK;
+- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
++ tmf_task.tag_of_task_to_be_managed = tag;
+
+ rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun,
+ &tmf_task);
+@@ -1722,7 +1722,7 @@ static int hisi_sas_query_task(struct sa
+
+ int_to_scsilun(cmnd->device->lun, &lun);
+ tmf_task.tmf = TMF_QUERY_TASK;
+- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag);
++ tmf_task.tag_of_task_to_be_managed = tag;
+
+ rc = hisi_sas_debug_issue_ssp_tmf(device,
+ lun.scsi_lun,
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -510,6 +510,7 @@ static void setup_itct_v1_hw(struct hisi
+ struct hisi_sas_itct *itct = &hisi_hba->itct[device_id];
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ u64 sas_addr;
+
+ memset(itct, 0, sizeof(*itct));
+
+@@ -534,8 +535,8 @@ static void setup_itct_v1_hw(struct hisi
+ itct->qw0 = cpu_to_le64(qw0);
+
+ /* qw1 */
+- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
+- itct->sas_addr = __swab64(itct->sas_addr);
++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
+
+ /* qw2 */
+ itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
+@@ -561,7 +562,7 @@ static void clear_itct_v1_hw(struct hisi
+ reg_val &= ~CFG_AGING_TIME_ITCT_REL_MSK;
+ hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val);
+
+- qw0 = cpu_to_le64(itct->qw0);
++ qw0 = le64_to_cpu(itct->qw0);
+ qw0 &= ~ITCT_HDR_VALID_MSK;
+ itct->qw0 = cpu_to_le64(qw0);
+ }
+@@ -1100,7 +1101,7 @@ static void slot_err_v1_hw(struct hisi_h
+ case SAS_PROTOCOL_SSP:
+ {
+ int error = -1;
+- u32 dma_err_type = cpu_to_le32(err_record->dma_err_type);
++ u32 dma_err_type = le32_to_cpu(err_record->dma_err_type);
+ u32 dma_tx_err_type = ((dma_err_type &
+ ERR_HDR_DMA_TX_ERR_TYPE_MSK)) >>
+ ERR_HDR_DMA_TX_ERR_TYPE_OFF;
+@@ -1108,9 +1109,9 @@ static void slot_err_v1_hw(struct hisi_h
+ ERR_HDR_DMA_RX_ERR_TYPE_MSK)) >>
+ ERR_HDR_DMA_RX_ERR_TYPE_OFF;
+ u32 trans_tx_fail_type =
+- cpu_to_le32(err_record->trans_tx_fail_type);
++ le32_to_cpu(err_record->trans_tx_fail_type);
+ u32 trans_rx_fail_type =
+- cpu_to_le32(err_record->trans_rx_fail_type);
++ le32_to_cpu(err_record->trans_rx_fail_type);
+
+ if (dma_tx_err_type) {
+ /* dma tx err */
+@@ -1558,7 +1559,7 @@ static irqreturn_t cq_interrupt_v1_hw(in
+ u32 cmplt_hdr_data;
+
+ complete_hdr = &complete_queue[rd_point];
+- cmplt_hdr_data = cpu_to_le32(complete_hdr->data);
++ cmplt_hdr_data = le32_to_cpu(complete_hdr->data);
+ idx = (cmplt_hdr_data & CMPLT_HDR_IPTT_MSK) >>
+ CMPLT_HDR_IPTT_OFF;
+ slot = &hisi_hba->slot_info[idx];
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -934,6 +934,7 @@ static void setup_itct_v2_hw(struct hisi
+ struct domain_device *parent_dev = device->parent;
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ u64 sas_addr;
+
+ memset(itct, 0, sizeof(*itct));
+
+@@ -966,8 +967,8 @@ static void setup_itct_v2_hw(struct hisi
+ itct->qw0 = cpu_to_le64(qw0);
+
+ /* qw1 */
+- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
+- itct->sas_addr = __swab64(itct->sas_addr);
++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
+
+ /* qw2 */
+ if (!dev_is_sata(device))
+@@ -2044,11 +2045,11 @@ static void slot_err_v2_hw(struct hisi_h
+ struct task_status_struct *ts = &task->task_status;
+ struct hisi_sas_err_record_v2 *err_record =
+ hisi_sas_status_buf_addr_mem(slot);
+- u32 trans_tx_fail_type = cpu_to_le32(err_record->trans_tx_fail_type);
+- u32 trans_rx_fail_type = cpu_to_le32(err_record->trans_rx_fail_type);
+- u16 dma_tx_err_type = cpu_to_le16(err_record->dma_tx_err_type);
+- u16 sipc_rx_err_type = cpu_to_le16(err_record->sipc_rx_err_type);
+- u32 dma_rx_err_type = cpu_to_le32(err_record->dma_rx_err_type);
++ u32 trans_tx_fail_type = le32_to_cpu(err_record->trans_tx_fail_type);
++ u32 trans_rx_fail_type = le32_to_cpu(err_record->trans_rx_fail_type);
++ u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);
++ u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);
++ u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);
+ int error = -1;
+
+ if (err_phase == 1) {
+@@ -2059,8 +2060,7 @@ static void slot_err_v2_hw(struct hisi_h
+ trans_tx_fail_type);
+ } else if (err_phase == 2) {
+ /* error in RX phase, the priority is: DW1 > DW3 > DW2 */
+- error = parse_trans_rx_err_code_v2_hw(
+- trans_rx_fail_type);
++ error = parse_trans_rx_err_code_v2_hw(trans_rx_fail_type);
+ if (error == -1) {
+ error = parse_dma_rx_err_code_v2_hw(
+ dma_rx_err_type);
+@@ -2358,6 +2358,7 @@ slot_complete_v2_hw(struct hisi_hba *his
+ &complete_queue[slot->cmplt_queue_slot];
+ unsigned long flags;
+ bool is_internal = slot->is_internal;
++ u32 dw0;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+ return -EINVAL;
+@@ -2382,8 +2383,9 @@ slot_complete_v2_hw(struct hisi_hba *his
+ }
+
+ /* Use SAS+TMF status codes */
+- switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK)
+- >> CMPLT_HDR_ABORT_STAT_OFF) {
++ dw0 = le32_to_cpu(complete_hdr->dw0);
++ switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >>
++ CMPLT_HDR_ABORT_STAT_OFF) {
+ case STAT_IO_ABORTED:
+ /* this io has been aborted by abort command */
+ ts->stat = SAS_ABORTED_TASK;
+@@ -2408,9 +2410,8 @@ slot_complete_v2_hw(struct hisi_hba *his
+ break;
+ }
+
+- if ((complete_hdr->dw0 & CMPLT_HDR_ERX_MSK) &&
+- (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {
+- u32 err_phase = (complete_hdr->dw0 & CMPLT_HDR_ERR_PHASE_MSK)
++ if ((dw0 & CMPLT_HDR_ERX_MSK) && (!(dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {
++ u32 err_phase = (dw0 & CMPLT_HDR_ERR_PHASE_MSK)
+ >> CMPLT_HDR_ERR_PHASE_OFF;
+ u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
+
+@@ -2526,22 +2527,23 @@ static void prep_ata_v2_hw(struct hisi_h
+ struct hisi_sas_tmf_task *tmf = slot->tmf;
+ u8 *buf_cmd;
+ int has_data = 0, hdr_tag = 0;
+- u32 dw1 = 0, dw2 = 0;
++ u32 dw0, dw1 = 0, dw2 = 0;
+
+ /* create header */
+ /* dw0 */
+- hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF);
++ dw0 = port->id << CMD_HDR_PORT_OFF;
+ if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
+- hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF);
++ dw0 |= 3 << CMD_HDR_CMD_OFF;
+ else
+- hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF);
++ dw0 |= 4 << CMD_HDR_CMD_OFF;
+
+ if (tmf && tmf->force_phy) {
+- hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK;
+- hdr->dw0 |= cpu_to_le32((1 << tmf->phy_id)
+- << CMD_HDR_PHY_ID_OFF);
++ dw0 |= CMD_HDR_FORCE_PHY_MSK;
++ dw0 |= (1 << tmf->phy_id) << CMD_HDR_PHY_ID_OFF;
+ }
+
++ hdr->dw0 = cpu_to_le32(dw0);
++
+ /* dw1 */
+ switch (task->data_dir) {
+ case DMA_TO_DEVICE:
+@@ -3152,20 +3154,24 @@ static void cq_tasklet_v2_hw(unsigned lo
+
+ /* Check for NCQ completion */
+ if (complete_hdr->act) {
+- u32 act_tmp = complete_hdr->act;
++ u32 act_tmp = le32_to_cpu(complete_hdr->act);
+ int ncq_tag_count = ffs(act_tmp);
++ u32 dw1 = le32_to_cpu(complete_hdr->dw1);
+
+- dev_id = (complete_hdr->dw1 & CMPLT_HDR_DEV_ID_MSK) >>
++ dev_id = (dw1 & CMPLT_HDR_DEV_ID_MSK) >>
+ CMPLT_HDR_DEV_ID_OFF;
+ itct = &hisi_hba->itct[dev_id];
+
+ /* The NCQ tags are held in the itct header */
+ while (ncq_tag_count) {
+- __le64 *ncq_tag = &itct->qw4_15[0];
++ __le64 *_ncq_tag = &itct->qw4_15[0], __ncq_tag;
++ u64 ncq_tag;
+
+- ncq_tag_count -= 1;
+- iptt = (ncq_tag[ncq_tag_count / 5]
+- >> (ncq_tag_count % 5) * 12) & 0xfff;
++ ncq_tag_count--;
++ __ncq_tag = _ncq_tag[ncq_tag_count / 5];
++ ncq_tag = le64_to_cpu(__ncq_tag);
++ iptt = (ncq_tag >> (ncq_tag_count % 5) * 12) &
++ 0xfff;
+
+ slot = &hisi_hba->slot_info[iptt];
+ slot->cmplt_queue_slot = rd_point;
+@@ -3176,7 +3182,9 @@ static void cq_tasklet_v2_hw(unsigned lo
+ ncq_tag_count = ffs(act_tmp);
+ }
+ } else {
+- iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
++ u32 dw1 = le32_to_cpu(complete_hdr->dw1);
++
++ iptt = dw1 & CMPLT_HDR_IPTT_MSK;
+ slot = &hisi_hba->slot_info[iptt];
+ slot->cmplt_queue_slot = rd_point;
+ slot->cmplt_queue = queue;
+@@ -3552,7 +3560,7 @@ static void wait_cmds_complete_timeout_v
+ dev_dbg(dev, "wait commands complete %dms\n", time);
+ }
+
+-struct device_attribute *host_attrs_v2_hw[] = {
++static struct device_attribute *host_attrs_v2_hw[] = {
+ &dev_attr_phy_event_threshold,
+ NULL
+ };
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -628,6 +628,7 @@ static void setup_itct_v3_hw(struct hisi
+ struct domain_device *parent_dev = device->parent;
+ struct asd_sas_port *sas_port = device->port;
+ struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
++ u64 sas_addr;
+
+ memset(itct, 0, sizeof(*itct));
+
+@@ -660,8 +661,8 @@ static void setup_itct_v3_hw(struct hisi
+ itct->qw0 = cpu_to_le64(qw0);
+
+ /* qw1 */
+- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE);
+- itct->sas_addr = __swab64(itct->sas_addr);
++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
+
+ /* qw2 */
+ if (!dev_is_sata(device))
+@@ -1590,15 +1591,16 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba
+ &complete_queue[slot->cmplt_queue_slot];
+ struct hisi_sas_err_record_v3 *record =
+ hisi_sas_status_buf_addr_mem(slot);
+- u32 dma_rx_err_type = record->dma_rx_err_type;
+- u32 trans_tx_fail_type = record->trans_tx_fail_type;
++ u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type);
++ u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type);
++ u32 dw3 = le32_to_cpu(complete_hdr->dw3);
+
+ switch (task->task_proto) {
+ case SAS_PROTOCOL_SSP:
+ if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
+ ts->residual = trans_tx_fail_type;
+ ts->stat = SAS_DATA_UNDERRUN;
+- } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
++ } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
+ ts->stat = SAS_QUEUE_FULL;
+ slot->abort = 1;
+ } else {
+@@ -1612,7 +1614,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba
+ if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
+ ts->residual = trans_tx_fail_type;
+ ts->stat = SAS_DATA_UNDERRUN;
+- } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
++ } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
+ ts->stat = SAS_PHY_DOWN;
+ slot->abort = 1;
+ } else {
+@@ -1645,6 +1647,7 @@ slot_complete_v3_hw(struct hisi_hba *his
+ &complete_queue[slot->cmplt_queue_slot];
+ unsigned long flags;
+ bool is_internal = slot->is_internal;
++ u32 dw0, dw1, dw3;
+
+ if (unlikely(!task || !task->lldd_task || !task->dev))
+ return -EINVAL;
+@@ -1668,11 +1671,14 @@ slot_complete_v3_hw(struct hisi_hba *his
+ goto out;
+ }
+
++ dw0 = le32_to_cpu(complete_hdr->dw0);
++ dw1 = le32_to_cpu(complete_hdr->dw1);
++ dw3 = le32_to_cpu(complete_hdr->dw3);
++
+ /*
+ * Use SAS+TMF status codes
+ */
+- switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK)
+- >> CMPLT_HDR_ABORT_STAT_OFF) {
++ switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >> CMPLT_HDR_ABORT_STAT_OFF) {
+ case STAT_IO_ABORTED:
+ /* this IO has been aborted by abort command */
+ ts->stat = SAS_ABORTED_TASK;
+@@ -1695,7 +1701,7 @@ slot_complete_v3_hw(struct hisi_hba *his
+ }
+
+ /* check for erroneous completion */
+- if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
++ if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
+ u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
+
+ slot_err_v3_hw(hisi_hba, task, slot);
+@@ -1704,8 +1710,7 @@ slot_complete_v3_hw(struct hisi_hba *his
+ "CQ hdr: 0x%x 0x%x 0x%x 0x%x "
+ "Error info: 0x%x 0x%x 0x%x 0x%x\n",
+ slot->idx, task, sas_dev->device_id,
+- complete_hdr->dw0, complete_hdr->dw1,
+- complete_hdr->act, complete_hdr->dw3,
++ dw0, dw1, complete_hdr->act, dw3,
+ error_info[0], error_info[1],
+ error_info[2], error_info[3]);
+ if (unlikely(slot->abort))
+@@ -1803,11 +1808,13 @@ static void cq_tasklet_v3_hw(unsigned lo
+ while (rd_point != wr_point) {
+ struct hisi_sas_complete_v3_hdr *complete_hdr;
+ struct device *dev = hisi_hba->dev;
++ u32 dw1;
+ int iptt;
+
+ complete_hdr = &complete_queue[rd_point];
++ dw1 = le32_to_cpu(complete_hdr->dw1);
+
+- iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK;
++ iptt = dw1 & CMPLT_HDR_IPTT_MSK;
+ if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) {
+ slot = &hisi_hba->slot_info[iptt];
+ slot->cmplt_queue_slot = rd_point;
+@@ -2203,7 +2210,7 @@ static ssize_t intr_coal_count_v3_hw_sto
+ }
+ static DEVICE_ATTR_RW(intr_coal_count_v3_hw);
+
+-struct device_attribute *host_attrs_v3_hw[] = {
++static struct device_attribute *host_attrs_v3_hw[] = {
+ &dev_attr_phy_event_threshold,
+ &dev_attr_intr_conv_v3_hw,
+ &dev_attr_intr_coal_ticks_v3_hw,
+@@ -2649,7 +2656,7 @@ static int hisi_sas_v3_suspend(struct pc
+ struct hisi_hba *hisi_hba = sha->lldd_ha;
+ struct device *dev = hisi_hba->dev;
+ struct Scsi_Host *shost = hisi_hba->shost;
+- u32 device_state;
++ pci_power_t device_state;
+ int rc;
+
+ if (!pdev->pm_cap) {
+@@ -2695,7 +2702,7 @@ static int hisi_sas_v3_resume(struct pci
+ struct Scsi_Host *shost = hisi_hba->shost;
+ struct device *dev = hisi_hba->dev;
+ unsigned int rc;
+- u32 device_state = pdev->current_state;
++ pci_power_t device_state = pdev->current_state;
+
+ dev_warn(dev, "resuming from operating state [D%d]\n",
+ device_state);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch b/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch
new file mode 100644
index 000000000..1e44aa3b8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch
@@ -0,0 +1,187 @@
+From 9e9903e8e143c32498565cb49a7aab6081734782 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Thu, 6 Dec 2018 21:34:41 +0800
+Subject: [PATCH 15/31] scsi: hisi_sas: Relocate some code to reduce complexity
+Origin: https://git.kernel.org/linus/6e1b731b535231e199c7810451c851398afccd33
+
+Relocate the codes related to dma_map/unmap in hisi_sas_task_prep() to
+reduce complexity, with a view to add DIF/DIX support.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 146 ++++++++++++++++----------
+ 1 file changed, 90 insertions(+), 56 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -297,6 +297,90 @@ static void hisi_sas_task_prep_abort(str
+ device_id, abort_flag, tag_to_abort);
+ }
+
++static void hisi_sas_dma_unmap(struct hisi_hba *hisi_hba,
++ struct sas_task *task, int n_elem,
++ int n_elem_req, int n_elem_resp)
++{
++ struct device *dev = hisi_hba->dev;
++
++ if (!sas_protocol_ata(task->task_proto)) {
++ if (task->num_scatter) {
++ if (n_elem)
++ dma_unmap_sg(dev, task->scatter,
++ task->num_scatter,
++ task->data_dir);
++ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
++ if (n_elem_req)
++ dma_unmap_sg(dev, &task->smp_task.smp_req,
++ 1, DMA_TO_DEVICE);
++ if (n_elem_resp)
++ dma_unmap_sg(dev, &task->smp_task.smp_resp,
++ 1, DMA_FROM_DEVICE);
++ }
++ }
++}
++
++static int hisi_sas_dma_map(struct hisi_hba *hisi_hba,
++ struct sas_task *task, int *n_elem,
++ int *n_elem_req, int *n_elem_resp)
++{
++ struct device *dev = hisi_hba->dev;
++ int rc;
++
++ if (sas_protocol_ata(task->task_proto)) {
++ *n_elem = task->num_scatter;
++ } else {
++ unsigned int req_len, resp_len;
++
++ if (task->num_scatter) {
++ *n_elem = dma_map_sg(dev, task->scatter,
++ task->num_scatter, task->data_dir);
++ if (!*n_elem) {
++ rc = -ENOMEM;
++ goto prep_out;
++ }
++ } else if (task->task_proto & SAS_PROTOCOL_SMP) {
++ *n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
++ 1, DMA_TO_DEVICE);
++ if (!*n_elem_req) {
++ rc = -ENOMEM;
++ goto prep_out;
++ }
++ req_len = sg_dma_len(&task->smp_task.smp_req);
++ if (req_len & 0x3) {
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++ *n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
++ 1, DMA_FROM_DEVICE);
++ if (!*n_elem_resp) {
++ rc = -ENOMEM;
++ goto err_out_dma_unmap;
++ }
++ resp_len = sg_dma_len(&task->smp_task.smp_resp);
++ if (resp_len & 0x3) {
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++ }
++ }
++
++ if (*n_elem > HISI_SAS_SGE_PAGE_CNT) {
++ dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
++ *n_elem);
++ rc = -EINVAL;
++ goto err_out_dma_unmap;
++ }
++ return 0;
++
++err_out_dma_unmap:
++ /* It would be better to call dma_unmap_sg() here, but it's messy */
++ hisi_sas_dma_unmap(hisi_hba, task, *n_elem,
++ *n_elem_req, *n_elem_resp);
++prep_out:
++ return rc;
++}
++
+ static int hisi_sas_task_prep(struct sas_task *task,
+ struct hisi_sas_dq **dq_pointer,
+ bool is_tmf, struct hisi_sas_tmf_task *tmf,
+@@ -339,49 +423,10 @@ static int hisi_sas_task_prep(struct sas
+ return -ECOMM;
+ }
+
+- if (!sas_protocol_ata(task->task_proto)) {
+- unsigned int req_len, resp_len;
+-
+- if (task->num_scatter) {
+- n_elem = dma_map_sg(dev, task->scatter,
+- task->num_scatter, task->data_dir);
+- if (!n_elem) {
+- rc = -ENOMEM;
+- goto prep_out;
+- }
+- } else if (task->task_proto & SAS_PROTOCOL_SMP) {
+- n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
+- 1, DMA_TO_DEVICE);
+- if (!n_elem_req) {
+- rc = -ENOMEM;
+- goto prep_out;
+- }
+- req_len = sg_dma_len(&task->smp_task.smp_req);
+- if (req_len & 0x3) {
+- rc = -EINVAL;
+- goto err_out_dma_unmap;
+- }
+- n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
+- 1, DMA_FROM_DEVICE);
+- if (!n_elem_resp) {
+- rc = -ENOMEM;
+- goto err_out_dma_unmap;
+- }
+- resp_len = sg_dma_len(&task->smp_task.smp_resp);
+- if (resp_len & 0x3) {
+- rc = -EINVAL;
+- goto err_out_dma_unmap;
+- }
+- }
+- } else
+- n_elem = task->num_scatter;
+-
+- if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
+- dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
+- n_elem);
+- rc = -EINVAL;
+- goto err_out_dma_unmap;
+- }
++ rc = hisi_sas_dma_map(hisi_hba, task, &n_elem,
++ &n_elem_req, &n_elem_resp);
++ if (rc < 0)
++ goto prep_out;
+
+ if (hisi_hba->hw->slot_index_alloc)
+ rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
+@@ -466,19 +511,8 @@ static int hisi_sas_task_prep(struct sas
+ err_out_tag:
+ hisi_sas_slot_index_free(hisi_hba, slot_idx);
+ err_out_dma_unmap:
+- if (!sas_protocol_ata(task->task_proto)) {
+- if (task->num_scatter) {
+- dma_unmap_sg(dev, task->scatter, task->num_scatter,
+- task->data_dir);
+- } else if (task->task_proto & SAS_PROTOCOL_SMP) {
+- if (n_elem_req)
+- dma_unmap_sg(dev, &task->smp_task.smp_req,
+- 1, DMA_TO_DEVICE);
+- if (n_elem_resp)
+- dma_unmap_sg(dev, &task->smp_task.smp_resp,
+- 1, DMA_FROM_DEVICE);
+- }
+- }
++ hisi_sas_dma_unmap(hisi_hba, task, n_elem,
++ n_elem_req, n_elem_resp);
+ prep_out:
+ dev_err(dev, "task prep: failed[%d]!\n", rc);
+ return rc;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch b/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch
new file mode 100644
index 000000000..e025687be
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch
@@ -0,0 +1,82 @@
+From 8baf75dd36d8e311434162c6a2c74a45262dc0d4 Mon Sep 17 00:00:00 2001
+From: Xiang Chen <chenxiang66@hisilicon.com>
+Date: Thu, 6 Dec 2018 21:34:42 +0800
+Subject: [PATCH 16/31] scsi: hisi_sas: Make sg_tablesize consistent value
+Origin: https://git.kernel.org/linus/6db831f4ef764ca19d7300d56ab9455af3cb930d
+
+Sht->sg_tablesize is set in the driver, and it will be assigned to
+shost->sg_tablesize in SCSI mid-layer. So it is not necessary to assign
+shost->sg_table one more time in the driver.
+
+In addition to the change, change each scsi_host_template.sg_tablesize
+to HISI_SAS_SGE_PAGE_CNT instead of SG_ALL.
+
+Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com>
+Signed-off-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 1 -
+ drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +-
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +--
+ 4 files changed, 3 insertions(+), 5 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2426,7 +2426,6 @@ int hisi_sas_probe(struct platform_devic
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+- shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+ if (hisi_hba->hw->slot_index_alloc) {
+ shost->can_queue = hisi_hba->hw->max_command_entries;
+ shost->cmd_per_lun = hisi_hba->hw->max_command_entries;
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c
+@@ -1814,7 +1814,7 @@ static struct scsi_host_template sht_v1_
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+ .this_id = -1,
+- .sg_tablesize = SG_ALL,
++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+@@ -3576,7 +3576,7 @@ static struct scsi_host_template sht_v2_
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+ .this_id = -1,
+- .sg_tablesize = SG_ALL,
++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2229,7 +2229,7 @@ static struct scsi_host_template sht_v3_
+ .change_queue_depth = sas_change_queue_depth,
+ .bios_param = sas_bios_param,
+ .this_id = -1,
+- .sg_tablesize = SG_ALL,
++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
+ .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .eh_device_reset_handler = sas_eh_device_reset_handler,
+@@ -2371,7 +2371,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ shost->max_lun = ~0;
+ shost->max_channel = 1;
+ shost->max_cmd_len = 16;
+- shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
+ shost->can_queue = hisi_hba->hw->max_command_entries -
+ HISI_SAS_RESERVED_IPTT_CNT;
+ shost->cmd_per_lun = hisi_hba->hw->max_command_entries -
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch
new file mode 100644
index 000000000..377ee58bd
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch
@@ -0,0 +1,43 @@
+From 341487a9b370af5c2566fb0c3fe5384c96bdbda7 Mon Sep 17 00:00:00 2001
+From: Huazhong Tan <tanhuazhong@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:52 +0800
+Subject: [PATCH 17/31] net: hns3: remove unnecessary configuration recapture
+ while resetting
+Origin: https://git.kernel.org/linus/b51c366df70da0100193d13975980f1990a2d47b
+
+When doing reset, it is unnecessary to get the hardware's default
+configuration again, otherwise, the user's configuration will be
+overwritten.
+
+Fixes: 4ed340ab8f49 ("net: hns3: Add reset process in hclge_main")
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -5814,19 +5814,6 @@ static int hclge_reset_ae_dev(struct hna
+ return ret;
+ }
+
+- ret = hclge_get_cap(hdev);
+- if (ret) {
+- dev_err(&pdev->dev, "get hw capability error, ret = %d.\n",
+- ret);
+- return ret;
+- }
+-
+- ret = hclge_configure(hdev);
+- if (ret) {
+- dev_err(&pdev->dev, "Configure dev error, ret = %d.\n", ret);
+- return ret;
+- }
+-
+ ret = hclge_map_tqp(hdev);
+ if (ret) {
+ dev_err(&pdev->dev, "Map tqp error, ret = %d.\n", ret);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch b/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch
new file mode 100644
index 000000000..e5141d719
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch
@@ -0,0 +1,29 @@
+From 7740fe91e657e23f25e750d9e34da059a6f607ac Mon Sep 17 00:00:00 2001
+From: Fuyun Liang <liangfuyun1@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:55 +0800
+Subject: [PATCH 18/31] net: hns3: remove 1000M/half support of phy
+Origin: https://git.kernel.org/linus/8362089d787724bb252f13f942921051943369c7
+
+Our phy does not support 1000M/half, this patch removes 1000M/half from
+PHY_SUPPORTED_FEATURES.
+
+Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+@@ -14,7 +14,7 @@
+ SUPPORTED_Asym_Pause | \
+ PHY_10BT_FEATURES | \
+ PHY_100BT_FEATURES | \
+- PHY_1000BT_FEATURES)
++ SUPPORTED_1000baseT_Full)
+
+ enum hclge_mdio_c22_op_seq {
+ HCLGE_MDIO_C22_WRITE = 1,
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch
new file mode 100644
index 000000000..6769afdcf
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch
@@ -0,0 +1,32 @@
+From 4f28c6b52ffb62eb5a0a5a85af4fa10658fecee5 Mon Sep 17 00:00:00 2001
+From: Peng Li <lipeng321@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:56 +0800
+Subject: [PATCH 19/31] net: hns3: synchronize speed and duplex from phy when
+ phy link up
+Origin: https://git.kernel.org/linus/0ad5ea5dbd6cb1e62bac547db5e61bab15af4f44
+
+Driver calls phy_connect_direct and registers hclge_mac_adjust_link
+to synchronize mac speed and duplex from phy. It is better to
+synchronize mac speed and duplex from phy when phy link up.
+
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c
+@@ -181,6 +181,10 @@ static void hclge_mac_adjust_link(struct
+ int duplex, speed;
+ int ret;
+
++ /* When phy link down, do nothing */
++ if (netdev->phydev->link == 0)
++ return;
++
+ speed = netdev->phydev->speed;
+ duplex = netdev->phydev->duplex;
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch b/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch
new file mode 100644
index 000000000..de4795be4
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch
@@ -0,0 +1,157 @@
+From caeef6247aa6f5250d14108b33cef5458ba6c58e Mon Sep 17 00:00:00 2001
+From: Yunsheng Lin <linyunsheng@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:57 +0800
+Subject: [PATCH 20/31] net: hns3: getting tx and dv buffer size through
+ firmware
+Origin: https://git.kernel.org/linus/368686be234daf365ef184a6ee1c4a6c18ede3b1
+
+This patch adds support of getting tx and dv buffer size through
+firmware, because different version of hardware requires different
+size of tx and dv buffer.
+
+This patch also add dv_buf_size to tc' private buffer size even if
+pfc is not enable for the tc.
+
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../hisilicon/hns3/hns3pf/hclge_cmd.h | 5 ++-
+ .../hisilicon/hns3/hns3pf/hclge_main.c | 41 ++++++++++++++-----
+ .../hisilicon/hns3/hns3pf/hclge_main.h | 3 ++
+ 3 files changed, 38 insertions(+), 11 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h
+@@ -365,7 +365,9 @@ struct hclge_pf_res_cmd {
+ #define HCLGE_PF_VEC_NUM_M GENMASK(7, 0)
+ __le16 pf_intr_vector_number;
+ __le16 pf_own_fun_number;
+- __le32 rsv[3];
++ __le16 tx_buf_size;
++ __le16 dv_buf_size;
++ __le32 rsv[2];
+ };
+
+ #define HCLGE_CFG_OFFSET_S 0
+@@ -791,6 +793,7 @@ struct hclge_serdes_lb_cmd {
+ #define HCLGE_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */
+ #define HCLGE_DEFAULT_DV 0xA000 /* 40k byte */
+ #define HCLGE_DEFAULT_NON_DCB_DV 0x7800 /* 30K byte */
++#define HCLGE_NON_DCB_ADDITIONAL_BUF 0x200 /* 512 byte */
+
+ #define HCLGE_TYPE_CRQ 0
+ #define HCLGE_TYPE_CSQ 1
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -931,6 +931,18 @@ static int hclge_query_pf_resource(struc
+ hdev->num_tqps = __le16_to_cpu(req->tqp_num);
+ hdev->pkt_buf_size = __le16_to_cpu(req->buf_size) << HCLGE_BUF_UNIT_S;
+
++ if (req->tx_buf_size)
++ hdev->tx_buf_size =
++ __le16_to_cpu(req->tx_buf_size) << HCLGE_BUF_UNIT_S;
++ else
++ hdev->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
++
++ if (req->dv_buf_size)
++ hdev->dv_buf_size =
++ __le16_to_cpu(req->dv_buf_size) << HCLGE_BUF_UNIT_S;
++ else
++ hdev->dv_buf_size = HCLGE_DEFAULT_DV;
++
+ if (hnae3_dev_roce_supported(hdev)) {
+ hdev->roce_base_msix_offset =
+ hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee),
+@@ -1591,9 +1603,10 @@ static bool hclge_is_rx_buf_ok(struct h
+ pfc_enable_num = hclge_get_pfc_enalbe_num(hdev);
+
+ if (hnae3_dev_dcb_supported(hdev))
+- shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV;
++ shared_buf_min = 2 * hdev->mps + hdev->dv_buf_size;
+ else
+- shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_NON_DCB_DV;
++ shared_buf_min = hdev->mps + HCLGE_NON_DCB_ADDITIONAL_BUF
++ + hdev->dv_buf_size;
+
+ shared_buf_tc = pfc_enable_num * hdev->mps +
+ (tc_num - pfc_enable_num) * hdev->mps / 2 +
+@@ -1606,8 +1619,15 @@ static bool hclge_is_rx_buf_ok(struct h
+
+ shared_buf = rx_all - rx_priv;
+ buf_alloc->s_buf.buf_size = shared_buf;
+- buf_alloc->s_buf.self.high = shared_buf;
+- buf_alloc->s_buf.self.low = 2 * hdev->mps;
++ if (hnae3_dev_dcb_supported(hdev)) {
++ buf_alloc->s_buf.self.high = shared_buf - hdev->dv_buf_size;
++ buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high
++ - hdev->mps / 2;
++ } else {
++ buf_alloc->s_buf.self.high = hdev->mps +
++ HCLGE_NON_DCB_ADDITIONAL_BUF;
++ buf_alloc->s_buf.self.low = hdev->mps / 2;
++ }
+
+ for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+ if ((hdev->hw_tc_map & BIT(i)) &&
+@@ -1634,11 +1654,11 @@ static int hclge_tx_buffer_calc(struct h
+ for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+ struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i];
+
+- if (total_size < HCLGE_DEFAULT_TX_BUF)
++ if (total_size < hdev->tx_buf_size)
+ return -ENOMEM;
+
+ if (hdev->hw_tc_map & BIT(i))
+- priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
++ priv->tx_buf_size = hdev->tx_buf_size;
+ else
+ priv->tx_buf_size = 0;
+
+@@ -1684,11 +1704,12 @@ static int hclge_rx_buffer_calc(struct h
+ priv->wl.low = aligned_mps;
+ priv->wl.high = priv->wl.low + aligned_mps;
+ priv->buf_size = priv->wl.high +
+- HCLGE_DEFAULT_DV;
++ hdev->dv_buf_size;
+ } else {
+ priv->wl.low = 0;
+ priv->wl.high = 2 * aligned_mps;
+- priv->buf_size = priv->wl.high;
++ priv->buf_size = priv->wl.high +
++ hdev->dv_buf_size;
+ }
+ } else {
+ priv->enable = 0;
+@@ -1720,11 +1741,11 @@ static int hclge_rx_buffer_calc(struct h
+ if (hdev->tm_info.hw_pfc_map & BIT(i)) {
+ priv->wl.low = 128;
+ priv->wl.high = priv->wl.low + aligned_mps;
+- priv->buf_size = priv->wl.high + HCLGE_DEFAULT_DV;
++ priv->buf_size = priv->wl.high + hdev->dv_buf_size;
+ } else {
+ priv->wl.low = 0;
+ priv->wl.high = aligned_mps;
+- priv->buf_size = priv->wl.high;
++ priv->buf_size = priv->wl.high + hdev->dv_buf_size;
+ }
+ }
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
+@@ -545,6 +545,9 @@ struct hclge_dev {
+ u32 flag;
+
+ u32 pkt_buf_size; /* Total pf buf size for tx/rx */
++ u32 tx_buf_size; /* Tx buffer size for each TC */
++ u32 dv_buf_size; /* Dv buffer size for each TC */
++
+ u32 mps; /* Max packet size */
+
+ enum hclge_mta_dmac_sel_type mta_mac_sel_type;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch b/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch
new file mode 100644
index 000000000..e5c403de9
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch
@@ -0,0 +1,144 @@
+From 234c314e892d40daa37e97e9057e04d3e3a0c285 Mon Sep 17 00:00:00 2001
+From: Yunsheng Lin <linyunsheng@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:58 +0800
+Subject: [PATCH 21/31] net: hns3: aligning buffer size in SSU to 256 bytes
+Origin: https://git.kernel.org/linus/b9a400ac295728b2d47445e09814e1880409b311
+
+The hardware expects the buffer size set to SSU is aligned to
+256 bytes, this patch aligns the buffer size to 256 byte using
+roundup or rounddown function.
+
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../hisilicon/hns3/hns3pf/hclge_main.c | 45 ++++++++++++-------
+ 1 file changed, 28 insertions(+), 17 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -31,6 +31,10 @@ static int hclge_set_mta_filter_mode(str
+ enum hclge_mta_dmac_sel_type mta_mac_sel,
+ bool enable);
+ static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu);
++
++#define HCLGE_BUF_SIZE_UNIT 256
++
++static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps);
+ static int hclge_init_vlan_config(struct hclge_dev *hdev);
+ static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev);
+
+@@ -937,12 +941,16 @@ static int hclge_query_pf_resource(struc
+ else
+ hdev->tx_buf_size = HCLGE_DEFAULT_TX_BUF;
+
++ hdev->tx_buf_size = roundup(hdev->tx_buf_size, HCLGE_BUF_SIZE_UNIT);
++
+ if (req->dv_buf_size)
+ hdev->dv_buf_size =
+ __le16_to_cpu(req->dv_buf_size) << HCLGE_BUF_UNIT_S;
+ else
+ hdev->dv_buf_size = HCLGE_DEFAULT_DV;
+
++ hdev->dv_buf_size = roundup(hdev->dv_buf_size, HCLGE_BUF_SIZE_UNIT);
++
+ if (hnae3_dev_roce_supported(hdev)) {
+ hdev->roce_base_msix_offset =
+ hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee),
+@@ -1595,48 +1603,50 @@ static bool hclge_is_rx_buf_ok(struct h
+ {
+ u32 shared_buf_min, shared_buf_tc, shared_std;
+ int tc_num, pfc_enable_num;
+- u32 shared_buf;
++ u32 shared_buf, aligned_mps;
+ u32 rx_priv;
+ int i;
+
+ tc_num = hclge_get_tc_num(hdev);
+ pfc_enable_num = hclge_get_pfc_enalbe_num(hdev);
++ aligned_mps = roundup(hdev->mps, HCLGE_BUF_SIZE_UNIT);
+
+ if (hnae3_dev_dcb_supported(hdev))
+- shared_buf_min = 2 * hdev->mps + hdev->dv_buf_size;
++ shared_buf_min = 2 * aligned_mps + hdev->dv_buf_size;
+ else
+- shared_buf_min = hdev->mps + HCLGE_NON_DCB_ADDITIONAL_BUF
++ shared_buf_min = aligned_mps + HCLGE_NON_DCB_ADDITIONAL_BUF
+ + hdev->dv_buf_size;
+
+- shared_buf_tc = pfc_enable_num * hdev->mps +
+- (tc_num - pfc_enable_num) * hdev->mps / 2 +
+- hdev->mps;
++ shared_buf_tc = pfc_enable_num * aligned_mps +
++ (tc_num - pfc_enable_num) * aligned_mps / 2 +
++ aligned_mps;
+ shared_std = max_t(u32, shared_buf_min, shared_buf_tc);
+
+ rx_priv = hclge_get_rx_priv_buff_alloced(buf_alloc);
+ if (rx_all <= rx_priv + shared_std)
+ return false;
+
+- shared_buf = rx_all - rx_priv;
++ shared_buf = rounddown(rx_all - rx_priv, HCLGE_BUF_SIZE_UNIT);
+ buf_alloc->s_buf.buf_size = shared_buf;
+ if (hnae3_dev_dcb_supported(hdev)) {
+ buf_alloc->s_buf.self.high = shared_buf - hdev->dv_buf_size;
+ buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high
+- - hdev->mps / 2;
++ - roundup(aligned_mps / 2, HCLGE_BUF_SIZE_UNIT);
+ } else {
+- buf_alloc->s_buf.self.high = hdev->mps +
++ buf_alloc->s_buf.self.high = aligned_mps +
+ HCLGE_NON_DCB_ADDITIONAL_BUF;
+- buf_alloc->s_buf.self.low = hdev->mps / 2;
++ buf_alloc->s_buf.self.low =
++ roundup(aligned_mps / 2, HCLGE_BUF_SIZE_UNIT);
+ }
+
+ for (i = 0; i < HCLGE_MAX_TC_NUM; i++) {
+ if ((hdev->hw_tc_map & BIT(i)) &&
+ (hdev->tm_info.hw_pfc_map & BIT(i))) {
+- buf_alloc->s_buf.tc_thrd[i].low = hdev->mps;
+- buf_alloc->s_buf.tc_thrd[i].high = 2 * hdev->mps;
++ buf_alloc->s_buf.tc_thrd[i].low = aligned_mps;
++ buf_alloc->s_buf.tc_thrd[i].high = 2 * aligned_mps;
+ } else {
+ buf_alloc->s_buf.tc_thrd[i].low = 0;
+- buf_alloc->s_buf.tc_thrd[i].high = hdev->mps;
++ buf_alloc->s_buf.tc_thrd[i].high = aligned_mps;
+ }
+ }
+
+@@ -1676,7 +1686,6 @@ static int hclge_tx_buffer_calc(struct h
+ static int hclge_rx_buffer_calc(struct hclge_dev *hdev,
+ struct hclge_pkt_buf_alloc *buf_alloc)
+ {
+-#define HCLGE_BUF_SIZE_UNIT 128
+ u32 rx_all = hdev->pkt_buf_size, aligned_mps;
+ int no_pfc_priv_num, pfc_priv_num;
+ struct hclge_priv_buf *priv;
+@@ -1702,9 +1711,11 @@ static int hclge_rx_buffer_calc(struct h
+ priv->enable = 1;
+ if (hdev->tm_info.hw_pfc_map & BIT(i)) {
+ priv->wl.low = aligned_mps;
+- priv->wl.high = priv->wl.low + aligned_mps;
++ priv->wl.high =
++ roundup(priv->wl.low + aligned_mps,
++ HCLGE_BUF_SIZE_UNIT);
+ priv->buf_size = priv->wl.high +
+- hdev->dv_buf_size;
++ hdev->dv_buf_size;
+ } else {
+ priv->wl.low = 0;
+ priv->wl.high = 2 * aligned_mps;
+@@ -1739,7 +1750,7 @@ static int hclge_rx_buffer_calc(struct h
+ priv->enable = 1;
+
+ if (hdev->tm_info.hw_pfc_map & BIT(i)) {
+- priv->wl.low = 128;
++ priv->wl.low = 256;
+ priv->wl.high = priv->wl.low + aligned_mps;
+ priv->buf_size = priv->wl.high + hdev->dv_buf_size;
+ } else {
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch b/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch
new file mode 100644
index 000000000..26cee78ea
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch
@@ -0,0 +1,45 @@
+From 4d887b7901d59b472df97bd8a2f8bdeb43be7ced Mon Sep 17 00:00:00 2001
+From: Yunsheng Lin <linyunsheng@huawei.com>
+Date: Tue, 18 Dec 2018 19:37:59 +0800
+Subject: [PATCH 22/31] net: hns3: fix a SSU buffer checking bug
+Origin: https://git.kernel.org/linus/af854724e51e4047f534ac6d19b3ef9fb3c35c49
+
+When caculating the SSU buffer, it first allocate tx and
+rx private buffer, then the remaining buffer is for rx
+shared buffer. The remaining buffer size should be at
+least bigger than or equal to the shared_std, which is the
+minimum shared buffer size required by the driver, but
+currently if the remaining buffer size is equal to the
+shared_std, it returns failure, which causes SSU buffer
+allocation failure problem.
+
+This patch fixes this problem by rounding up shared_std before
+checking the the remaining buffer size bigger than or equal to
+the shared_std.
+
+Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support")
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -1620,10 +1620,11 @@ static bool hclge_is_rx_buf_ok(struct h
+ shared_buf_tc = pfc_enable_num * aligned_mps +
+ (tc_num - pfc_enable_num) * aligned_mps / 2 +
+ aligned_mps;
+- shared_std = max_t(u32, shared_buf_min, shared_buf_tc);
++ shared_std = roundup(max_t(u32, shared_buf_min, shared_buf_tc),
++ HCLGE_BUF_SIZE_UNIT);
+
+ rx_priv = hclge_get_rx_priv_buff_alloced(buf_alloc);
+- if (rx_all <= rx_priv + shared_std)
++ if (rx_all < rx_priv + shared_std)
+ return false;
+
+ shared_buf = rounddown(rx_all - rx_priv, HCLGE_BUF_SIZE_UNIT);
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch b/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch
new file mode 100644
index 000000000..ad8ccd77f
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch
@@ -0,0 +1,30 @@
+From ea3eff7a2ef69730c8e48715fbf965cb9da8b0bc Mon Sep 17 00:00:00 2001
+From: Jian Shen <shenjian15@huawei.com>
+Date: Thu, 20 Dec 2018 11:51:59 +0800
+Subject: [PATCH 23/31] net: hns3: change default tc state to close
+Origin: https://git.kernel.org/linus/a298797532d9dc244abf349d7c2ed063732c6ba3
+
+In original codes, default tc value is set to the max tc. It's more
+reasonable to close tc by changing default tc value to 1. Users can
+enable it with lldp tool when they want to use tc.
+
+Signed-off-by: Jian Shen <shenjian15@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
+@@ -1200,7 +1200,7 @@ static int hclge_configure(struct hclge_
+ hdev->pfc_max = hdev->tc_max;
+ }
+
+- hdev->tm_info.num_tc = hdev->tc_max;
++ hdev->tm_info.num_tc = 1;
+
+ /* Currently not support uncontiuous tc */
+ for (i = 0; i < hdev->tm_info.num_tc; i++)
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch b/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch
new file mode 100644
index 000000000..b3c3464ca
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch
@@ -0,0 +1,39 @@
+From 0f27af14383edac1efaf140d7cbe2d7dfdab7318 Mon Sep 17 00:00:00 2001
+From: Peng Li <lipeng321@huawei.com>
+Date: Thu, 20 Dec 2018 11:52:00 +0800
+Subject: [PATCH 24/31] net: hns3: fix a bug caused by udelay
+Origin: https://git.kernel.org/linus/1b7d7b0581173219b82abbd81c88cf8aa7d402c2
+
+udelay() in driver may always occupancy processor. If there is only
+one cpu in system, the VF driver may initialize fail when insmod
+PF and VF driver in the same system. This patch use msleep() to free
+cpu when VF wait PF message.
+
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c
+@@ -26,7 +26,7 @@ static int hclgevf_get_mbx_resp(struct h
+ u8 *resp_data, u16 resp_len)
+ {
+ #define HCLGEVF_MAX_TRY_TIMES 500
+-#define HCLGEVF_SLEEP_USCOEND 1000
++#define HCLGEVF_SLEEP_USECOND 1000
+ struct hclgevf_mbx_resp_status *mbx_resp;
+ u16 r_code0, r_code1;
+ int i = 0;
+@@ -40,7 +40,7 @@ static int hclgevf_get_mbx_resp(struct h
+ }
+
+ while ((!hdev->mbx_resp.received_resp) && (i < HCLGEVF_MAX_TRY_TIMES)) {
+- udelay(HCLGEVF_SLEEP_USCOEND);
++ usleep_range(HCLGEVF_SLEEP_USECOND, HCLGEVF_SLEEP_USECOND * 2);
+ i++;
+ }
+
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch b/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch
new file mode 100644
index 000000000..2dcf9f2ef
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch
@@ -0,0 +1,28 @@
+From 883a7a53d7f6a6494e3a0df73fb02f76ecc42bc1 Mon Sep 17 00:00:00 2001
+From: Peng Li <lipeng321@huawei.com>
+Date: Thu, 20 Dec 2018 11:52:06 +0800
+Subject: [PATCH 25/31] net: hns3: remove redundant variable initialization
+Origin: https://git.kernel.org/linus/1154bb26c879fea51c20aee167ddce4345caa255
+
+This patch removes the redundant variable initialization,
+as driver will devm_kzalloc to set value to hdev soon.
+
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+@@ -1360,7 +1360,7 @@ static int hclgevf_configure(struct hclg
+ static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev)
+ {
+ struct pci_dev *pdev = ae_dev->pdev;
+- struct hclgevf_dev *hdev = ae_dev->priv;
++ struct hclgevf_dev *hdev;
+
+ hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL);
+ if (!hdev)
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch b/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch
new file mode 100644
index 000000000..9eddea483
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch
@@ -0,0 +1,46 @@
+From a4e5945057386872cb9add271aea76ca2413f481 Mon Sep 17 00:00:00 2001
+From: Huazhong Tan <tanhuazhong@huawei.com>
+Date: Mon, 31 Dec 2018 10:58:29 +0800
+Subject: [PATCH 26/31] net: hns3: call hns3_nic_net_open() while doing
+ HNAE3_UP_CLIENT
+Origin: https://git.kernel.org/linus/e888402789b9db5de4fcda361331d66dbf0cd9fd
+
+For HNAE3_DOWN_CLIENT calling hns3_nic_net_stop(), HNAE3_UP_CLIENT
+should call hns3_nic_net_open(), since if the number of queue or
+the map of TC has is changed before HHAE3_UP_CLIENT is called,
+it will cause problem.
+
+Also the HNS3_NIC_STATE_RESETTING flag needs to be cleared before
+hns3_nic_net_open() called, and set it back while hns3_nic_net_open()
+failed.
+
+Fixes: bb6b94a896d4 ("net: hns3: Add reset interface implementation in client")
+Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
+Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
+Signed-off-by: Peng Li <lipeng321@huawei.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
+@@ -3439,11 +3439,15 @@ static int hns3_reset_notify_down_enet(s
+ static int hns3_reset_notify_up_enet(struct hnae3_handle *handle)
+ {
+ struct hnae3_knic_private_info *kinfo = &handle->kinfo;
++ struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev);
+ int ret = 0;
+
++ clear_bit(HNS3_NIC_STATE_RESETTING, &priv->state);
++
+ if (netif_running(kinfo->netdev)) {
+- ret = hns3_nic_net_up(kinfo->netdev);
++ ret = hns3_nic_net_open(kinfo->netdev);
+ if (ret) {
++ set_bit(HNS3_NIC_STATE_RESETTING, &priv->state);
+ netdev_err(kinfo->netdev,
+ "hns net up fail, ret=%d!\n", ret);
+ return ret;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch
new file mode 100644
index 000000000..48e2022bd
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch
@@ -0,0 +1,43 @@
+From 84193e72c505286e4681b3c566c64eea3e25f7fd Mon Sep 17 00:00:00 2001
+From: Lijun Ou <oulijun@huawei.com>
+Date: Wed, 12 Dec 2018 17:49:08 +0800
+Subject: [PATCH 29/31] RDMA/hns: Add constraint on the setting of local ACK
+ timeout
+Origin: https://git.kernel.org/linus/44754b95dd35ee07c462b5425ae9c4cde8c7e7c8
+
+According to IB protocol, local ACK timeout shall be a 5 bit
+value. Currently, hip08 could not support the possible max value 31. Fail
+the request in this case.
+
+Signed-off-by: Yixian Liu <liuyixian@huawei.com>
+Signed-off-by: Lijun Ou <oulijun@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+Index: linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+===================================================================
+--- linux.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -3398,10 +3398,16 @@ static int modify_qp_rtr_to_rts(struct i
+ V2_QPC_BYTE_212_LSN_S, 0);
+
+ if (attr_mask & IB_QP_TIMEOUT) {
+- roce_set_field(context->byte_28_at_fl, V2_QPC_BYTE_28_AT_M,
+- V2_QPC_BYTE_28_AT_S, attr->timeout);
+- roce_set_field(qpc_mask->byte_28_at_fl, V2_QPC_BYTE_28_AT_M,
+- V2_QPC_BYTE_28_AT_S, 0);
++ if (attr->timeout < 31) {
++ roce_set_field(context->byte_28_at_fl,
++ V2_QPC_BYTE_28_AT_M, V2_QPC_BYTE_28_AT_S,
++ attr->timeout);
++ roce_set_field(qpc_mask->byte_28_at_fl,
++ V2_QPC_BYTE_28_AT_M, V2_QPC_BYTE_28_AT_S,
++ 0);
++ } else {
++ dev_warn(dev, "Local ACK timeout shall be 0 to 30.\n");
++ }
+ }
+
+ roce_set_field(context->byte_172_sq_psn, V2_QPC_BYTE_172_SQ_CUR_PSN_M,
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch b/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch
new file mode 100644
index 000000000..612b481ff
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch
@@ -0,0 +1,28 @@
+From 454bc02382f8ed2eb3ebc7db4867ed419e3f0241 Mon Sep 17 00:00:00 2001
+From: Lijun Ou <oulijun@huawei.com>
+Date: Wed, 12 Dec 2018 17:49:09 +0800
+Subject: [PATCH 30/31] RDMA/hns: Modify the pbl ba page size for hip08
+Origin: https://git.kernel.org/linus/91fb4d83b88a7b544ce564c44167aad29d4154f0
+
+Modify the pbl ba page size to 16K for in order to support 4G MR size.
+
+Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com>
+Signed-off-by: Lijun Ou <oulijun@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+===================================================================
+--- linux.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
++++ linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c
+@@ -1235,7 +1235,7 @@ static int hns_roce_v2_profile(struct hn
+ caps->mpt_ba_pg_sz = 0;
+ caps->mpt_buf_pg_sz = 0;
+ caps->mpt_hop_num = HNS_ROCE_CONTEXT_HOP_NUM;
+- caps->pbl_ba_pg_sz = 0;
++ caps->pbl_ba_pg_sz = 2;
+ caps->pbl_buf_pg_sz = 0;
+ caps->pbl_hop_num = HNS_ROCE_PBL_HOP_NUM;
+ caps->mtt_ba_pg_sz = 0;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch b/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch
new file mode 100644
index 000000000..4f9e5f6be
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch
@@ -0,0 +1,63 @@
+From 07a7830061e657ce352e690dbe0a794ffb10d22e Mon Sep 17 00:00:00 2001
+From: Lijun Ou <oulijun@huawei.com>
+Date: Sat, 12 Jan 2019 18:36:29 +0800
+Subject: [PATCH 31/31] RDMA/hns: RDMA/hns: Assign rq head pointer when enable
+ rq record db
+Origin: https://git.kernel.org/linus/de77503a59403e7045c18c6bb0a10c245a99b648
+
+When flush cqe, it needs to get the pointer of rq and sq from db address
+space of user and update it into qp context by modified qp. if rq does not
+exist, it will not get the value from db address space of user.
+
+Signed-off-by: Lijun Ou <oulijun@huawei.com>
+Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
+---
+ drivers/infiniband/hw/hns/hns_roce_qp.c | 19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+Index: linux/drivers/infiniband/hw/hns/hns_roce_qp.c
+===================================================================
+--- linux.orig/drivers/infiniband/hw/hns/hns_roce_qp.c
++++ linux/drivers/infiniband/hw/hns/hns_roce_qp.c
+@@ -652,6 +652,10 @@ static int hns_roce_create_qp_common(str
+ dev_err(dev, "rq record doorbell map failed!\n");
+ goto err_sq_dbmap;
+ }
++
++ /* indicate kernel supports rq record db */
++ resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB;
++ hr_qp->rdb_en = 1;
+ }
+ } else {
+ if (init_attr->create_flags &
+@@ -760,16 +764,11 @@ static int hns_roce_create_qp_common(str
+ else
+ hr_qp->doorbell_qpn = cpu_to_le64(hr_qp->qpn);
+
+- if (ib_pd->uobject && (udata->outlen >= sizeof(resp)) &&
+- (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)) {
+-
+- /* indicate kernel supports rq record db */
+- resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB;
+- ret = ib_copy_to_udata(udata, &resp, sizeof(resp));
++ if (udata) {
++ ret = ib_copy_to_udata(udata, &resp,
++ min(udata->outlen, sizeof(resp)));
+ if (ret)
+ goto err_qp;
+-
+- hr_qp->rdb_en = 1;
+ }
+ hr_qp->event = hns_roce_ib_qp_event;
+
+@@ -946,7 +945,9 @@ int hns_roce_modify_qp(struct ib_qp *ibq
+ (attr_mask & IB_QP_STATE) && new_state == IB_QPS_ERR) {
+ if (hr_qp->sdb_en == 1) {
+ hr_qp->sq.head = *(int *)(hr_qp->sdb.virt_addr);
+- hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr);
++
++ if (hr_qp->rdb_en == 1)
++ hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr);
+ } else {
+ dev_warn(dev, "flush cqe is not supported in userspace!\n");
+ goto out;
diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch b/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch
new file mode 100644
index 000000000..68374aee8
--- /dev/null
+++ b/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch
@@ -0,0 +1,70 @@
+From badecc38102204f5297ad6ce1d7c7875e514c6f7 Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Mon, 18 Feb 2019 08:34:25 +0100
+Subject: [PATCH] scsi: hisi_sas: fix calls to dma_set_mask_and_coherent()
+Origin: https://git.kernel.org/linus/d9a00459effc30f6de2cdd887b64f15c6c54ae71
+
+The change to use dma_set_mask_and_coherent() incorrectly made a second
+call with the 32 bit DMA mask value when the call with the 64 bit DMA
+mask value succeeded.
+
+[mkp: fixed commit message]
+
+Fixes: e4db40e7a1a2 ("scsi: hisi_sas: use dma_set_mask_and_coherent")
+Cc: <stable@vger.kernel.org>
+Suggested-by: Ewan D. Milne <emilne@redhat.com>
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Hannes Reinecke <hare@suse.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+---
+ drivers/scsi/hisi_sas/hisi_sas_main.c | 8 ++++++--
+ drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 +++++---
+ 2 files changed, 11 insertions(+), 5 deletions(-)
+
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c
+@@ -2339,6 +2339,7 @@ static struct Scsi_Host *hisi_sas_shost_
+ struct Scsi_Host *shost;
+ struct hisi_hba *hisi_hba;
+ struct device *dev = &pdev->dev;
++ int error;
+
+ shost = scsi_host_alloc(hw->sht, sizeof(*hisi_hba));
+ if (!shost) {
+@@ -2359,8 +2360,11 @@ static struct Scsi_Host *hisi_sas_shost_
+ if (hisi_sas_get_fw_info(hisi_hba) < 0)
+ goto err_out;
+
+- if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) &&
+- dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) {
++ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
++ if (error)
++ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
++
++ if (error) {
+ dev_err(dev, "No usable DMA addressing method\n");
+ goto err_out;
+ }
+Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+===================================================================
+--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+@@ -2328,10 +2328,12 @@ hisi_sas_v3_probe(struct pci_dev *pdev,
+ if (rc)
+ goto err_out_disable_device;
+
+- if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
+- dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
++ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
++ if (rc)
++ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
++ if (rc) {
+ dev_err(dev, "No usable DMA addressing method\n");
+- rc = -EIO;
++ rc = -ENODEV;
+ goto err_out_regions;
+ }
+
diff --git a/debian/patches/bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch b/debian/patches/bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch
new file mode 100644
index 000000000..b45fc948b
--- /dev/null
+++ b/debian/patches/bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch
@@ -0,0 +1,387 @@
+From: Huacai Chen <chenhc@lemote.com>
+Date: Tue, 15 Jan 2019 16:04:54 +0800
+Subject: MIPS: Loongson: Introduce and use loongson_llsc_mb()
+Origin: https://git.kernel.org/linus/e02e07e3127d8aec1f4bcdfb2fc52a2d99b4859e
+
+On the Loongson-2G/2H/3A/3B there is a hardware flaw that ll/sc and
+lld/scd is very weak ordering. We should add sync instructions "before
+each ll/lld" and "at the branch-target between ll/sc" to workaround.
+Otherwise, this flaw will cause deadlock occasionally (e.g. when doing
+heavy load test with LTP).
+
+Below is the explaination of CPU designer:
+
+"For Loongson 3 family, when a memory access instruction (load, store,
+or prefetch)'s executing occurs between the execution of LL and SC, the
+success or failure of SC is not predictable. Although programmer would
+not insert memory access instructions between LL and SC, the memory
+instructions before LL in program-order, may dynamically executed
+between the execution of LL/SC, so a memory fence (SYNC) is needed
+before LL/LLD to avoid this situation.
+
+Since Loongson-3A R2 (3A2000), we have improved our hardware design to
+handle this case. But we later deduce a rarely circumstance that some
+speculatively executed memory instructions due to branch misprediction
+between LL/SC still fall into the above case, so a memory fence (SYNC)
+at branch-target (if its target is not between LL/SC) is needed for
+Loongson 3A1000, 3B1500, 3A2000 and 3A3000.
+
+Our processor is continually evolving and we aim to to remove all these
+workaround-SYNCs around LL/SC for new-come processor."
+
+Here is an example:
+
+Both cpu1 and cpu2 simutaneously run atomic_add by 1 on same atomic var,
+this bug cause both 'sc' run by two cpus (in atomic_add) succeed at same
+time('sc' return 1), and the variable is only *added by 1*, sometimes,
+which is wrong and unacceptable(it should be added by 2).
+
+Why disable fix-loongson3-llsc in compiler?
+Because compiler fix will cause problems in kernel's __ex_table section.
+
+This patch fix all the cases in kernel, but:
+
++. the fix at the end of futex_atomic_cmpxchg_inatomic is for branch-target
+of 'bne', there other cases which smp_mb__before_llsc() and smp_llsc_mb() fix
+the ll and branch-target coincidently such as atomic_sub_if_positive/
+cmpxchg/xchg, just like this one.
+
++. Loongson 3 does support CONFIG_EDAC_ATOMIC_SCRUB, so no need to touch
+edac.h
+
++. local_ops and cmpxchg_local should not be affected by this bug since
+only the owner can write.
+
++. mips_atomic_set for syscall.c is deprecated and rarely used, just let
+it go
+
+Signed-off-by: Huacai Chen <chenhc@lemote.com>
+Signed-off-by: Huang Pei <huangpei@loongson.cn>
+[paul.burton@mips.com:
+ - Simplify the addition of -mno-fix-loongson3-llsc to cflags, and add
+ a comment describing why it's there.
+ - Make loongson_llsc_mb() a no-op when
+ CONFIG_CPU_LOONGSON3_WORKAROUNDS=n, rather than a compiler memory
+ barrier.
+ - Add a comment describing the bug & how loongson_llsc_mb() helps
+ in asm/barrier.h.]
+Signed-off-by: Paul Burton <paul.burton@mips.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: ambrosehua@gmail.com
+Cc: Steven J . Hill <Steven.Hill@cavium.com>
+Cc: linux-mips@linux-mips.org
+Cc: Fuxin Zhang <zhangfx@lemote.com>
+Cc: Zhangjin Wu <wuzhangjin@gmail.com>
+Cc: Li Xuefeng <lixuefeng@loongson.cn>
+Cc: Xu Chenghua <xuchenghua@loongson.cn>
+---
+ arch/mips/Kconfig | 15 +++++++++++++++
+ arch/mips/include/asm/atomic.h | 6 ++++++
+ arch/mips/include/asm/barrier.h | 36 ++++++++++++++++++++++++++++++++++++
+ arch/mips/include/asm/bitops.h | 5 +++++
+ arch/mips/include/asm/futex.h | 3 +++
+ arch/mips/include/asm/pgtable.h | 2 ++
+ arch/mips/loongson64/Platform | 23 +++++++++++++++++++++++
+ arch/mips/mm/tlbex.c | 10 ++++++++++
+ 8 files changed, 100 insertions(+)
+
+Index: linux/arch/mips/Kconfig
+===================================================================
+--- linux.orig/arch/mips/Kconfig
++++ linux/arch/mips/Kconfig
+@@ -1397,6 +1397,21 @@ config LOONGSON3_ENHANCEMENT
+ please say 'N' here. If you want a high-performance kernel to run on
+ new Loongson 3 machines only, please say 'Y' here.
+
++config CPU_LOONGSON3_WORKAROUNDS
++ bool "Old Loongson 3 LLSC Workarounds"
++ default y if SMP
++ depends on CPU_LOONGSON3
++ help
++ Loongson 3 processors have the llsc issues which require workarounds.
++ Without workarounds the system may hang unexpectedly.
++
++ Newer Loongson 3 will fix these issues and no workarounds are needed.
++ The workarounds have no significant side effect on them but may
++ decrease the performance of the system so this option should be
++ disabled unless the kernel is intended to be run on old systems.
++
++ If unsure, please say Y.
++
+ config CPU_LOONGSON2E
+ bool "Loongson 2E"
+ depends on SYS_HAS_CPU_LOONGSON2E
+Index: linux/arch/mips/include/asm/atomic.h
+===================================================================
+--- linux.orig/arch/mips/include/asm/atomic.h
++++ linux/arch/mips/include/asm/atomic.h
+@@ -58,6 +58,7 @@ static __inline__ void atomic_##op(int i
+ if (kernel_uses_llsc) { \
+ int temp; \
+ \
++ loongson_llsc_mb(); \
+ __asm__ __volatile__( \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ "1: ll %0, %1 # atomic_" #op " \n" \
+@@ -84,6 +85,7 @@ static __inline__ int atomic_##op##_retu
+ if (kernel_uses_llsc) { \
+ int temp; \
+ \
++ loongson_llsc_mb(); \
+ __asm__ __volatile__( \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ "1: ll %1, %2 # atomic_" #op "_return \n" \
+@@ -116,6 +118,7 @@ static __inline__ int atomic_fetch_##op#
+ if (kernel_uses_llsc) { \
+ int temp; \
+ \
++ loongson_llsc_mb(); \
+ __asm__ __volatile__( \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ "1: ll %1, %2 # atomic_fetch_" #op " \n" \
+@@ -251,6 +254,7 @@ static __inline__ void atomic64_##op(lon
+ if (kernel_uses_llsc) { \
+ long temp; \
+ \
++ loongson_llsc_mb(); \
+ __asm__ __volatile__( \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ "1: lld %0, %1 # atomic64_" #op " \n" \
+@@ -277,6 +281,7 @@ static __inline__ long atomic64_##op##_r
+ if (kernel_uses_llsc) { \
+ long temp; \
+ \
++ loongson_llsc_mb(); \
+ __asm__ __volatile__( \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ "1: lld %1, %2 # atomic64_" #op "_return\n" \
+@@ -309,6 +314,7 @@ static __inline__ long atomic64_fetch_##
+ if (kernel_uses_llsc) { \
+ long temp; \
+ \
++ loongson_llsc_mb(); \
+ __asm__ __volatile__( \
+ " .set "MIPS_ISA_LEVEL" \n" \
+ "1: lld %1, %2 # atomic64_fetch_" #op "\n" \
+Index: linux/arch/mips/include/asm/barrier.h
+===================================================================
+--- linux.orig/arch/mips/include/asm/barrier.h
++++ linux/arch/mips/include/asm/barrier.h
+@@ -222,6 +222,42 @@
+ #define __smp_mb__before_atomic() __smp_mb__before_llsc()
+ #define __smp_mb__after_atomic() smp_llsc_mb()
+
++/*
++ * Some Loongson 3 CPUs have a bug wherein execution of a memory access (load,
++ * store or pref) in between an ll & sc can cause the sc instruction to
++ * erroneously succeed, breaking atomicity. Whilst it's unusual to write code
++ * containing such sequences, this bug bites harder than we might otherwise
++ * expect due to reordering & speculation:
++ *
++ * 1) A memory access appearing prior to the ll in program order may actually
++ * be executed after the ll - this is the reordering case.
++ *
++ * In order to avoid this we need to place a memory barrier (ie. a sync
++ * instruction) prior to every ll instruction, in between it & any earlier
++ * memory access instructions. Many of these cases are already covered by
++ * smp_mb__before_llsc() but for the remaining cases, typically ones in
++ * which multiple CPUs may operate on a memory location but ordering is not
++ * usually guaranteed, we use loongson_llsc_mb() below.
++ *
++ * This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later.
++ *
++ * 2) If a conditional branch exists between an ll & sc with a target outside
++ * of the ll-sc loop, for example an exit upon value mismatch in cmpxchg()
++ * or similar, then misprediction of the branch may allow speculative
++ * execution of memory accesses from outside of the ll-sc loop.
++ *
++ * In order to avoid this we need a memory barrier (ie. a sync instruction)
++ * at each affected branch target, for which we also use loongson_llsc_mb()
++ * defined below.
++ *
++ * This case affects all current Loongson 3 CPUs.
++ */
++#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */
++#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
++#else
++#define loongson_llsc_mb() do { } while (0)
++#endif
++
+ #include <asm-generic/barrier.h>
+
+ #endif /* __ASM_BARRIER_H */
+Index: linux/arch/mips/include/asm/bitops.h
+===================================================================
+--- linux.orig/arch/mips/include/asm/bitops.h
++++ linux/arch/mips/include/asm/bitops.h
+@@ -68,6 +68,7 @@ static inline void set_bit(unsigned long
+ : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m));
+ #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
+ } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
++ loongson_llsc_mb();
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # set_bit \n"
+@@ -78,6 +79,7 @@ static inline void set_bit(unsigned long
+ } while (unlikely(!temp));
+ #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
+ } else if (kernel_uses_llsc) {
++ loongson_llsc_mb();
+ do {
+ __asm__ __volatile__(
+ " .set "MIPS_ISA_ARCH_LEVEL" \n"
+@@ -120,6 +122,7 @@ static inline void clear_bit(unsigned lo
+ : "ir" (~(1UL << bit)));
+ #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6)
+ } else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
++ loongson_llsc_mb();
+ do {
+ __asm__ __volatile__(
+ " " __LL "%0, %1 # clear_bit \n"
+@@ -130,6 +133,7 @@ static inline void clear_bit(unsigned lo
+ } while (unlikely(!temp));
+ #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
+ } else if (kernel_uses_llsc) {
++ loongson_llsc_mb();
+ do {
+ __asm__ __volatile__(
+ " .set "MIPS_ISA_ARCH_LEVEL" \n"
+@@ -188,6 +192,7 @@ static inline void change_bit(unsigned l
+ unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG);
+ unsigned long temp;
+
++ loongson_llsc_mb();
+ do {
+ __asm__ __volatile__(
+ " .set "MIPS_ISA_ARCH_LEVEL" \n"
+Index: linux/arch/mips/include/asm/futex.h
+===================================================================
+--- linux.orig/arch/mips/include/asm/futex.h
++++ linux/arch/mips/include/asm/futex.h
+@@ -50,6 +50,7 @@
+ "i" (-EFAULT) \
+ : "memory"); \
+ } else if (cpu_has_llsc) { \
++ loongson_llsc_mb(); \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+@@ -162,6 +163,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval,
+ "i" (-EFAULT)
+ : "memory");
+ } else if (cpu_has_llsc) {
++ loongson_llsc_mb();
+ __asm__ __volatile__(
+ "# futex_atomic_cmpxchg_inatomic \n"
+ " .set push \n"
+@@ -190,6 +192,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval,
+ : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
+ "i" (-EFAULT)
+ : "memory");
++ loongson_llsc_mb();
+ } else
+ return -ENOSYS;
+
+Index: linux/arch/mips/include/asm/pgtable.h
+===================================================================
+--- linux.orig/arch/mips/include/asm/pgtable.h
++++ linux/arch/mips/include/asm/pgtable.h
+@@ -229,6 +229,7 @@ static inline void set_pte(pte_t *ptep,
+ : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
+ : [global] "r" (page_global));
+ } else if (kernel_uses_llsc) {
++ loongson_llsc_mb();
+ __asm__ __volatile__ (
+ " .set "MIPS_ISA_ARCH_LEVEL" \n"
+ " .set push \n"
+@@ -244,6 +245,7 @@ static inline void set_pte(pte_t *ptep,
+ " .set mips0 \n"
+ : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
+ : [global] "r" (page_global));
++ loongson_llsc_mb();
+ }
+ #else /* !CONFIG_SMP */
+ if (pte_none(*buddy))
+Index: linux/arch/mips/loongson64/Platform
+===================================================================
+--- linux.orig/arch/mips/loongson64/Platform
++++ linux/arch/mips/loongson64/Platform
+@@ -23,6 +23,29 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+ endif
+
+ cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap
++
++#
++# Some versions of binutils, not currently mainline as of 2019/02/04, support
++# an -mfix-loongson3-llsc flag which emits a sync prior to each ll instruction
++# to work around a CPU bug (see loongson_llsc_mb() in asm/barrier.h for a
++# description).
++#
++# We disable this in order to prevent the assembler meddling with the
++# instruction that labels refer to, ie. if we label an ll instruction:
++#
++# 1: ll v0, 0(a0)
++#
++# ...then with the assembler fix applied the label may actually point at a sync
++# instruction inserted by the assembler, and if we were using the label in an
++# exception table the table would no longer contain the address of the ll
++# instruction.
++#
++# Avoid this by explicitly disabling that assembler behaviour. If upstream
++# binutils does not merge support for the flag then we can revisit & remove
++# this later - for now it ensures vendor toolchains don't cause problems.
++#
++cflags-$(CONFIG_CPU_LOONGSON3) += $(call as-option,-Wa$(comma)-mno-fix-loongson3-llsc,)
++
+ #
+ # binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
+ # as MIPS64 R2; older versions as just R1. This leaves the possibility open
+Index: linux/arch/mips/mm/tlbex.c
+===================================================================
+--- linux.orig/arch/mips/mm/tlbex.c
++++ linux/arch/mips/mm/tlbex.c
+@@ -943,6 +943,8 @@ build_get_pgd_vmalloc64(u32 **p, struct
+ * to mimic that here by taking a load/istream page
+ * fault.
+ */
++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
++ uasm_i_sync(p, 0);
+ UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
+ uasm_i_jr(p, ptr);
+
+@@ -1663,6 +1665,8 @@ static void
+ iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
+ {
+ #ifdef CONFIG_SMP
++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
++ uasm_i_sync(p, 0);
+ # ifdef CONFIG_PHYS_ADDR_T_64BIT
+ if (cpu_has_64bits)
+ uasm_i_lld(p, pte, 0, ptr);
+@@ -2276,6 +2280,8 @@ static void build_r4000_tlb_load_handler
+ #endif
+
+ uasm_l_nopage_tlbl(&l, p);
++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
++ uasm_i_sync(&p, 0);
+ build_restore_work_registers(&p);
+ #ifdef CONFIG_CPU_MICROMIPS
+ if ((unsigned long)tlb_do_page_fault_0 & 1) {
+@@ -2330,6 +2336,8 @@ static void build_r4000_tlb_store_handle
+ #endif
+
+ uasm_l_nopage_tlbs(&l, p);
++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
++ uasm_i_sync(&p, 0);
+ build_restore_work_registers(&p);
+ #ifdef CONFIG_CPU_MICROMIPS
+ if ((unsigned long)tlb_do_page_fault_1 & 1) {
+@@ -2385,6 +2393,8 @@ static void build_r4000_tlb_modify_handl
+ #endif
+
+ uasm_l_nopage_tlbm(&l, p);
++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS))
++ uasm_i_sync(&p, 0);
+ build_restore_work_registers(&p);
+ #ifdef CONFIG_CPU_MICROMIPS
+ if ((unsigned long)tlb_do_page_fault_1 & 1) {
diff --git a/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch b/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch
new file mode 100644
index 000000000..45e1252df
--- /dev/null
+++ b/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch
@@ -0,0 +1,39 @@
+From: Krzysztof Kozlowski <krzk@kernel.org>
+Date: Wed, 29 Aug 2018 09:32:23 +0200
+Subject: powerpc/boot: Fix missing crc32poly.h when building with KERNEL_XZ
+Origin: https://patchwork.ozlabs.org/patch/963258/
+
+After commit faa16bc404d7 ("lib: Use existing define with
+polynomial") the lib/xz/xz_crc32.c includes a header from include/linux
+directory thus any other user of this code should define proper include
+path.
+
+This fixes the build error on powerpc with CONFIG_KERNEL_XZ:
+
+ In file included from ../arch/powerpc/boot/../../../lib/decompress_unxz.c:233:0,
+ from ../arch/powerpc/boot/decompress.c:42:
+ ../arch/powerpc/boot/../../../lib/xz/xz_crc32.c:18:29: fatal error: linux/crc32poly.h: No such file or directory
+
+Reported-by: Michal Kubecek <mkubecek@suse.cz>
+Fixes: faa16bc404d7 ("lib: Use existing define with polynomial")
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Reported-by: kbuild test robot <lkp@intel.com>
+Reported-by: Meelis Roos <mroos@linux.ee>
+Tested-by: Michal Kubecek <mkubecek@suse.cz>
+---
+ arch/powerpc/boot/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/arch/powerpc/boot/Makefile
+===================================================================
+--- linux.orig/arch/powerpc/boot/Makefile
++++ linux/arch/powerpc/boot/Makefile
+@@ -68,7 +68,7 @@ ifeq ($(call cc-option-yn, -fstack-prote
+ BOOTCFLAGS += -fno-stack-protector
+ endif
+
+-BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj)
++BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj) -I$(srctree)/include
+
+ DTC_FLAGS ?= -p 1024
+
diff --git a/debian/patches/bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch b/debian/patches/bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch
new file mode 100644
index 000000000..833cf5a3c
--- /dev/null
+++ b/debian/patches/bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch
@@ -0,0 +1,42 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 26 Dec 2018 00:00:40 +0000
+Subject: powerpc: Fix -mcpu= options for SPE-only compiler
+Forwarded: https://lists.debian.org/debian-kernel/2018/12/msg00295.html
+
+GCC for Debian's "powerpcspe" architecture only supports 32-bit
+SPE targets, and using -mcpu=powerpc or -mcpu=powerpc64 is a fatal
+error.
+
+* Change the test for a biarch compiler to pass both the -m32 and -m64
+ options, so that it doesn't catch 32-bit-only compilers
+* Add an ifdef CONFIG_PPC64 around the 64-bit CPU option definitions
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+--- a/arch/powerpc/Makefile
++++ b/arch/powerpc/Makefile
+@@ -12,7 +12,7 @@
+ # Rewritten by Cort Dougan and Paul Mackerras
+ #
+
+-HAS_BIARCH := $(call cc-option-yn, -m32)
++HAS_BIARCH := $(call cc-option-yn, -m32 -m64)
+
+ # Set default 32 bits cross compilers for vdso and boot wrapper
+ CROSS32_COMPILE ?=
+@@ -159,6 +159,7 @@ CFLAGS-$(CONFIG_PPC32) += $(call cc-opti
+
+ CFLAGS-$(CONFIG_PPC32) += $(call cc-option,-mno-readonly-in-sdata)
+
++ifdef CONFIG_PPC64
+ ifdef CONFIG_PPC_BOOK3S_64
+ ifdef CONFIG_CPU_LITTLE_ENDIAN
+ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8
+@@ -170,6 +171,7 @@ endif
+ else ifdef CONFIG_PPC_BOOK3E_64
+ CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64
+ endif
++endif
+
+ ifdef CONFIG_FUNCTION_TRACER
+ CC_FLAGS_FTRACE := -pg
diff --git a/debian/patches/bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch b/debian/patches/bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch
new file mode 100644
index 000000000..8fc19da9f
--- /dev/null
+++ b/debian/patches/bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch
@@ -0,0 +1,30 @@
+From: James Clarke <jrtc27@jrtc27.com>
+Date: Sun, 18 Feb 2018 15:54:44 +0000
+Subject: powerpc/lib/Makefile: Don't pull in quad.o for 32-bit kernels
+Origin: https://people.debian.org/~jrtc27/linux-ppc32/0002-powerpc-lib-Makefile-Don-t-pull-in-quad.o-for-32-bit.patch
+
+The functions exported by quad.o are only used when guarded by
+__powerpc64__ and so are unused on 32-bit kernels. Moreover, their
+implementations make use of instructions which will cause an illegal
+instruction error on 32-bit processors, and are not accepted by the
+assembler for SPE processors.
+
+Fixes: 31bfdb036f12 ("powerpc: Use instruction emulation infrastructure to handle alignment faults")
+Signed-off-by: James Clarke <jrtc27@jrtc27.com>
+---
+ arch/powerpc/lib/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/arch/powerpc/lib/Makefile
+===================================================================
+--- linux.orig/arch/powerpc/lib/Makefile
++++ linux/arch/powerpc/lib/Makefile
+@@ -35,7 +35,7 @@ obj64-$(CONFIG_KPROBES_SANITY_TEST) += t
+ obj-y += checksum_$(BITS).o checksum_wrappers.o \
+ string_$(BITS).o memcmp_$(BITS).o
+
+-obj-y += sstep.o ldstfp.o quad.o
++obj-y += sstep.o ldstfp.o
+ obj64-y += quad.o
+
+ obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
diff --git a/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch b/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch
new file mode 100644
index 000000000..8e50801c9
--- /dev/null
+++ b/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch
@@ -0,0 +1,132 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 19 Aug 2017 21:42:09 +0100
+Subject: sh: Do not use hyphen in exported variable names
+Forwarded: https://marc.info/?l=linux-sh&m=150317827322995&w=2
+
+arch/sh/Makefile defines and exports ld-bfd to be used by
+arch/sh/boot/Makefile and arch/sh/boot/compressed/Makefile. Similarly
+arch/sh/boot/Makefile defines and exports suffix-y to be used by
+arch/sh/boot/compressed/Makefile. However some shells, including
+dash, will not pass through environment variables whose name includes
+a hyphen. Usually GNU make does not use a shell to recurse, but if
+e.g. $(srctree) contains '~' it will use a shell here.
+
+Rename these variables to ld_bfd and suffix_y.
+
+References: https://buildd.debian.org/status/fetch.php?pkg=linux&arch=sh4&ver=4.13%7Erc5-1%7Eexp1&stamp=1502943967&raw=0
+Fixes: ef9b542fce00 ("sh: bzip2/lzma uImage support.")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ arch/sh/Makefile | 10 +++++-----
+ arch/sh/boot/Makefile | 16 ++++++++--------
+ arch/sh/boot/compressed/Makefile | 6 +++---
+ arch/sh/boot/romimage/Makefile | 4 ++--
+ 4 files changed, 18 insertions(+), 18 deletions(-)
+
+Index: linux/arch/sh/Makefile
+===================================================================
+--- linux.orig/arch/sh/Makefile
++++ linux/arch/sh/Makefile
+@@ -119,16 +119,16 @@ LDFLAGS_vmlinux += --defsym phys_stext=
+ endif
+
+ ifdef CONFIG_CPU_LITTLE_ENDIAN
+-ld-bfd := elf32-$(UTS_MACHINE)-linux
+-LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld-bfd)
++ld_bfd := elf32-$(UTS_MACHINE)-linux
++LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld_bfd)
+ KBUILD_LDFLAGS += -EL
+ else
+-ld-bfd := elf32-$(UTS_MACHINE)big-linux
+-LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd)
++ld_bfd := elf32-$(UTS_MACHINE)big-linux
++LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld_bfd)
+ KBUILD_LDFLAGS += -EB
+ endif
+
+-export ld-bfd BITS
++export ld_bfd BITS
+
+ head-y := arch/sh/kernel/head_$(BITS).o
+
+Index: linux/arch/sh/boot/Makefile
+===================================================================
+--- linux.orig/arch/sh/boot/Makefile
++++ linux/arch/sh/boot/Makefile
+@@ -19,12 +19,12 @@ CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000
+ CONFIG_ENTRY_OFFSET ?= 0x00001000
+ CONFIG_PHYSICAL_START ?= $(CONFIG_MEMORY_START)
+
+-suffix-y := bin
+-suffix-$(CONFIG_KERNEL_GZIP) := gz
+-suffix-$(CONFIG_KERNEL_BZIP2) := bz2
+-suffix-$(CONFIG_KERNEL_LZMA) := lzma
+-suffix-$(CONFIG_KERNEL_XZ) := xz
+-suffix-$(CONFIG_KERNEL_LZO) := lzo
++suffix_y := bin
++suffix_$(CONFIG_KERNEL_GZIP) := gz
++suffix_$(CONFIG_KERNEL_BZIP2) := bz2
++suffix_$(CONFIG_KERNEL_LZMA) := lzma
++suffix_$(CONFIG_KERNEL_XZ) := xz
++suffix_$(CONFIG_KERNEL_LZO) := lzo
+
+ targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \
+ uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin
+@@ -106,10 +106,10 @@ OBJCOPYFLAGS_uImage.srec := -I binary -O
+ $(obj)/uImage.srec: $(obj)/uImage
+ $(call if_changed,objcopy)
+
+-$(obj)/uImage: $(obj)/uImage.$(suffix-y)
++$(obj)/uImage: $(obj)/uImage.$(suffix_y)
+ @ln -sf $(notdir $<) $@
+ @echo ' Image $@ is ready'
+
+ export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \
+ CONFIG_PHYSICAL_START CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET \
+- KERNEL_MEMORY suffix-y
++ KERNEL_MEMORY suffix_y
+Index: linux/arch/sh/boot/compressed/Makefile
+===================================================================
+--- linux.orig/arch/sh/boot/compressed/Makefile
++++ linux/arch/sh/boot/compressed/Makefile
+@@ -33,7 +33,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS)
+ KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
+ endif
+
+-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \
++LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(IMAGE_OFFSET) -e startup \
+ -T $(obj)/../../kernel/vmlinux.lds
+
+ #
+@@ -75,7 +75,7 @@ $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.al
+
+ OBJCOPYFLAGS += -R .empty_zero_page
+
+-LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
++LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T
+
+-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE
++$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE
+ $(call if_changed,ld)
+Index: linux/arch/sh/boot/romimage/Makefile
+===================================================================
+--- linux.orig/arch/sh/boot/romimage/Makefile
++++ linux/arch/sh/boot/romimage/Makefile
+@@ -13,7 +13,7 @@ mmcif-obj-$(CONFIG_CPU_SUBTYPE_SH7724) :
+ load-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-load-y)
+ obj-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-obj-y)
+
+-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(load-y) -e romstart \
++LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(load-y) -e romstart \
+ -T $(obj)/../../kernel/vmlinux.lds
+
+ $(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE
+@@ -24,7 +24,7 @@ OBJCOPYFLAGS += -j .empty_zero_page
+ $(obj)/zeropage.bin: vmlinux FORCE
+ $(call if_changed,objcopy)
+
+-LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T
++LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T
+
+ $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE
+ $(call if_changed,ld)
diff --git a/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch b/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch
new file mode 100644
index 000000000..e8727ef11
--- /dev/null
+++ b/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch
@@ -0,0 +1,37 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 22 Jul 2017 17:37:33 +0100
+Subject: perf tools: Fix unwind build on i386
+Forwarded: no
+
+EINVAL may not be defined when building unwind-libunwind.c with
+REMOTE_UNWIND_LIBUNWIND, resulting in a compiler error in
+LIBUNWIND__ARCH_REG_ID(). Its only caller, access_reg(), only checks
+for a negative return value and doesn't care what it is. So change
+-EINVAL to -1.
+
+Fixes: 52ffe0ff02fc ("Support x86(32-bit) cross platform callchain unwind.")
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+
+Index: linux/tools/perf/arch/x86/util/unwind-libunwind.c
+===================================================================
+--- linux.orig/tools/perf/arch/x86/util/unwind-libunwind.c
++++ linux/tools/perf/arch/x86/util/unwind-libunwind.c
+@@ -67,7 +67,7 @@ int LIBUNWIND__ARCH_REG_ID(int regnum)
+ break;
+ default:
+ pr_err("unwind: invalid reg id %d\n", regnum);
+- return -EINVAL;
++ return -1;
+ }
+
+ return id;
+@@ -107,7 +107,7 @@ int LIBUNWIND__ARCH_REG_ID(int regnum)
+ break;
+ default:
+ pr_err("unwind: invalid reg id %d\n", regnum);
+- return -EINVAL;
++ return -1;
+ }
+
+ return id;
diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch
new file mode 100644
index 000000000..c9cd5cfc4
--- /dev/null
+++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch
@@ -0,0 +1,37 @@
+From: Sven Rebhan <sven.rebhan@gmail.com>
+Date: Tue, 21 Feb 2017 20:53:48 +0100
+Subject: platform/x86: ideapad-laptop: Add IdeaPad 310-15IKB to no_hw_rfkill
+Origin: https://git.kernel.org/linus/1f3bc53d843f92d6e7e7cf56ee79acec918e6421
+
+Like other Lenovo models the IdeaPad 310-15IKB does not have an hw rfkill
+switch. This results in hard-blocked radios after boot, resulting in
+always blocked radios rendering them unusable.
+
+Add the IdeaPad 310-15IKB to the no_hw_rfkill DMI list and allows using
+the built-in radios.
+
+Signed-off-by: Sven Rebhan <Sven.Rebhan@googlemail.com>
+[andy: massaged commit message]
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+---
+ drivers/platform/x86/ideapad-laptop.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux/drivers/platform/x86/ideapad-laptop.c
+===================================================================
+--- linux.orig/drivers/platform/x86/ideapad-laptop.c
++++ linux/drivers/platform/x86/ideapad-laptop.c
+@@ -1098,6 +1098,13 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo ideapad 310-15IKB",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15IKB"),
++ },
++ },
++ {
+ .ident = "Lenovo ideapad Y700-15ACZ",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch
new file mode 100644
index 000000000..43a075fea
--- /dev/null
+++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch
@@ -0,0 +1,35 @@
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Tue, 21 Feb 2017 20:53:48 +0100
+Subject: platform/x86: ideapad-laptop: Add IdeaPad V310-15ISK to no_hw_rfkill
+Origin: https://git.kernel.org/linus/ccc7179f4d9467947c94f4302d61cd5143842fcd
+
+Like other Lenovo models the IdeaPad V310-15ISK does not have an hw
+rfkill switch. This results in hard-blocked radios after boot, resulting
+in always blocked radios rendering them unusable.
+
+Add the IdeaPad V310-15ISK to the no_hw_rfkill DMI list and allows using
+the built-in radios.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+---
+ drivers/platform/x86/ideapad-laptop.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux/drivers/platform/x86/ideapad-laptop.c
+===================================================================
+--- linux.orig/drivers/platform/x86/ideapad-laptop.c
++++ linux/drivers/platform/x86/ideapad-laptop.c
+@@ -1098,6 +1098,13 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo V310-15ISK",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-15ISK"),
++ },
++ },
++ {
+ .ident = "Lenovo ideapad 310-15IKB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch
new file mode 100644
index 000000000..f64747726
--- /dev/null
+++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch
@@ -0,0 +1,37 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 1 Jul 2017 08:20:18 +0200
+Subject: platform/x86: ideapad-laptop: Add IdeaPad V510-15IKB to no_hw_rfkill
+Origin: https://git.kernel.org/linus/0df4b805cbccbe3f8378f49c415adb2fcffdd3dc
+Bug-Debian: https://bugs.debian.org/866706
+
+Like other Lenovo models the IdeaPad V510-15IKB does not have an hw
+rfkill switch. This results in hard-blocked radios after boot, resulting
+in always blocked radios rendering them unusable.
+
+Add the IdeaPad V510-15IKB to the no_hw_rfkill DMI list and allows using
+the built-in radios.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+---
+ drivers/platform/x86/ideapad-laptop.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux/drivers/platform/x86/ideapad-laptop.c
+===================================================================
+--- linux.orig/drivers/platform/x86/ideapad-laptop.c
++++ linux/drivers/platform/x86/ideapad-laptop.c
+@@ -1105,6 +1105,13 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo V510-15IKB",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V510-15IKB"),
++ },
++ },
++ {
+ .ident = "Lenovo ideapad 310-15IKB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch
new file mode 100644
index 000000000..4041cd9a3
--- /dev/null
+++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch
@@ -0,0 +1,112 @@
+From: Yang Jiaxun <yjx@flygoat.com>
+Date: Tue, 4 Jul 2017 14:39:19 +0000
+Subject: platform/x86: ideapad-laptop: Add several models to no_hw_rfkill
+Origin: https://git.kernel.org/linus/710c059c248a24609051f5a3dd1d8468cdc675b0
+
+Some Lenovo ideapad models do not have hardware rfkill switches, but
+trying to read the rfkill switches through the ideapad-laptop module.
+It caused to always reported blocking breaking wifi.
+
+Fix it by adding those models to no_hw_rfkill_list.
+
+Signed-off-by: Yang Jiaxun <yjx@flygoat.com>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+---
+ drivers/platform/x86/ideapad-laptop.c | 70 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 70 insertions(+)
+
+Index: linux/drivers/platform/x86/ideapad-laptop.c
+===================================================================
+--- linux.orig/drivers/platform/x86/ideapad-laptop.c
++++ linux/drivers/platform/x86/ideapad-laptop.c
+@@ -1098,6 +1098,27 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo V310-14IKB",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-14IKB"),
++ },
++ },
++ {
++ .ident = "Lenovo V310-14ISK",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-14ISK"),
++ },
++ },
++ {
++ .ident = "Lenovo V310-15IKB",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-15IKB"),
++ },
++ },
++ {
+ .ident = "Lenovo V310-15ISK",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+@@ -1112,6 +1133,41 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo ideapad 300-15IBR",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 300-15IBR"),
++ },
++ },
++ {
++ .ident = "Lenovo ideapad 300-15IKB",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 300-15IKB"),
++ },
++ },
++ {
++ .ident = "Lenovo ideapad 300S-11IBR",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 300S-11BR"),
++ },
++ },
++ {
++ .ident = "Lenovo ideapad 310-15ABR",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15ABR"),
++ },
++ },
++ {
++ .ident = "Lenovo ideapad 310-15IAP",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15IAP"),
++ },
++ },
++ {
+ .ident = "Lenovo ideapad 310-15IKB",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+@@ -1119,6 +1175,20 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo ideapad 310-15ISK",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15ISK"),
++ },
++ },
++ {
++ .ident = "Lenovo ideapad Y700-14ISK",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-14ISK"),
++ },
++ },
++ {
+ .ident = "Lenovo ideapad Y700-15ACZ",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch
new file mode 100644
index 000000000..0020839df
--- /dev/null
+++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch
@@ -0,0 +1,35 @@
+From: Olle Liljenzin <olle@liljenzin.se>
+Date: Sun, 18 Jun 2017 13:09:31 +0200
+Subject: platform/x86: ideapad-laptop: Add Y520-15IKBN to no_hw_rfkill
+Origin: https://git.kernel.org/linus/5d9f40b56630a8702b5f7a61a770f9b73aa07464
+
+Lenovo Legion Y520-15IKBN is yet another Lenovo model that does not
+have an hw rfkill switch, resulting in wifi always reported as hard
+blocked.
+
+Add the model to the list of models without rfkill switch.
+
+Signed-off-by: Olle Liljenzin <olle@liljenzin.se>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+---
+ drivers/platform/x86/ideapad-laptop.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux/drivers/platform/x86/ideapad-laptop.c
+===================================================================
+--- linux.orig/drivers/platform/x86/ideapad-laptop.c
++++ linux/drivers/platform/x86/ideapad-laptop.c
+@@ -1182,6 +1182,13 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo Legion Y520-15IKBN",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKBN"),
++ },
++ },
++ {
+ .ident = "Lenovo Yoga 2 11 / 13 / Pro",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch
new file mode 100644
index 000000000..59f3dc3f6
--- /dev/null
+++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch
@@ -0,0 +1,35 @@
+From: Olle Liljenzin <olle@liljenzin.se>
+Date: Sun, 18 Jun 2017 14:37:58 +0200
+Subject: platform/x86: ideapad-laptop: Add Y720-15IKBN to no_hw_rfkill
+Origin: https://git.kernel.org/linus/b2f2fe205c3b9b595dc50ee431230a45d03f9c2c
+
+Lenovo Legion Y720-15IKBN is yet another Lenovo model that does not
+have an hw rfkill switch, resulting in wifi always reported as hard
+blocked.
+
+Add the model to the list of models without rfkill switch.
+
+Signed-off-by: Olle Liljenzin <olle@liljenzin.se>
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+---
+ drivers/platform/x86/ideapad-laptop.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux/drivers/platform/x86/ideapad-laptop.c
+===================================================================
+--- linux.orig/drivers/platform/x86/ideapad-laptop.c
++++ linux/drivers/platform/x86/ideapad-laptop.c
+@@ -1189,6 +1189,13 @@ static const struct dmi_system_id no_hw_
+ },
+ },
+ {
++ .ident = "Lenovo Legion Y720-15IKBN",
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y720-15IKBN"),
++ },
++ },
++ {
+ .ident = "Lenovo Yoga 2 11 / 13 / Pro",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
diff --git a/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch b/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch
new file mode 100644
index 000000000..e571c91fe
--- /dev/null
+++ b/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch
@@ -0,0 +1,24 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 25 Sep 2015 22:50:50 +0100
+Subject: Revert "perf build: Fix libunwind feature detection on 32-bit x86"
+Forwarded: no
+
+This reverts commit 05b41775e2edd69a83f592e3534930c934d4038e.
+It broke feature detection that was working just fine for us.
+---
+ tools/perf/Makefile.config | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/tools/perf/Makefile.config
+===================================================================
+--- linux.orig/tools/perf/Makefile.config
++++ linux/tools/perf/Makefile.config
+@@ -42,7 +42,7 @@ ifeq ($(SRCARCH),x86)
+ LIBUNWIND_LIBS = -lunwind-x86_64 -lunwind -llzma
+ $(call detected,CONFIG_X86_64)
+ else
+- LIBUNWIND_LIBS = -lunwind-x86 -llzma -lunwind
++ LIBUNWIND_LIBS = -lunwind -lunwind-x86
+ endif
+ NO_PERF_REGS := 0
+ endif
diff --git a/debian/patches/bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch b/debian/patches/bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch
new file mode 100644
index 000000000..77b56df47
--- /dev/null
+++ b/debian/patches/bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch
@@ -0,0 +1,114 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 11 Sep 2018 03:07:28 +0100
+Subject: tools: turbostat: Add checks for failure of fgets() and fscanf()
+Forwarded: https://marc.info/?l=linux-pm&m=153711036626779
+
+Most calls to fgets() and fscanf() are followed by error checks.
+Add an exit-on-error in the remaining cases.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ tools/power/x86/turbostat/turbostat.c | 28 +++++++++++++++++----------
+ 1 file changed, 18 insertions(+), 10 deletions(-)
+
+Index: linux/tools/power/x86/turbostat/turbostat.c
+===================================================================
+--- linux.orig/tools/power/x86/turbostat/turbostat.c
++++ linux/tools/power/x86/turbostat/turbostat.c
+@@ -2554,7 +2554,8 @@ int get_thread_siblings(struct cpu_topol
+ filep = fopen_or_die(path, "r");
+ do {
+ offset -= BITMASK_SIZE;
+- fscanf(filep, "%lx%c", &map, &character);
++ if (fscanf(filep, "%lx%c", &map, &character) != 2)
++ err(1, "%s: failed to parse file", path);
+ for (shift = 0; shift < BITMASK_SIZE; shift++) {
+ if ((map >> shift) & 0x1) {
+ so = shift + offset;
+@@ -3407,14 +3408,14 @@ dump_sysfs_cstate_config(void)
+ input = fopen(path, "r");
+ if (input == NULL)
+ continue;
+- fgets(name_buf, sizeof(name_buf), input);
++ if (!fgets(name_buf, sizeof(name_buf), input))
++ err(1, "%s: failed to read file", path);
+
+ /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
+ sp = strchr(name_buf, '-');
+ if (!sp)
+ sp = strchrnul(name_buf, '\n');
+ *sp = '\0';
+-
+ fclose(input);
+
+ sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc",
+@@ -3422,7 +3423,8 @@ dump_sysfs_cstate_config(void)
+ input = fopen(path, "r");
+ if (input == NULL)
+ continue;
+- fgets(desc, sizeof(desc), input);
++ if (!fgets(desc, sizeof(desc), input))
++ err(1, "%s: failed to read file", path);
+
+ fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc);
+ fclose(input);
+@@ -3444,7 +3446,8 @@ dump_sysfs_pstate_config(void)
+ fprintf(stderr, "NSFOD %s\n", path);
+ return;
+ }
+- fgets(driver_buf, sizeof(driver_buf), input);
++ if (!fgets(driver_buf, sizeof(driver_buf), input))
++ err(1, "%s: failed to read file", path);
+ fclose(input);
+
+ sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
+@@ -3454,7 +3457,8 @@ dump_sysfs_pstate_config(void)
+ fprintf(stderr, "NSFOD %s\n", path);
+ return;
+ }
+- fgets(governor_buf, sizeof(governor_buf), input);
++ if (!fgets(governor_buf, sizeof(governor_buf), input))
++ err(1, "%s: failed to read file", path);
+ fclose(input);
+
+ fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf);
+@@ -3463,7 +3467,8 @@ dump_sysfs_pstate_config(void)
+ sprintf(path, "/sys/devices/system/cpu/cpufreq/boost");
+ input = fopen(path, "r");
+ if (input != NULL) {
+- fscanf(input, "%d", &turbo);
++ if (fscanf(input, "%d", &turbo) != 1)
++ err(1, "%s: failed to parse number from file", path);
+ fprintf(outf, "cpufreq boost: %d\n", turbo);
+ fclose(input);
+ }
+@@ -3471,7 +3476,8 @@ dump_sysfs_pstate_config(void)
+ sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo");
+ input = fopen(path, "r");
+ if (input != NULL) {
+- fscanf(input, "%d", &turbo);
++ if (fscanf(input, "%d", &turbo) != 1)
++ err(1, "%s: failed to parse number from file", path);
+ fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo);
+ fclose(input);
+ }
+@@ -5296,7 +5302,8 @@ void probe_sysfs(void)
+ input = fopen(path, "r");
+ if (input == NULL)
+ continue;
+- fgets(name_buf, sizeof(name_buf), input);
++ if (!fgets(name_buf, sizeof(name_buf), input))
++ err(1, "%s: failed to read file", path);
+
+ /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
+ sp = strchr(name_buf, '-');
+@@ -5323,7 +5330,8 @@ void probe_sysfs(void)
+ input = fopen(path, "r");
+ if (input == NULL)
+ continue;
+- fgets(name_buf, sizeof(name_buf), input);
++ if (!fgets(name_buf, sizeof(name_buf), input))
++ err(1, "%s: failed to read file", path);
+ /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */
+ sp = strchr(name_buf, '-');
+ if (!sp)
diff --git a/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch b/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch
new file mode 100644
index 000000000..14df64f35
--- /dev/null
+++ b/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch
@@ -0,0 +1,36 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 20 Apr 2013 15:52:02 +0100
+Subject: viafb: Autoload on OLPC XO 1.5 only
+Bug-Debian: https://bugs.debian.org/705788
+Forwarded: no
+
+It appears that viafb won't work automatically on all the boards for
+which it has a PCI device ID match. Currently, it is blacklisted by
+udev along with most other framebuffer drivers, so this doesn't matter
+much.
+
+However, this driver is required for console support on the XO 1.5.
+We need to allow it to be autoloaded on this model only, and then
+un-blacklist it in udev.
+
+---
+Index: linux/drivers/video/fbdev/via/via-core.c
+===================================================================
+--- linux.orig/drivers/video/fbdev/via/via-core.c
++++ linux/drivers/video/fbdev/via/via-core.c
+@@ -752,7 +752,14 @@ static const struct pci_device_id via_pc
+ .driver_data = UNICHROME_VX900 },
+ { }
+ };
+-MODULE_DEVICE_TABLE(pci, via_pci_table);
++
++static const struct pci_device_id via_pci_autoload_table[] __initconst = {
++ /* OLPC XO 1.5 */
++ { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
++ .subvendor = 0x152d, .subdevice = 0x0833 },
++ { }
++};
++MODULE_DEVICE_TABLE(pci, via_pci_autoload_table);
+
+ static struct pci_driver via_driver = {
+ .name = "viafb",
diff --git a/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch b/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch
new file mode 100644
index 000000000..2970dc8b4
--- /dev/null
+++ b/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 25 Sep 2018 19:44:13 +0100
+Subject: x86-32: Disable 3D-Now in generic config
+
+We want the 686 flavour to run on Geode LX and similar AMD family 5
+CPUs as well as family 6 and higher CPUs. This used to work with
+CONFIG_M686=y. However commit 25d76ac88821 "x86/Kconfig: Explicitly
+enumerate i686-class CPUs in Kconfig" in Linux 4.16 has made the
+kernel require family 6 or higher.
+
+It looks like a sensible choice would be to enable CONFIG_MGEODE_LX
+and CONFIG_X86_GENERIC (for more generic optimisations), but this
+currently enables CONFIG_X86_USE_3D_NOW which will cause the kernel to
+crash on CPUs without the AMD-specific 3D-Now instructions.
+
+Make CONFIG_X86_USE_3DNOW depend on CONFIG_X86_GENERIC being disabled.
+
+---
+Index: linux/arch/x86/Kconfig.cpu
+===================================================================
+--- linux.orig/arch/x86/Kconfig.cpu
++++ linux/arch/x86/Kconfig.cpu
+@@ -337,7 +337,7 @@ config X86_USE_PPRO_CHECKSUM
+
+ config X86_USE_3DNOW
+ def_bool y
+- depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
++ depends on (MCYRIXIII || MK7 || MGEODE_LX) && !X86_GENERIC && !UML
+
+ #
+ # P6_NOPs are a relatively minor optimization that require a family >=
diff --git a/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch b/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch
new file mode 100644
index 000000000..3f6baa5dc
--- /dev/null
+++ b/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch
@@ -0,0 +1,99 @@
+From: Serge Hallyn <serge.hallyn@canonical.com>
+Date: Fri, 31 May 2013 19:12:12 +0000 (+0100)
+Subject: add sysctl to disallow unprivileged CLONE_NEWUSER by default
+Origin: http://kernel.ubuntu.com/git?p=serge%2Fubuntu-saucy.git;a=commit;h=5c847404dcb2e3195ad0057877e1422ae90892b8
+
+add sysctl to disallow unprivileged CLONE_NEWUSER by default
+
+This is a short-term patch. Unprivileged use of CLONE_NEWUSER
+is certainly an intended feature of user namespaces. However
+for at least saucy we want to make sure that, if any security
+issues are found, we have a fail-safe.
+
+Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
+[bwh: Remove unneeded binary sysctl bits]
+---
+Index: linux/kernel/fork.c
+===================================================================
+--- linux.orig/kernel/fork.c
++++ linux/kernel/fork.c
+@@ -103,6 +103,11 @@
+
+ #define CREATE_TRACE_POINTS
+ #include <trace/events/task.h>
++#ifdef CONFIG_USER_NS
++extern int unprivileged_userns_clone;
++#else
++#define unprivileged_userns_clone 0
++#endif
+
+ /*
+ * Minimum number of threads to boot the kernel
+@@ -1675,6 +1680,10 @@ static __latent_entropy struct task_stru
+ if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
+ return ERR_PTR(-EINVAL);
+
++ if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone)
++ if (!capable(CAP_SYS_ADMIN))
++ return ERR_PTR(-EPERM);
++
+ /*
+ * Thread groups must share signals as well, and detached threads
+ * can only be started up within the thread group.
+@@ -2504,6 +2513,12 @@ int ksys_unshare(unsigned long unshare_f
+ if (unshare_flags & CLONE_NEWNS)
+ unshare_flags |= CLONE_FS;
+
++ if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) {
++ err = -EPERM;
++ if (!capable(CAP_SYS_ADMIN))
++ goto bad_unshare_out;
++ }
++
+ err = check_unshare_flags(unshare_flags);
+ if (err)
+ goto bad_unshare_out;
+Index: linux/kernel/sysctl.c
+===================================================================
+--- linux.orig/kernel/sysctl.c
++++ linux/kernel/sysctl.c
+@@ -105,6 +105,9 @@ extern int core_uses_pid;
+ extern char core_pattern[];
+ extern unsigned int core_pipe_limit;
+ #endif
++#ifdef CONFIG_USER_NS
++extern int unprivileged_userns_clone;
++#endif
+ extern int pid_max;
+ extern int pid_max_min, pid_max_max;
+ extern int percpu_pagelist_fraction;
+@@ -515,6 +518,15 @@ static struct ctl_table kern_table[] = {
+ .mode = 0644,
+ .proc_handler = proc_dointvec,
+ },
++#endif
++#ifdef CONFIG_USER_NS
++ {
++ .procname = "unprivileged_userns_clone",
++ .data = &unprivileged_userns_clone,
++ .maxlen = sizeof(int),
++ .mode = 0644,
++ .proc_handler = proc_dointvec,
++ },
+ #endif
+ #ifdef CONFIG_PROC_SYSCTL
+ {
+Index: linux/kernel/user_namespace.c
+===================================================================
+--- linux.orig/kernel/user_namespace.c
++++ linux/kernel/user_namespace.c
+@@ -26,6 +26,9 @@
+ #include <linux/bsearch.h>
+ #include <linux/sort.h>
+
++/* sysctl */
++int unprivileged_userns_clone;
++
+ static struct kmem_cache *user_ns_cachep __read_mostly;
+ static DEFINE_MUTEX(userns_state_mutex);
+
diff --git a/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch b/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch
new file mode 100644
index 000000000..8726519ad
--- /dev/null
+++ b/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 19 Nov 2010 02:12:48 +0000
+Subject: [PATCH 2/3] af_802154: Disable auto-loading as mitigation against local exploits
+Forwarded: not-needed
+
+Recent review has revealed several bugs in obscure protocol
+implementations that can be exploited by local users for denial of
+service or privilege escalation. We can mitigate the effect of any
+remaining vulnerabilities in such protocols by preventing unprivileged
+users from loading the modules, so that they are only exploitable on
+systems where the administrator has chosen to load the protocol.
+
+The 'af_802154' (IEEE 802.15.4) protocol is not widely used, was
+not present in the 'lenny' kernel, and seems to receive only sporadic
+maintenance. Therefore disable auto-loading.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ net/ieee802154/socket.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+Index: linux/net/ieee802154/socket.c
+===================================================================
+--- linux.orig/net/ieee802154/socket.c
++++ linux/net/ieee802154/socket.c
+@@ -1144,4 +1144,4 @@ module_init(af_ieee802154_init);
+ module_exit(af_ieee802154_remove);
+
+ MODULE_LICENSE("GPL");
+-MODULE_ALIAS_NETPROTO(PF_IEEE802154);
++/* MODULE_ALIAS_NETPROTO(PF_IEEE802154); */
diff --git a/debian/patches/debian/android-enable-building-ashmem-and-binder-as-modules.patch b/debian/patches/debian/android-enable-building-ashmem-and-binder-as-modules.patch
new file mode 100644
index 000000000..da02e00e0
--- /dev/null
+++ b/debian/patches/debian/android-enable-building-ashmem-and-binder-as-modules.patch
@@ -0,0 +1,97 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 22 Jun 2018 17:27:00 +0100
+Subject: android: Enable building ashmem and binder as modules
+Bug-Debian: https://bugs.debian.org/901492
+
+We want to enable use of the Android ashmem and binder drivers to
+support Anbox, but they should not be built-in as that would waste
+resources and increase security attack surface on systems that don't
+need them.
+
+- Add a MODULE_LICENSE declaration to ashmem
+- Change the Makefiles to build each driver as an object with the
+ "_linux" suffix (which is what Anbox expects)
+- Change config symbol types to tristate
+
+---
+Index: linux/drivers/android/Kconfig
+===================================================================
+--- linux.orig/drivers/android/Kconfig
++++ linux/drivers/android/Kconfig
+@@ -9,7 +9,7 @@ config ANDROID
+ if ANDROID
+
+ config ANDROID_BINDER_IPC
+- bool "Android Binder IPC Driver"
++ tristate "Android Binder IPC Driver"
+ depends on MMU
+ default n
+ ---help---
+Index: linux/drivers/android/Makefile
+===================================================================
+--- linux.orig/drivers/android/Makefile
++++ linux/drivers/android/Makefile
+@@ -1,4 +1,5 @@
+ ccflags-y += -I$(src) # needed for trace events
+
+-obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o
+-obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o
++obj-$(CONFIG_ANDROID_BINDER_IPC) += binder_linux.o
++binder_linux-y := binder.o binder_alloc.o
++binder_linux-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o
+Index: linux/drivers/staging/android/Kconfig
+===================================================================
+--- linux.orig/drivers/staging/android/Kconfig
++++ linux/drivers/staging/android/Kconfig
+@@ -3,7 +3,7 @@ menu "Android"
+ if ANDROID
+
+ config ASHMEM
+- bool "Enable the Anonymous Shared Memory Subsystem"
++ tristate "Enable the Anonymous Shared Memory Subsystem"
+ default n
+ depends on SHMEM
+ help
+Index: linux/drivers/staging/android/Makefile
+===================================================================
+--- linux.orig/drivers/staging/android/Makefile
++++ linux/drivers/staging/android/Makefile
+@@ -2,5 +2,6 @@ ccflags-y += -I$(src) # needed for tra
+
+ obj-y += ion/
+
+-obj-$(CONFIG_ASHMEM) += ashmem.o
++obj-$(CONFIG_ASHMEM) += ashmem_linux.o
++ashmem_linux-y += ashmem.o
+ obj-$(CONFIG_ANDROID_VSOC) += vsoc.o
+Index: linux/drivers/staging/android/ashmem.c
+===================================================================
+--- linux.orig/drivers/staging/android/ashmem.c
++++ linux/drivers/staging/android/ashmem.c
+@@ -24,6 +24,7 @@
+ #include <linux/bitops.h>
+ #include <linux/mutex.h>
+ #include <linux/shmem_fs.h>
++#include <linux/module.h>
+ #include "ashmem.h"
+
+ #define ASHMEM_NAME_PREFIX "dev/ashmem/"
+@@ -924,3 +925,5 @@ out:
+ return ret;
+ }
+ device_initcall(ashmem_init);
++
++MODULE_LICENSE("GPL v2");
+Index: linux/drivers/android/binder_alloc.c
+===================================================================
+--- linux.orig/drivers/android/binder_alloc.c
++++ linux/drivers/android/binder_alloc.c
+@@ -44,7 +44,7 @@ enum {
+ };
+ static uint32_t binder_alloc_debug_mask = BINDER_DEBUG_USER_ERROR;
+
+-module_param_named(debug_mask, binder_alloc_debug_mask,
++module_param_named(alloc_debug_mask, binder_alloc_debug_mask,
+ uint, 0644);
+
+ #define binder_alloc_debug(mask, x...) \
diff --git a/debian/patches/debian/arch-sh4-fix-uimage-build.patch b/debian/patches/debian/arch-sh4-fix-uimage-build.patch
new file mode 100644
index 000000000..d9c651ccb
--- /dev/null
+++ b/debian/patches/debian/arch-sh4-fix-uimage-build.patch
@@ -0,0 +1,20 @@
+From: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
+Subject: [sh4] Fix uImage build
+Bug-Debian: https://bugs.debian.org/569034
+Forwarded: not-needed
+
+[bwh: This was added without a description, but I think it is dealing
+with a similar issue to powerpcspe-omit-uimage.patch]
+
+Index: linux/arch/sh/Makefile
+===================================================================
+--- linux.orig/arch/sh/Makefile
++++ linux/arch/sh/Makefile
+@@ -89,7 +89,6 @@ OBJCOPYFLAGS := -O binary -R .note -R .n
+
+ # Give the various platforms the opportunity to set default image types
+ defaultimage-$(CONFIG_SUPERH32) := zImage
+-defaultimage-$(CONFIG_SH_SH7785LCR) := uImage
+ defaultimage-$(CONFIG_SH_RSK) := uImage
+ defaultimage-$(CONFIG_SH_URQUELL) := uImage
+ defaultimage-$(CONFIG_SH_MIGOR) := uImage
diff --git a/debian/patches/debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch b/debian/patches/debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch
new file mode 100644
index 000000000..5be1b26a7
--- /dev/null
+++ b/debian/patches/debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch
@@ -0,0 +1,37 @@
+From: Adam Borowski <kilobyte@angband.pl>
+Date: Tue, 28 Mar 2017 16:55:05 +0200
+Subject: btrfs: warn about RAID5/6 being experimental at mount time
+Bug-Debian: https://bugs.debian.org/863290
+Origin: https://bugs.debian.org/863290#5
+
+Too many people come complaining about losing their data -- and indeed,
+there's no warning outside a wiki and the mailing list tribal knowledge.
+Message severity chosen for consistency with XFS -- "alert" makes dmesg
+produce nice red background which should get the point across.
+
+Signed-off-by: Adam Borowski <kilobyte@angband.pl>
+[bwh: Also add_taint() so this is flagged in bug reports]
+---
+ fs/btrfs/disk-io.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+Index: linux/fs/btrfs/disk-io.c
+===================================================================
+--- linux.orig/fs/btrfs/disk-io.c
++++ linux/fs/btrfs/disk-io.c
+@@ -3089,6 +3089,15 @@ retry_root_backup:
+ btrfs_set_and_info(fs_info, SSD, "enabling ssd optimizations");
+ }
+
++ if ((fs_info->avail_data_alloc_bits |
++ fs_info->avail_metadata_alloc_bits |
++ fs_info->avail_system_alloc_bits) &
++ BTRFS_BLOCK_GROUP_RAID56_MASK) {
++ btrfs_alert(fs_info,
++ "btrfs RAID5/6 is EXPERIMENTAL and has known data-loss bugs");
++ add_taint(TAINT_USER, LOCKDEP_STILL_OK);
++ }
++
+ /*
+ * Mount does not set all options immediately, we can do it now and do
+ * not have to wait for transaction commit
diff --git a/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch b/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch
new file mode 100644
index 000000000..57e118698
--- /dev/null
+++ b/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch
@@ -0,0 +1,29 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: cdc_ncm,cdc_mbim: Use NCM by default
+Date: Sun, 31 Mar 2013 03:58:04 +0100
+Forwarded: not-needed
+
+Devices that support both NCM and MBIM modes should be kept in NCM
+mode unless there is userland support for MBIM.
+
+Set the default value of cdc_ncm.prefer_mbim to false and leave it to
+userland (modem-manager) to override this with a modprobe.conf file
+once it's ready to speak MBIM.
+
+---
+Index: linux/drivers/net/usb/cdc_ncm.c
+===================================================================
+--- linux.orig/drivers/net/usb/cdc_ncm.c
++++ linux/drivers/net/usb/cdc_ncm.c
+@@ -53,11 +53,7 @@
+ #include <linux/usb/cdc.h>
+ #include <linux/usb/cdc_ncm.h>
+
+-#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM)
+-static bool prefer_mbim = true;
+-#else
+ static bool prefer_mbim;
+-#endif
+ module_param(prefer_mbim, bool, 0644);
+ MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions");
+
diff --git a/debian/patches/debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch b/debian/patches/debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch
new file mode 100644
index 000000000..9f0e897c7
--- /dev/null
+++ b/debian/patches/debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch
@@ -0,0 +1,45 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 16 Feb 2017 19:09:17 +0000
+Subject: dccp: Disable auto-loading as mitigation against local exploits
+Forwarded: not-needed
+
+We can mitigate the effect of vulnerabilities in obscure protocols by
+preventing unprivileged users from loading the modules, so that they
+are only exploitable on systems where the administrator has chosen to
+load the protocol.
+
+The 'dccp' protocol is not actively maintained or widely used.
+Therefore disable auto-loading.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/net/dccp/ipv4.c
+===================================================================
+--- linux.orig/net/dccp/ipv4.c
++++ linux/net/dccp/ipv4.c
+@@ -1079,8 +1079,8 @@ module_exit(dccp_v4_exit);
+ * values directly, Also cover the case where the protocol is not specified,
+ * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP
+ */
+-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6);
+-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6);
++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6); */
++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6); */
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
+ MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol");
+Index: linux/net/dccp/ipv6.c
+===================================================================
+--- linux.orig/net/dccp/ipv6.c
++++ linux/net/dccp/ipv6.c
+@@ -1162,8 +1162,8 @@ module_exit(dccp_v6_exit);
+ * values directly, Also cover the case where the protocol is not specified,
+ * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP
+ */
+-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6);
+-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6);
++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6); */
++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6); */
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>");
+ MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol");
diff --git a/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch b/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch
new file mode 100644
index 000000000..cb83e5ee8
--- /dev/null
+++ b/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch
@@ -0,0 +1,34 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 20 Nov 2010 02:24:55 +0000
+Subject: [PATCH] decnet: Disable auto-loading as mitigation against local exploits
+Forwarded: not-needed
+
+Recent review has revealed several bugs in obscure protocol
+implementations that can be exploited by local users for denial of
+service or privilege escalation. We can mitigate the effect of any
+remaining vulnerabilities in such protocols by preventing unprivileged
+users from loading the modules, so that they are only exploitable on
+systems where the administrator has chosen to load the protocol.
+
+The 'decnet' protocol is unmaintained and of mostly historical
+interest, and the user-space support package 'dnet-common' loads the
+module explicitly. Therefore disable auto-loading.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ net/decnet/af_decnet.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+Index: linux/net/decnet/af_decnet.c
+===================================================================
+--- linux.orig/net/decnet/af_decnet.c
++++ linux/net/decnet/af_decnet.c
+@@ -2346,7 +2346,7 @@ static const struct proto_ops dn_proto_o
+ MODULE_DESCRIPTION("The Linux DECnet Network Protocol");
+ MODULE_AUTHOR("Linux DECnet Project Team");
+ MODULE_LICENSE("GPL");
+-MODULE_ALIAS_NETPROTO(PF_DECnet);
++/* MODULE_ALIAS_NETPROTO(PF_DECnet); */
+
+ static const char banner[] __initconst = KERN_INFO
+ "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n";
diff --git a/debian/patches/debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch b/debian/patches/debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch
new file mode 100644
index 000000000..97d8be0b2
--- /dev/null
+++ b/debian/patches/debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch
@@ -0,0 +1,29 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 13 Apr 2009 17:34:00 +0100
+Subject: Remove microcode patches for mgsuvd (not enabled in Debian configs)
+Forwarded: not-needed
+
+Index: linux/arch/powerpc/platforms/8xx/Kconfig
+===================================================================
+--- linux.orig/arch/powerpc/platforms/8xx/Kconfig
++++ linux/arch/powerpc/platforms/8xx/Kconfig
+@@ -144,16 +144,19 @@ config NO_UCODE_PATCH
+
+ config USB_SOF_UCODE_PATCH
+ bool "USB SOF patch"
++ depends on BROKEN
+ help
+ Help not implemented yet, coming soon.
+
+ config I2C_SPI_UCODE_PATCH
+ bool "I2C/SPI relocation patch"
++ depends on BROKEN
+ help
+ Help not implemented yet, coming soon.
+
+ config I2C_SPI_SMC1_UCODE_PATCH
+ bool "I2C/SPI/SMC1 relocation patch"
++ depends on BROKEN
+ help
+ Help not implemented yet, coming soon.
+
diff --git a/debian/patches/debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch b/debian/patches/debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch
new file mode 100644
index 000000000..47233b0ff
--- /dev/null
+++ b/debian/patches/debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch
@@ -0,0 +1,17 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 17 Aug 2009 02:45:41 +0100
+Subject: dvb-usb-af9005: mark as broken
+Forwarded: not-needed
+
+Index: linux/drivers/media/usb/dvb-usb/Kconfig
+===================================================================
+--- linux.orig/drivers/media/usb/dvb-usb/Kconfig
++++ linux/drivers/media/usb/dvb-usb/Kconfig
+@@ -246,6 +246,7 @@ config DVB_USB_OPERA1
+
+ config DVB_USB_AF9005
+ tristate "Afatech AF9005 DVB-T USB1.1 support"
++ depends on BROKEN
+ depends on DVB_USB
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
diff --git a/debian/patches/debian/dfsg/drivers-net-appletalk-cops.patch b/debian/patches/debian/dfsg/drivers-net-appletalk-cops.patch
new file mode 100644
index 000000000..d0d266861
--- /dev/null
+++ b/debian/patches/debian/dfsg/drivers-net-appletalk-cops.patch
@@ -0,0 +1,52 @@
+From: Frederik Schüler <fs@debian.org>
+Date: Fri, 05 Jan 2007 15:55:24 +0000
+Subject: Add removal patches for: 3c359, smctr, keyspan, cops
+Forwarded: not-needed
+
+Index: linux/drivers/net/appletalk/Kconfig
+===================================================================
+--- linux.orig/drivers/net/appletalk/Kconfig
++++ linux/drivers/net/appletalk/Kconfig
+@@ -49,32 +49,6 @@ config LTPC
+ This driver is experimental, which means that it may not work.
+ See the file <file:Documentation/networking/ltpc.txt>.
+
+-config COPS
+- tristate "COPS LocalTalk PC support"
+- depends on DEV_APPLETALK && (ISA || EISA)
+- help
+- This allows you to use COPS AppleTalk cards to connect to LocalTalk
+- networks. You also need version 1.3.3 or later of the netatalk
+- package. This driver is experimental, which means that it may not
+- work. This driver will only work if you choose "AppleTalk DDP"
+- networking support, above.
+- Please read the file <file:Documentation/networking/cops.txt>.
+-
+-config COPS_DAYNA
+- bool "Dayna firmware support"
+- depends on COPS
+- help
+- Support COPS compatible cards with Dayna style firmware (Dayna
+- DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC
+- III, Farallon PhoneNET PC II).
+-
+-config COPS_TANGENT
+- bool "Tangent firmware support"
+- depends on COPS
+- help
+- Support COPS compatible cards with Tangent style firmware (Tangent
+- ATB_II, Novell NL-1000, Daystar Digital LT-200.
+-
+ config IPDDP
+ tristate "Appletalk-IP driver support"
+ depends on DEV_APPLETALK && ATALK
+Index: linux/drivers/net/appletalk/Makefile
+===================================================================
+--- linux.orig/drivers/net/appletalk/Makefile
++++ linux/drivers/net/appletalk/Makefile
+@@ -3,5 +3,4 @@
+ #
+
+ obj-$(CONFIG_IPDDP) += ipddp.o
+-obj-$(CONFIG_COPS) += cops.o
+ obj-$(CONFIG_LTPC) += ltpc.o
diff --git a/debian/patches/debian/dfsg/video-remove-nvidiafb-and-rivafb.patch b/debian/patches/debian/dfsg/video-remove-nvidiafb-and-rivafb.patch
new file mode 100644
index 000000000..24e209fd1
--- /dev/null
+++ b/debian/patches/debian/dfsg/video-remove-nvidiafb-and-rivafb.patch
@@ -0,0 +1,134 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 2 Jun 2012 19:53:38 +0100
+Subject: video: Remove nvidiafb and rivafb
+Bug-Debian: https://bugs.debian.org/383481
+Forwarded: no
+
+These drivers contain register programming code provided by the
+hardware vendor that appears to have been deliberately obfuscated.
+This is arguably not the preferred form for modification.
+
+These drivers are also largely redundant with nouveau. The RIVA 128
+(NV3) is not supported by nouveau but is about 15 years old and
+probably discontinued 10 years ago.
+
+---
+Index: linux/drivers/video/fbdev/Kconfig
+===================================================================
+--- linux.orig/drivers/video/fbdev/Kconfig
++++ linux/drivers/video/fbdev/Kconfig
+@@ -901,101 +901,6 @@ config FB_ATMEL
+ help
+ This enables support for the AT91/AT32 LCD Controller.
+
+-config FB_NVIDIA
+- tristate "nVidia Framebuffer Support"
+- depends on FB && PCI
+- select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
+- select FB_MODE_HELPERS
+- select FB_CFB_FILLRECT
+- select FB_CFB_COPYAREA
+- select FB_CFB_IMAGEBLIT
+- select BITREVERSE
+- select VGASTATE
+- help
+- This driver supports graphics boards with the nVidia chips, TNT
+- and newer. For very old chipsets, such as the RIVA128, then use
+- the rivafb.
+- Say Y if you have such a graphics board.
+-
+- To compile this driver as a module, choose M here: the
+- module will be called nvidiafb.
+-
+-config FB_NVIDIA_I2C
+- bool "Enable DDC Support"
+- depends on FB_NVIDIA
+- select FB_DDC
+- help
+- This enables I2C support for nVidia Chipsets. This is used
+- only for getting EDID information from the attached display
+- allowing for robust video mode handling and switching.
+-
+- Because fbdev-2.6 requires that drivers must be able to
+- independently validate video mode parameters, you should say Y
+- here.
+-
+-config FB_NVIDIA_DEBUG
+- bool "Lots of debug output"
+- depends on FB_NVIDIA
+- default n
+- help
+- Say Y here if you want the nVidia driver to output all sorts
+- of debugging information to provide to the maintainer when
+- something goes wrong.
+-
+-config FB_NVIDIA_BACKLIGHT
+- bool "Support for backlight control"
+- depends on FB_NVIDIA
+- default y
+- help
+- Say Y here if you want to control the backlight of your display.
+-
+-config FB_RIVA
+- tristate "nVidia Riva support"
+- depends on FB && PCI
+- select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
+- select FB_MODE_HELPERS
+- select FB_CFB_FILLRECT
+- select FB_CFB_COPYAREA
+- select FB_CFB_IMAGEBLIT
+- select BITREVERSE
+- select VGASTATE
+- help
+- This driver supports graphics boards with the nVidia Riva/Geforce
+- chips.
+- Say Y if you have such a graphics board.
+-
+- To compile this driver as a module, choose M here: the
+- module will be called rivafb.
+-
+-config FB_RIVA_I2C
+- bool "Enable DDC Support"
+- depends on FB_RIVA
+- select FB_DDC
+- help
+- This enables I2C support for nVidia Chipsets. This is used
+- only for getting EDID information from the attached display
+- allowing for robust video mode handling and switching.
+-
+- Because fbdev-2.6 requires that drivers must be able to
+- independently validate video mode parameters, you should say Y
+- here.
+-
+-config FB_RIVA_DEBUG
+- bool "Lots of debug output"
+- depends on FB_RIVA
+- default n
+- help
+- Say Y here if you want the Riva driver to output all sorts
+- of debugging information to provide to the maintainer when
+- something goes wrong.
+-
+-config FB_RIVA_BACKLIGHT
+- bool "Support for backlight control"
+- depends on FB_RIVA
+- default y
+- help
+- Say Y here if you want to control the backlight of your display.
+-
+ config FB_I740
+ tristate "Intel740 support"
+ depends on FB && PCI
+Index: linux/drivers/video/fbdev/Makefile
+===================================================================
+--- linux.orig/drivers/video/fbdev/Makefile
++++ linux/drivers/video/fbdev/Makefile
+@@ -22,8 +22,6 @@ obj-$(CONFIG_FB_PM3) += pm3fb.o
+
+ obj-$(CONFIG_FB_I740) += i740fb.o
+ obj-$(CONFIG_FB_MATROX) += matrox/
+-obj-$(CONFIG_FB_RIVA) += riva/
+-obj-$(CONFIG_FB_NVIDIA) += nvidia/
+ obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
+ obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
+ obj-$(CONFIG_FB_RADEON) += aty/
diff --git a/debian/patches/debian/dfsg/vs6624-disable.patch b/debian/patches/debian/dfsg/vs6624-disable.patch
new file mode 100644
index 000000000..41219ffd5
--- /dev/null
+++ b/debian/patches/debian/dfsg/vs6624-disable.patch
@@ -0,0 +1,17 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 27 May 2012 01:56:58 +0100
+Subject: vs6624: mark as broken
+Forwarded: not-needed
+
+Index: linux/drivers/media/i2c/Kconfig
+===================================================================
+--- linux.orig/drivers/media/i2c/Kconfig
++++ linux/drivers/media/i2c/Kconfig
+@@ -803,6 +803,7 @@ config VIDEO_OV13858
+ OV13858 camera.
+
+ config VIDEO_VS6624
++ depends on BROKEN
+ tristate "ST VS6624 sensor support"
+ depends on VIDEO_V4L2 && I2C
+ depends on MEDIA_CAMERA_SUPPORT
diff --git a/debian/patches/debian/export-symbols-needed-by-android-drivers.patch b/debian/patches/debian/export-symbols-needed-by-android-drivers.patch
new file mode 100644
index 000000000..c2c8b5f23
--- /dev/null
+++ b/debian/patches/debian/export-symbols-needed-by-android-drivers.patch
@@ -0,0 +1,156 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 26 Jun 2018 16:59:01 +0100
+Subject: Export symbols needed by Android drivers
+Bug-Debian: https://bugs.debian.org/901492
+
+We want to enable use of the Android ashmem and binder drivers to
+support Anbox, but they should not be built-in as that would waste
+resources and increase security attack surface on systems that don't
+need them.
+
+Export the currently un-exported symbols they depend on.
+
+---
+--- a/fs/file.c
++++ b/fs/file.c
+@@ -409,6 +409,7 @@ struct files_struct *get_files_struct(st
+
+ return files;
+ }
++EXPORT_SYMBOL_GPL(get_files_struct);
+
+ void put_files_struct(struct files_struct *files)
+ {
+@@ -421,6 +422,7 @@ void put_files_struct(struct files_struc
+ kmem_cache_free(files_cachep, files);
+ }
+ }
++EXPORT_SYMBOL_GPL(put_files_struct);
+
+ void reset_files_struct(struct files_struct *files)
+ {
+@@ -534,6 +536,7 @@ out:
+ spin_unlock(&files->file_lock);
+ return error;
+ }
++EXPORT_SYMBOL_GPL(__alloc_fd);
+
+ static int alloc_fd(unsigned start, unsigned flags)
+ {
+@@ -607,6 +610,7 @@ void __fd_install(struct files_struct *f
+ rcu_assign_pointer(fdt->fd[fd], file);
+ rcu_read_unlock_sched();
+ }
++EXPORT_SYMBOL_GPL(__fd_install);
+
+ void fd_install(unsigned int fd, struct file *file)
+ {
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -1054,6 +1054,7 @@ void mmput_async(struct mm_struct *mm)
+ schedule_work(&mm->async_put_work);
+ }
+ }
++EXPORT_SYMBOL_GPL(mmput_async);
+ #endif
+
+ /**
+--- a/kernel/signal.c
++++ b/kernel/signal.c
+@@ -1368,6 +1368,7 @@ struct sighand_struct *__lock_task_sigha
+
+ return sighand;
+ }
++EXPORT_SYMBOL_GPL(__lock_task_sighand);
+
+ /*
+ * send signal info to all the members of a group
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1644,6 +1644,7 @@ void zap_page_range(struct vm_area_struc
+ mmu_notifier_invalidate_range_end(mm, start, end);
+ tlb_finish_mmu(&tlb, start, end);
+ }
++EXPORT_SYMBOL_GPL(zap_page_range);
+
+ /**
+ * zap_page_range_single - remove user pages in a given range
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -4053,6 +4053,7 @@ int shmem_zero_setup(struct vm_area_stru
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(shmem_zero_setup);
+
+ /**
+ * shmem_read_mapping_page_gfp - read into page cache, using specified page allocation flags.
+--- a/mm/vmalloc.c
++++ b/mm/vmalloc.c
+@@ -1300,6 +1300,7 @@ int map_kernel_range_noflush(unsigned lo
+ {
+ return vmap_page_range_noflush(addr, addr + size, prot, pages);
+ }
++EXPORT_SYMBOL_GPL(map_kernel_range_noflush);
+
+ /**
+ * unmap_kernel_range_noflush - unmap kernel VM area
+@@ -1440,6 +1441,7 @@ struct vm_struct *get_vm_area(unsigned l
+ NUMA_NO_NODE, GFP_KERNEL,
+ __builtin_return_address(0));
+ }
++EXPORT_SYMBOL_GPL(get_vm_area);
+
+ struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,
+ const void *caller)
+--- a/security/security.c
++++ b/security/security.c
+@@ -236,24 +236,28 @@ int security_binder_set_context_mgr(cons
+ {
+ return call_int_hook(binder_set_context_mgr, 0, mgr);
+ }
++EXPORT_SYMBOL_GPL(security_binder_set_context_mgr);
+
+ int security_binder_transaction(const struct cred *from,
+ const struct cred *to)
+ {
+ return call_int_hook(binder_transaction, 0, from, to);
+ }
++EXPORT_SYMBOL_GPL(security_binder_transaction);
+
+ int security_binder_transfer_binder(const struct cred *from,
+ const struct cred *to)
+ {
+ return call_int_hook(binder_transfer_binder, 0, from, to);
+ }
++EXPORT_SYMBOL_GPL(security_binder_transfer_binder);
+
+ int security_binder_transfer_file(const struct cred *from,
+ const struct cred *to, struct file *file)
+ {
+ return call_int_hook(binder_transfer_file, 0, from, to, file);
+ }
++EXPORT_SYMBOL_GPL(security_binder_transfer_file);
+
+ int security_ptrace_access_check(struct task_struct *child, unsigned int mode)
+ {
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3979,6 +3979,7 @@ int can_nice(const struct task_struct *p
+ return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
+ capable(CAP_SYS_NICE));
+ }
++EXPORT_SYMBOL_GPL(can_nice);
+
+ #ifdef __ARCH_WANT_SYS_NICE
+
+--- a/kernel/sched/wait.c
++++ b/kernel/sched/wait.c
+@@ -215,6 +215,7 @@ void __wake_up_pollfree(struct wait_queu
+ /* POLLFREE must have cleared the queue. */
+ WARN_ON_ONCE(waitqueue_active(wq_head));
+ }
++EXPORT_SYMBOL_GPL(__wake_up_pollfree);
+
+ /*
+ * Note: we use "set_current_state()" _after_ the wait-queue add,
diff --git a/debian/patches/debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch b/debian/patches/debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch
new file mode 100644
index 000000000..5149007a4
--- /dev/null
+++ b/debian/patches/debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: fanotify: Taint on use of FANOTIFY_ACCESS_PERMISSIONS
+Date: Wed, 13 Jul 2016 01:37:22 +0100
+Forwarded: not-needed
+
+Various free and proprietary AV products use this feature and users
+apparently want it. But punting access checks to userland seems like
+an easy way to deadlock the system, and there will be nothing we can
+do about that. So warn and taint the kernel if this feature is
+actually used.
+
+---
+Index: linux/fs/notify/fanotify/fanotify_user.c
+===================================================================
+--- linux.orig/fs/notify/fanotify/fanotify_user.c
++++ linux/fs/notify/fanotify/fanotify_user.c
+@@ -842,6 +842,14 @@ static int do_fanotify_mark(int fanotify
+ if (mask & ~valid_mask)
+ return -EINVAL;
+
++#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
++ if (mask & FAN_ALL_PERM_EVENTS) {
++ pr_warn_once("%s (%d): Using fanotify permission checks may lead to deadlock; tainting kernel\n",
++ current->comm, current->pid);
++ add_taint(TAINT_USER, LOCKDEP_STILL_OK);
++ }
++#endif
++
+ f = fdget(fanotify_fd);
+ if (unlikely(!f.file))
+ return -EBADF;
diff --git a/debian/patches/debian/firmware_class-refer-to-debian-wiki-firmware-page.patch b/debian/patches/debian/firmware_class-refer-to-debian-wiki-firmware-page.patch
new file mode 100644
index 000000000..da4942ee6
--- /dev/null
+++ b/debian/patches/debian/firmware_class-refer-to-debian-wiki-firmware-page.patch
@@ -0,0 +1,58 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 12 Mar 2018 01:14:03 +0000
+Subject: firmware_class: Refer to Debian wiki page when logging missing firmware
+Bug-Debian: https://bugs.debian.org/888405
+Forwarded: not-needed
+
+If firmware loading fails due to a missing file, log a second error
+message referring to our wiki page about firmware. This will explain
+why some firmware is in non-free, or can't be packaged at all. Only
+do this once per boot.
+
+Do something similar in the radeon and amdgpu drivers, where we have
+an early check to avoid failing at a point where we cannot display
+anything.
+
+---
+Index: linux/drivers/base/firmware_loader/main.c
+===================================================================
+--- linux.orig/drivers/base/firmware_loader/main.c
++++ linux/drivers/base/firmware_loader/main.c
+@@ -340,9 +340,12 @@ fw_get_filesystem_firmware(struct device
+ }
+ __putname(path);
+
+- if (rc)
++ if (rc) {
+ dev_err(device, "firmware: failed to load %s (%d)\n",
+ fw_priv->fw_name, rc);
++ if (rc == -ENOENT)
++ pr_err_once("See https://wiki.debian.org/Firmware for information about missing firmware\n");
++ }
+
+ return rc;
+ }
+Index: linux/drivers/gpu/drm/radeon/radeon_drv.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/radeon/radeon_drv.c
++++ linux/drivers/gpu/drm/radeon/radeon_drv.c
+@@ -403,6 +403,7 @@ static int radeon_pci_probe(struct pci_d
+ if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 &&
+ !radeon_firmware_installed()) {
+ DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware installed\n");
++ pr_err_once("See https://wiki.debian.org/Firmware for information about missing firmware\n");
+ return -ENODEV;
+ }
+
+Index: linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+===================================================================
+--- linux.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -859,6 +859,7 @@ static int amdgpu_pci_probe(struct pci_d
+
+ if (!amdgpu_firmware_installed()) {
+ DRM_ERROR("amdgpu requires firmware installed\n");
++ pr_err_once("See https://wiki.debian.org/Firmware for information about missing firmware\n");
+ return -ENODEV;
+ }
+
diff --git a/debian/patches/debian/fjes-disable-autoload.patch b/debian/patches/debian/fjes-disable-autoload.patch
new file mode 100644
index 000000000..e1081d872
--- /dev/null
+++ b/debian/patches/debian/fjes-disable-autoload.patch
@@ -0,0 +1,26 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 18 Mar 2017 20:47:58 +0000
+Subject: fjes: Disable auto-loading
+Bug-Debian: https://bugs.debian.org/853976
+Forwarded: no
+
+fjes matches a generic ACPI device ID, and relies on its probe
+function to distinguish whether that really corresponds to a supported
+device. Very few system will need the driver and it wastes memory on
+all the other systems where the same device ID appears, so disable
+auto-loading.
+
+---
+Index: linux/drivers/net/fjes/fjes_main.c
+===================================================================
+--- linux.orig/drivers/net/fjes/fjes_main.c
++++ linux/drivers/net/fjes/fjes_main.c
+@@ -83,7 +83,7 @@ static const struct acpi_device_id fjes_
+ {ACPI_MOTHERBOARD_RESOURCE_HID, 0},
+ {"", 0},
+ };
+-MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids);
++/* MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids); */
+
+ static struct acpi_driver fjes_acpi_driver = {
+ .name = DRV_NAME,
diff --git a/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch b/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch
new file mode 100644
index 000000000..50b32bc2d
--- /dev/null
+++ b/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch
@@ -0,0 +1,24 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: fs: Enable link security restrictions by default
+Date: Fri, 02 Nov 2012 05:32:06 +0000
+Bug-Debian: https://bugs.debian.org/609455
+Forwarded: not-needed
+
+This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415
+('VFS: don't do protected {sym,hard}links by default').
+
+Index: linux/fs/namei.c
+===================================================================
+--- linux.orig/fs/namei.c
++++ linux/fs/namei.c
+@@ -885,8 +885,8 @@ static inline void put_link(struct namei
+ path_put(&last->link);
+ }
+
+-int sysctl_protected_symlinks __read_mostly = 0;
+-int sysctl_protected_hardlinks __read_mostly = 0;
++int sysctl_protected_symlinks __read_mostly = 1;
++int sysctl_protected_hardlinks __read_mostly = 1;
+ int sysctl_protected_fifos __read_mostly;
+ int sysctl_protected_regular __read_mostly;
+
diff --git a/debian/patches/debian/gitignore.patch b/debian/patches/debian/gitignore.patch
new file mode 100644
index 000000000..493e558b7
--- /dev/null
+++ b/debian/patches/debian/gitignore.patch
@@ -0,0 +1,49 @@
+From: Ian Campbell <ijc@hellion.org.uk>
+Date: Thu, 17 Jan 2013 08:55:21 +0000
+Subject: Tweak gitignore for Debian pkg-kernel using git svn.
+Forwarded: not-needed
+
+[bwh: Tweak further for pure git]
+
+Index: linux/.gitignore
+===================================================================
+--- linux.orig/.gitignore
++++ linux/.gitignore
+@@ -64,11 +64,6 @@ modules.builtin
+ /*.spec
+
+ #
+-# Debian directory (make deb-pkg)
+-#
+-/debian/
+-
+-#
+ # Snap directory (make snap-pkg)
+ #
+ /snap/
+@@ -79,14 +74,6 @@ modules.builtin
+ /tar-install/
+
+ #
+-# git files that we don't want to ignore even if they are dot-files
+-#
+-!.gitignore
+-!.mailmap
+-!.cocciconfig
+-!.clang-format
+-
+-#
+ # Generated include files
+ #
+ include/config
+@@ -132,3 +119,10 @@ all.config
+
+ # Kdevelop4
+ *.kdev4
++
++#
++# Debian packaging: ignore everything at the top level, since it isn't
++# included in our repository
++#
++/*
++!/debian/
diff --git a/debian/patches/debian/i386-686-pae-pci-set-pci-nobios-by-default.patch b/debian/patches/debian/i386-686-pae-pci-set-pci-nobios-by-default.patch
new file mode 100644
index 000000000..d9dcef669
--- /dev/null
+++ b/debian/patches/debian/i386-686-pae-pci-set-pci-nobios-by-default.patch
@@ -0,0 +1,29 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Tue, 16 Feb 2016 02:45:42 +0000
+Subject: [i386/686-pae] PCI: Set pci=nobios by default
+Forwarded: not-needed
+
+CONFIG_PCI_GOBIOS results in physical addresses 640KB-1MB being mapped
+W+X, which is undesirable for security reasons and will result in a
+warning at boot now that we enable CONFIG_DEBUG_WX.
+
+This can be overridden using the kernel parameter "pci=nobios", but we
+want to disable W+X by default. Disable PCI BIOS probing by default;
+it can still be enabled using "pci=bios".
+
+---
+Index: linux/arch/x86/pci/common.c
+===================================================================
+--- linux.orig/arch/x86/pci/common.c
++++ linux/arch/x86/pci/common.c
+@@ -19,8 +19,8 @@
+ #include <asm/pci_x86.h>
+ #include <asm/setup.h>
+
+-unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
+- PCI_PROBE_MMCONF;
++unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF |
++ (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE) ? 0 : PCI_PROBE_BIOS);
+
+ static int pci_bf_sort;
+ int pci_routeirq;
diff --git a/debian/patches/debian/ia64-hardcode-arch-script-output.patch b/debian/patches/debian/ia64-hardcode-arch-script-output.patch
new file mode 100644
index 000000000..f4b320f15
--- /dev/null
+++ b/debian/patches/debian/ia64-hardcode-arch-script-output.patch
@@ -0,0 +1,72 @@
+From: dann frazier <dannf@debian.org>
+Subject: Hardcode arch script output
+Date: Mon, 26 Mar 2007 16:30:51 -0600
+Bug-Debian: https://bugs.debian.org/392592
+Forwarded: not-needed
+
+Here's a patch that simply uses hardcoded definitions instead of
+doing the dynamic tests that require architecture-specific scripts.
+
+I don't particularly like this approach because it restricts
+portability and diverts from upstream. But, it is simpler, and this
+really needs to be fixed somehow before etch (along with a rebuild of
+linux-modules-extra-2.6), so I'm willing to live with it if my other
+patch is deemed unacceptable.
+
+My primary concern is that, in the future, the output of these scripts
+will change and we (or our successors) will either not notice or
+forget to update the hardcoded values.
+
+Including the scripts in linux-kbuild will avoid this manual step
+altogether, and allow for the possibility of other archs to provide
+their own scripts in the future.
+
+Index: linux/arch/ia64/Makefile
+===================================================================
+--- linux.orig/arch/ia64/Makefile
++++ linux/arch/ia64/Makefile
+@@ -30,16 +30,7 @@ cflags-y := -pipe $(EXTRA) -ffixed-r13 -
+ -falign-functions=32 -frename-registers -fno-optimize-sibling-calls
+ KBUILD_CFLAGS_KERNEL := -mconstant-gp
+
+-GAS_STATUS = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)")
+-KBUILD_CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)")
+-
+-ifeq ($(GAS_STATUS),buggy)
+-$(error Sorry, you need a newer version of the assember, one that is built from \
+- a source-tree that post-dates 18-Dec-2002. You can find a pre-compiled \
+- static binary of such an assembler at: \
+- \
+- ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
+-endif
++KBUILD_CPPFLAGS += -DHAVE_WORKING_TEXT_ALIGN -DHAVE_MODEL_SMALL_ATTRIBUTE -DHAVE_SERIALIZE_DIRECTIVE
+
+ KBUILD_CFLAGS += $(cflags-y)
+ head-y := arch/ia64/kernel/head.o
+@@ -65,7 +56,7 @@ boot := arch/ia64/hp/sim/boot
+
+ PHONY += boot compressed check
+
+-all: compressed unwcheck
++all: compressed
+
+ compressed: vmlinux.gz
+
+@@ -74,9 +65,6 @@ vmlinuz: vmlinux.gz
+ vmlinux.gz: vmlinux
+ $(Q)$(MAKE) $(build)=$(boot) $@
+
+-unwcheck: vmlinux
+- -$(Q)READELF=$(READELF) $(PYTHON) $(srctree)/arch/ia64/scripts/unwcheck.py $<
+-
+ archclean:
+ $(Q)$(MAKE) $(clean)=$(boot)
+
+@@ -92,7 +80,6 @@ define archhelp
+ echo '* compressed - Build compressed kernel image'
+ echo ' install - Install compressed kernel image'
+ echo ' boot - Build vmlinux and bootloader for Ski simulator'
+- echo '* unwcheck - Check vmlinux for invalid unwind info'
+ endef
+
+ archprepare: make_nr_irqs_h
diff --git a/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch b/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch
new file mode 100644
index 000000000..37d84d005
--- /dev/null
+++ b/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch
@@ -0,0 +1,28 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: iwlwifi: Do not request unreleased firmware for IWL6000
+Bug-Debian: https://bugs.debian.org/689416
+Forwarded: not-needed
+
+The iwlwifi driver currently supports firmware API versions 4-6 for
+these devices. It will request the file for the latest supported
+version and then fall back to earlier versions. However, the latest
+version that has actually been released is 4, so we expect the
+requests for versions 6 and then 5 to fail.
+
+The installer appears to report any failed request, and it is probably
+not easy to detect that this particular failure is harmless. So stop
+requesting the unreleased firmware.
+
+Index: linux/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+===================================================================
+--- linux.orig/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
++++ linux/drivers/net/wireless/intel/iwlwifi/cfg/6000.c
+@@ -32,7 +32,7 @@
+ #include "dvm/commands.h" /* needed for BT for now */
+
+ /* Highest firmware API version supported */
+-#define IWL6000_UCODE_API_MAX 6
++#define IWL6000_UCODE_API_MAX 4 /* v5-6 are supported but not released */
+ #define IWL6050_UCODE_API_MAX 5
+ #define IWL6000G2_UCODE_API_MAX 6
+ #define IWL6035_UCODE_API_MAX 6
diff --git a/debian/patches/debian/kernelvariables.patch b/debian/patches/debian/kernelvariables.patch
new file mode 100644
index 000000000..d33dad595
--- /dev/null
+++ b/debian/patches/debian/kernelvariables.patch
@@ -0,0 +1,81 @@
+From: Bastian Blank <waldi@debian.org>
+Subject: kbuild: Make the toolchain variables easily overwritable
+Date: Sun, 22 Feb 2009 15:39:35 +0100
+Forwarded: not-needed
+
+Allow make variables to be overridden for each flavour by a file in
+the build tree, .kernelvariables.
+
+We currently use this for ARCH, KERNELRELEASE, CC, and in some cases
+also CROSS_COMPILE, CFLAGS_KERNEL and CFLAGS_MODULE.
+
+This file can only be read after we establish the build tree, and all
+use of $(ARCH) needs to be moved after this.
+
+Index: linux/Makefile
+===================================================================
+--- linux.orig/Makefile
++++ linux/Makefile
+@@ -321,31 +321,6 @@ include scripts/subarch.include
+ # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+ ARCH ?= $(SUBARCH)
+
+-# Architecture as present in compile.h
+-UTS_MACHINE := $(ARCH)
+-SRCARCH := $(ARCH)
+-
+-# Additional ARCH settings for x86
+-ifeq ($(ARCH),i386)
+- SRCARCH := x86
+-endif
+-ifeq ($(ARCH),x86_64)
+- SRCARCH := x86
+-endif
+-
+-# Additional ARCH settings for sparc
+-ifeq ($(ARCH),sparc32)
+- SRCARCH := sparc
+-endif
+-ifeq ($(ARCH),sparc64)
+- SRCARCH := sparc
+-endif
+-
+-# Additional ARCH settings for sh
+-ifeq ($(ARCH),sh64)
+- SRCARCH := sh
+-endif
+-
+ KCONFIG_CONFIG ?= .config
+ export KCONFIG_CONFIG
+
+@@ -399,6 +374,30 @@ CFLAGS_KERNEL =
+ AFLAGS_KERNEL =
+ LDFLAGS_vmlinux =
+
++-include $(obj)/.kernelvariables
++
++# Architecture as present in compile.h
++UTS_MACHINE := $(ARCH)
++SRCARCH := $(ARCH)
++
++# Additional ARCH settings for x86
++ifeq ($(ARCH),i386)
++ SRCARCH := x86
++endif
++ifeq ($(ARCH),x86_64)
++ SRCARCH := x86
++endif
++
++# Additional ARCH settings for sparc
++ifeq ($(ARCH),sparc64)
++ SRCARCH := sparc
++endif
++
++# Additional ARCH settings for sh
++ifeq ($(ARCH),sh64)
++ SRCARCH := sh
++endif
++
+ # Use USERINCLUDE when you must reference the UAPI directories only.
+ USERINCLUDE := \
+ -I$(srctree)/arch/$(SRCARCH)/include/uapi \
diff --git a/debian/patches/debian/mips-boston-disable-its.patch b/debian/patches/debian/mips-boston-disable-its.patch
new file mode 100644
index 000000000..ad93dfa8a
--- /dev/null
+++ b/debian/patches/debian/mips-boston-disable-its.patch
@@ -0,0 +1,22 @@
+From: YunQiang Su <syq@debian.org>
+Date: Mon, 14 May 2018 16:16:18 +0800
+Subject: Disable uImage generation for mips generic
+Forwarded: not-needed
+
+MIPS generic trys to generate uImage when build, which then ask for
+u-boot-tools.
+
+Index: linux/arch/mips/generic/Platform
+===================================================================
+--- linux.orig/arch/mips/generic/Platform
++++ linux/arch/mips/generic/Platform
+@@ -11,9 +11,7 @@
+ platform-$(CONFIG_MIPS_GENERIC) += generic/
+ cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic
+ load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000
+-all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb
+
+-its-y := vmlinux.its.S
+ its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S
+ its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S
+ its-$(CONFIG_FIT_IMAGE_FDT_OCELOT_PCB123) += board-ocelot_pcb123.its.S
diff --git a/debian/patches/debian/mips-disable-werror.patch b/debian/patches/debian/mips-disable-werror.patch
new file mode 100644
index 000000000..37da74ce3
--- /dev/null
+++ b/debian/patches/debian/mips-disable-werror.patch
@@ -0,0 +1,25 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 13 Sep 2010 02:16:18 +0100
+Subject: [PATCH] Partially revert "MIPS: Add -Werror to arch/mips/Kbuild"
+Forwarded: not-needed
+
+This reverts commits 66f9ba101f54bda63ab1db97f9e9e94763d0651b and
+5373633cc9253ba82547473e899cab141c54133e.
+
+We really don't want to add -Werror anywhere.
+---
+Index: linux/arch/mips/Kbuild
+===================================================================
+--- linux.orig/arch/mips/Kbuild
++++ linux/arch/mips/Kbuild
+@@ -1,10 +1,3 @@
+-# Fail on warnings - also for files referenced in subdirs
+-# -Werror can be disabled for specific files using:
+-# CFLAGS_<file.o> := -Wno-error
+-ifeq ($(W),)
+-subdir-ccflags-y := -Werror
+-endif
+-
+ # platform specific definitions
+ include arch/mips/Kbuild.platforms
+ obj-y := $(platform-y)
diff --git a/debian/patches/debian/ntfs-mark-it-as-broken.patch b/debian/patches/debian/ntfs-mark-it-as-broken.patch
new file mode 100644
index 000000000..19892c9f0
--- /dev/null
+++ b/debian/patches/debian/ntfs-mark-it-as-broken.patch
@@ -0,0 +1,21 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 25 Apr 2019 15:31:33 +0100
+Subject: ntfs: mark it as broken
+
+NTFS has unfixed issues CVE-2018-12929, CVE-2018-12930, and
+CVE-2018-12931. ntfs-3g is a better supported alternative.
+
+Make sure it can't be enabled even in custom kernels.
+
+---
+Index: linux/fs/ntfs/Kconfig
+===================================================================
+--- linux.orig/fs/ntfs/Kconfig
++++ linux/fs/ntfs/Kconfig
+@@ -1,5 +1,6 @@
+ config NTFS_FS
+ tristate "NTFS file system support"
++ depends on BROKEN
+ select NLS
+ help
+ NTFS is the file system of Microsoft Windows NT, 2000, XP and 2003.
diff --git a/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch b/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch
new file mode 100644
index 000000000..b951744e5
--- /dev/null
+++ b/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch
@@ -0,0 +1,59 @@
+From: Nicolas Schier <nicolas@fjasle.eu>
+Subject: ovl: permit overlayfs mounts in user namespaces (taints kernel)
+Date: Mon, 19 Nov 2018 20:36:14 +0100
+
+Permit overlayfs mounts within user namespaces to allow utilisation of e.g.
+unprivileged LXC overlay snapshots.
+
+Except by the Ubuntu community [1], overlayfs mounts in user namespaces are
+expected to be a security risk [2] and thus are not enabled on upstream
+Linux kernels. For the non-Ubuntu users that have to stick to unprivileged
+overlay-based LXCs, this meant to patch and compile the kernel manually.
+Instead, adding the kernel tainting 'permit_mounts_in_userns' module
+parameter allows a kind of a user-friendly way to enable the feature.
+
+Testable with:
+
+ sudo modprobe overlay permit_mounts_in_userns=1
+ sudo sysctl -w kernel.unprivileged_userns_clone=1
+ mkdir -p lower upper work mnt
+ unshare --map-root-user --mount \
+ mount -t overlay none mnt \
+ -o lowerdir=lower,upperdir=upper,workdir=work
+
+[1]: Ubuntu allows unprivileged mounting of overlay filesystem
+https://lists.ubuntu.com/archives/kernel-team/2014-February/038091.html
+
+[2]: User namespaces + overlayfs = root privileges
+https://lwn.net/Articles/671641/
+
+Signed-off-by: Nicolas Schier <nicolas@fjasle.eu>
+
+Index: linux/fs/overlayfs/super.c
+===================================================================
+--- linux.orig/fs/overlayfs/super.c
++++ linux/fs/overlayfs/super.c
+@@ -56,6 +56,11 @@ module_param_named(xino_auto, ovl_xino_a
+ MODULE_PARM_DESC(ovl_xino_auto_def,
+ "Auto enable xino feature");
+
++static bool ovl_permit_mounts_in_userns;
++module_param_named_unsafe(permit_mounts_in_userns, ovl_permit_mounts_in_userns,
++ bool, 0444);
++MODULE_PARM_DESC(permit_mounts_in_userns, "Permit mounts in user namespaces");
++
+ static void ovl_entry_stack_free(struct ovl_entry *oe)
+ {
+ unsigned int i;
+@@ -1715,6 +1720,11 @@ static int __init ovl_init(void)
+ if (ovl_inode_cachep == NULL)
+ return -ENOMEM;
+
++ if (unlikely(ovl_permit_mounts_in_userns)) {
++ pr_warn("overlayfs: Allowing overlay mounts in user namespaces bears security risks\n");
++ ovl_fs_type.fs_flags |= FS_USERNS_MOUNT;
++ }
++
+ err = register_filesystem(&ovl_fs_type);
+ if (err)
+ kmem_cache_destroy(ovl_inode_cachep);
diff --git a/debian/patches/debian/powerpcspe-omit-uimage.patch b/debian/patches/debian/powerpcspe-omit-uimage.patch
new file mode 100644
index 000000000..48606a174
--- /dev/null
+++ b/debian/patches/debian/powerpcspe-omit-uimage.patch
@@ -0,0 +1,45 @@
+Description: Prevent building uImage with missing mkimage
+ On some powerpc platforms, CONFIG_DEFAULT_UIMAGE is selected automatically,
+ which leads to uImage being built automatically with mkimage. This tool is not
+ available in linux's build-dependencies, and the file is not strictly
+ necessary, so we are omitting this step in the build process, Debian-specific.
+Author: Roland Stigge <stigge@antcom.de>
+Bug-Debian: https://bugs.debian.org/708094
+Forwarded: not-needed
+
+Index: linux/arch/powerpc/boot/Makefile
+===================================================================
+--- linux.orig/arch/powerpc/boot/Makefile
++++ linux/arch/powerpc/boot/Makefile
+@@ -268,7 +268,6 @@ image-$(CONFIG_PPC_CHRP) += zImage.chrp
+ image-$(CONFIG_PPC_EFIKA) += zImage.chrp
+ image-$(CONFIG_PPC_PMAC) += zImage.pmac
+ image-$(CONFIG_PPC_HOLLY) += dtbImage.holly
+-image-$(CONFIG_DEFAULT_UIMAGE) += uImage
+ image-$(CONFIG_EPAPR_BOOT) += zImage.epapr
+
+ #
+@@ -327,23 +326,6 @@ image-$(CONFIG_MPC834x_MDS) += cuImage.
+ image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds
+ image-$(CONFIG_ASP834x) += dtbImage.asp834x-redboot
+
+-# Board ports in arch/powerpc/platform/85xx/Kconfig
+-image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads
+-image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads
+-image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \
+- cuImage.mpc8548cds_32b \
+- cuImage.mpc8555cds
+-image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds
+-image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \
+- cuImage.mpc8572ds
+-image-$(CONFIG_TQM8540) += cuImage.tqm8540
+-image-$(CONFIG_TQM8541) += cuImage.tqm8541
+-image-$(CONFIG_TQM8548) += cuImage.tqm8548
+-image-$(CONFIG_TQM8555) += cuImage.tqm8555
+-image-$(CONFIG_TQM8560) += cuImage.tqm8560
+-image-$(CONFIG_SBC8548) += cuImage.sbc8548
+-image-$(CONFIG_KSI8560) += cuImage.ksi8560
+-
+ # Board ports in arch/powerpc/platform/86xx/Kconfig
+ image-$(CONFIG_MVME7100) += dtbImage.mvme7100
+
diff --git a/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch b/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch
new file mode 100644
index 000000000..451c2923e
--- /dev/null
+++ b/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch
@@ -0,0 +1,31 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 19 Nov 2010 02:12:48 +0000
+Subject: [PATCH 1/3] rds: Disable auto-loading as mitigation against local exploits
+Forwarded: not-needed
+
+Recent review has revealed several bugs in obscure protocol
+implementations that can be exploited by local users for denial of
+service or privilege escalation. We can mitigate the effect of any
+remaining vulnerabilities in such protocols by preventing unprivileged
+users from loading the modules, so that they are only exploitable on
+systems where the administrator has chosen to load the protocol.
+
+The 'rds' protocol is one such protocol that has been found to be
+vulnerable, and which was not present in the 'lenny' kernel.
+Therefore disable auto-loading.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ net/rds/af_rds.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+Index: linux/net/rds/af_rds.c
+===================================================================
+--- linux.orig/net/rds/af_rds.c
++++ linux/net/rds/af_rds.c
+@@ -836,4 +836,4 @@ MODULE_DESCRIPTION("RDS: Reliable Datagr
+ " v" DRV_VERSION " (" DRV_RELDATE ")");
+ MODULE_VERSION(DRV_VERSION);
+ MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_ALIAS_NETPROTO(PF_RDS);
++/* MODULE_ALIAS_NETPROTO(PF_RDS); */
diff --git a/debian/patches/debian/revert-objtool-fix-config_stack_validation-y-warning.patch b/debian/patches/debian/revert-objtool-fix-config_stack_validation-y-warning.patch
new file mode 100644
index 000000000..6abe64a8f
--- /dev/null
+++ b/debian/patches/debian/revert-objtool-fix-config_stack_validation-y-warning.patch
@@ -0,0 +1,50 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 14 Jan 2018 19:27:18 +0000
+Subject: Revert "objtool: Fix CONFIG_STACK_VALIDATION=y warning for
+ out-of-tree modules"
+
+This reverts commit 9f0c18aec620bc9d82268b3cb937568dd07b43ff. This
+check doesn't make sense for OOT modules as they should always use
+a pre-built objtool.
+---
+ Makefile | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+--- a/Makefile
++++ b/Makefile
+@@ -971,17 +971,6 @@ export mod_sign_cmd
+
+ HOST_LIBELF_LIBS = $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf)
+
+-ifdef CONFIG_STACK_VALIDATION
+- has_libelf := $(call try-run,\
+- echo "int main() {}" | $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
+- ifeq ($(has_libelf),1)
+- objtool_target := tools/objtool FORCE
+- else
+- SKIP_STACK_VALIDATION := 1
+- export SKIP_STACK_VALIDATION
+- endif
+-endif
+-
+ PHONY += prepare0
+
+ ifeq ($(KBUILD_EXTMOD),)
+@@ -1132,6 +1121,17 @@ uapi-asm-generic:
+ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.asm-generic \
+ src=uapi/asm obj=arch/$(SRCARCH)/include/generated/uapi/asm
+
++ifdef CONFIG_STACK_VALIDATION
++ has_libelf := $(call try-run,\
++ echo "int main() {}" | $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0)
++ ifeq ($(has_libelf),1)
++ objtool_target := tools/objtool FORCE
++ else
++ SKIP_STACK_VALIDATION := 1
++ export SKIP_STACK_VALIDATION
++ endif
++endif
++
+ PHONY += prepare-objtool
+ prepare-objtool: $(objtool_target)
+ ifeq ($(SKIP_STACK_VALIDATION),1)
diff --git a/debian/patches/debian/sched-autogroup-disabled.patch b/debian/patches/debian/sched-autogroup-disabled.patch
new file mode 100644
index 000000000..20e57105c
--- /dev/null
+++ b/debian/patches/debian/sched-autogroup-disabled.patch
@@ -0,0 +1,21 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: sched: Do not enable autogrouping by default
+Date: Wed, 16 Mar 2011 03:17:06 +0000
+Forwarded: not-needed
+
+We want to provide the option of autogrouping but without enabling
+it by default yet.
+
+Index: linux/kernel/sched/autogroup.c
+===================================================================
+--- linux.orig/kernel/sched/autogroup.c
++++ linux/kernel/sched/autogroup.c
+@@ -5,7 +5,7 @@
+ #include <linux/nospec.h>
+ #include "sched.h"
+
+-unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1;
++unsigned int __read_mostly sysctl_sched_autogroup_enabled = 0;
+ static struct autogroup autogroup_default;
+ static atomic_t autogroup_seq_nr;
+
diff --git a/debian/patches/debian/snd-pcsp-disable-autoload.patch b/debian/patches/debian/snd-pcsp-disable-autoload.patch
new file mode 100644
index 000000000..2681d4275
--- /dev/null
+++ b/debian/patches/debian/snd-pcsp-disable-autoload.patch
@@ -0,0 +1,32 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Wed, 05 Feb 2014 23:01:30 +0000
+Subject: snd-pcsp: Disable autoload
+Forwarded: not-needed
+Bug-Debian: https://bugs.debian.org/697709
+
+There are two drivers claiming the platform:pcspkr device:
+- pcspkr creates an input(!) device that can only beep
+- snd-pcsp creates an equivalent input device plus a PCM device that can
+ play barely recognisable renditions of sampled sound
+
+snd-pcsp is blacklisted by the alsa-base package, but not everyone
+installs that. On PCs where no sound is wanted at all, both drivers
+will still be loaded and one or other will complain that it couldn't
+claim the relevant I/O range.
+
+In case anyone finds snd-pcsp useful, we continue to build it. But
+remove the alias, to ensure it's not loaded where it's not wanted.
+
+Index: linux/sound/drivers/pcsp/pcsp.c
+===================================================================
+--- linux.orig/sound/drivers/pcsp/pcsp.c
++++ linux/sound/drivers/pcsp/pcsp.c
+@@ -22,7 +22,7 @@ MODULE_AUTHOR("Stas Sergeev <stsp@users.
+ MODULE_DESCRIPTION("PC-Speaker driver");
+ MODULE_LICENSE("GPL");
+ MODULE_SUPPORTED_DEVICE("{{PC-Speaker, pcsp}}");
+-MODULE_ALIAS("platform:pcspkr");
++/*MODULE_ALIAS("platform:pcspkr");*/
+
+ static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */
+ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
diff --git a/debian/patches/debian/tools-perf-install.patch b/debian/patches/debian/tools-perf-install.patch
new file mode 100644
index 000000000..8cfd02afd
--- /dev/null
+++ b/debian/patches/debian/tools-perf-install.patch
@@ -0,0 +1,58 @@
+From: Bastian Blank <waldi@debian.org>
+Date: Fri, 07 Oct 2011 21:37:52 +0100
+Subject: Install perf scripts non-executable
+Forwarded: no
+
+[bwh: Forward-ported to 4.13]
+
+Index: linux/tools/perf/Makefile.perf
+===================================================================
+--- linux.orig/tools/perf/Makefile.perf
++++ linux/tools/perf/Makefile.perf
+@@ -796,8 +796,8 @@ endif
+ ifndef NO_LIBPERL
+ $(call QUIET_INSTALL, perl-scripts) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
+- $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
+- $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \
++ $(INSTALL) -m 644 scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \
++ $(INSTALL) -m 644 scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'; \
+ $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
+ endif
+@@ -805,27 +805,27 @@ ifndef NO_LIBPYTHON
+ $(call QUIET_INSTALL, python-scripts) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'; \
+- $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \
+- $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \
++ $(INSTALL) -m 644 scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \
++ $(INSTALL) -m 644 scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \
+ $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
+ endif
+ $(call QUIET_INSTALL, perf_completion-script) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \
+- $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf_$(VERSION)'
++ $(INSTALL) -m 644 perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf_$(VERSION)'
+ $(call QUIET_INSTALL, perf-tip) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(tip_instdir_SQ)'; \
+- $(INSTALL) Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)'
++ $(INSTALL) -m 644 Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)'
+
+ install-tests: all install-gtk
+ $(call QUIET_INSTALL, tests) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
+- $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
++ $(INSTALL) -m 644 tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
+- $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
++ $(INSTALL) -m 644 tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
+- $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
++ $(INSTALL) -m 644 tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \
+- $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
++ $(INSTALL) -m 644 tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'
+
+ install-bin: install-tools install-tests install-traceevent-plugins
+
diff --git a/debian/patches/debian/tools-perf-version.patch b/debian/patches/debian/tools-perf-version.patch
new file mode 100644
index 000000000..6833bb7a7
--- /dev/null
+++ b/debian/patches/debian/tools-perf-version.patch
@@ -0,0 +1,119 @@
+From: Bastian Blank <waldi@debian.org>
+Date: Mon, 26 Sep 2011 13:53:12 +0100
+Subject: Create manpages and binaries including the version
+Forwarded: no
+
+[bwh: Fix version insertion in perf man page cross-references and perf
+man page title. Install bash_completion script for perf with a
+version-dependent name. And do the same for trace.]
+
+Index: linux/tools/perf/Makefile.perf
+===================================================================
+--- linux.orig/tools/perf/Makefile.perf
++++ linux/tools/perf/Makefile.perf
+@@ -759,23 +759,23 @@ endif
+ install-tools: all install-gtk
+ $(call QUIET_INSTALL, binaries) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'; \
+- $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'; \
+- $(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf' '$(DESTDIR_SQ)$(bindir_SQ)/trace'
++ $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)/perf_$(VERSION)'; \
++ $(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf_$(VERSION)' '$(DESTDIR_SQ)$(bindir_SQ)/trace_$(VERSION)'
++ $(call QUIET_INSTALL, libexec) \
++ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+ ifndef NO_PERF_READ_VDSO32
+ $(call QUIET_INSTALL, perf-read-vdso32) \
+- $(INSTALL) $(OUTPUT)perf-read-vdso32 '$(DESTDIR_SQ)$(bindir_SQ)';
++ $(INSTALL) $(OUTPUT)perf-read-vdso32 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)';
+ endif
+ ifndef NO_PERF_READ_VDSOX32
+ $(call QUIET_INSTALL, perf-read-vdsox32) \
+- $(INSTALL) $(OUTPUT)perf-read-vdsox32 '$(DESTDIR_SQ)$(bindir_SQ)';
++ $(INSTALL) $(OUTPUT)perf-read-vdsox32 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)';
+ endif
+ ifndef NO_JVMTI
+ $(call QUIET_INSTALL, $(LIBJVMTI)) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \
+ $(INSTALL) $(OUTPUT)$(LIBJVMTI) '$(DESTDIR_SQ)$(libdir_SQ)';
+ endif
+- $(call QUIET_INSTALL, libexec) \
+- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
+ ifndef NO_LIBBPF
+ $(call QUIET_INSTALL, bpf-headers) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \
+@@ -811,7 +811,7 @@ ifndef NO_LIBPYTHON
+ endif
+ $(call QUIET_INSTALL, perf_completion-script) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \
+- $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf'
++ $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf_$(VERSION)'
+ $(call QUIET_INSTALL, perf-tip) \
+ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(tip_instdir_SQ)'; \
+ $(INSTALL) Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)'
+@@ -836,7 +836,7 @@ install-python_ext:
+
+ # 'make install-doc' should call 'make -C Documentation install'
+ $(INSTALL_DOC_TARGETS):
+- $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=)
++ $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=) VERSION=$(VERSION)
+
+ ### Cleaning rules
+
+Index: linux/tools/perf/Documentation/Makefile
+===================================================================
+--- linux.orig/tools/perf/Documentation/Makefile
++++ linux/tools/perf/Documentation/Makefile
+@@ -194,14 +194,16 @@ ifdef missing_tools
+ $(error "You need to install $(missing_tools) for man pages")
+ endif
+
+-do-install-man: man
++do-install-man: $(addprefix install-man-,$(_DOC_MAN1))
++
++install-man-perf.1: $(OUTPUT)perf.1
++ $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir)
++ sed -e 's/"PERF"/"PERF_$(VERSION)"/' -e 's/fBperf-/fBperf_$(VERSION)-/g' $^ > $(DESTDIR)$(man1dir)/perf_$(VERSION).1
++
++install-man-perf%.1: $(OUTPUT)perf%.1
+ $(call QUIET_INSTALL, Documentation-man) \
+ $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir); \
+-# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir); \
+-# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir); \
+- $(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir); \
+-# $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir); \
+-# $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir)
++ sed -e 's/"PERF\\-/"PERF_$(VERSION)\\-/' -e 's/fBperf-/fBperf_$(VERSION)-/g' $^ > $(DESTDIR)$(man1dir)/perf_$(VERSION)$*.1
+
+ install-man: check-man-tools man do-install-man
+
+Index: linux/tools/perf/util/Build
+===================================================================
+--- linux.orig/tools/perf/util/Build
++++ linux/tools/perf/util/Build
+@@ -193,6 +193,7 @@ CFLAGS_libstring.o += -Wno-unused-pa
+ CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))"
+ CFLAGS_parse-events.o += -Wno-redundant-decls
+ CFLAGS_header.o += -include $(OUTPUT)PERF-VERSION-FILE
++CFLAGS_vdso.o += -DPERFEXECDIR='"$(perfexec_instdir_SQ)"'
+
+ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE
+ $(call rule_mkdir)
+Index: linux/tools/perf/util/vdso.c
+===================================================================
+--- linux.orig/tools/perf/util/vdso.c
++++ linux/tools/perf/util/vdso.c
+@@ -52,12 +52,12 @@ static struct vdso_info *vdso_info__new(
+ .vdso32 = {
+ .temp_file_name = VDSO__TEMP_FILE_NAME,
+ .dso_name = DSO__NAME_VDSO32,
+- .read_prog = "perf-read-vdso32",
++ .read_prog = PERFEXECDIR "/perf-read-vdso32",
+ },
+ .vdsox32 = {
+ .temp_file_name = VDSO__TEMP_FILE_NAME,
+ .dso_name = DSO__NAME_VDSOX32,
+- .read_prog = "perf-read-vdsox32",
++ .read_prog = PERFEXECDIR "/perf-read-vdsox32",
+ },
+ #endif
+ };
diff --git a/debian/patches/debian/uname-version-timestamp.patch b/debian/patches/debian/uname-version-timestamp.patch
new file mode 100644
index 000000000..74cbebbde
--- /dev/null
+++ b/debian/patches/debian/uname-version-timestamp.patch
@@ -0,0 +1,35 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: Make mkcompile_h accept an alternate timestamp string
+Date: Tue, 12 May 2015 19:29:22 +0100
+Forwarded: not-needed
+
+We want to include the Debian version in the utsname::version string
+instead of a full timestamp string. However, we still need to provide
+a standard timestamp string for gen_initramfs_list.sh to make the
+kernel image reproducible.
+
+Make mkcompile_h use $KBUILD_BUILD_VERSION_TIMESTAMP in preference to
+$KBUILD_BUILD_TIMESTAMP.
+
+Index: linux/scripts/mkcompile_h
+===================================================================
+--- linux.orig/scripts/mkcompile_h
++++ linux/scripts/mkcompile_h
+@@ -33,10 +33,14 @@ else
+ VERSION=$KBUILD_BUILD_VERSION
+ fi
+
+-if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
+- TIMESTAMP=`date`
++if [ -z "$KBUILD_BUILD_VERSION_TIMESTAMP" ]; then
++ if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then
++ TIMESTAMP=`date`
++ else
++ TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
++ fi
+ else
+- TIMESTAMP=$KBUILD_BUILD_TIMESTAMP
++ TIMESTAMP=$KBUILD_BUILD_VERSION_TIMESTAMP
+ fi
+ if test -z "$KBUILD_BUILD_USER"; then
+ LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/')
diff --git a/debian/patches/debian/version.patch b/debian/patches/debian/version.patch
new file mode 100644
index 000000000..4447df7bb
--- /dev/null
+++ b/debian/patches/debian/version.patch
@@ -0,0 +1,177 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: Include package version along with kernel release in stack traces
+Date: Tue, 24 Jul 2012 03:13:10 +0100
+Forwarded: not-needed
+
+For distribution binary packages we assume
+$DISTRIBUTION_OFFICIAL_BUILD, $DISTRIBUTOR and $DISTRIBUTION_VERSION
+are set.
+
+Index: linux/Makefile
+===================================================================
+--- linux.orig/Makefile
++++ linux/Makefile
+@@ -1087,7 +1087,8 @@ endif
+ # that need to depend on updated CONFIG_* values can be checked here.
+ prepare2: prepare3 outputmakefile asm-generic
+
+-prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h
++prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h \
++ include/generated/package.h
+ $(cmd_crmodverdir)
+
+ archprepare: archheaders archscripts prepare1 scripts_basic
+@@ -1139,6 +1140,16 @@ define filechk_version.h
+ echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';)
+ endef
+
++ifneq ($(DISTRIBUTION_OFFICIAL_BUILD),)
++define filechk_package.h
++ echo \#define LINUX_PACKAGE_ID \" $(DISTRIBUTOR) $(DISTRIBUTION_VERSION)\"
++endef
++else
++define filechk_package.h
++ echo \#define LINUX_PACKAGE_ID \"\"
++endef
++endif
++
+ $(version_h): FORCE
+ $(call filechk,version.h)
+ $(Q)rm -f $(old_version_h)
+@@ -1146,6 +1157,9 @@ $(version_h): FORCE
+ include/generated/utsrelease.h: include/config/kernel.release FORCE
+ $(call filechk,utsrelease.h)
+
++include/generated/package.h: $(srctree)/Makefile FORCE
++ $(call filechk,package.h)
++
+ PHONY += headerdep
+ headerdep:
+ $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \
+Index: linux/arch/x86/um/sysrq_64.c
+===================================================================
+--- linux.orig/arch/x86/um/sysrq_64.c
++++ linux/arch/x86/um/sysrq_64.c
+@@ -9,6 +9,7 @@
+ #include <linux/sched.h>
+ #include <linux/sched/debug.h>
+ #include <linux/utsname.h>
++#include <generated/package.h>
+ #include <asm/current.h>
+ #include <asm/ptrace.h>
+ #include <asm/sysrq.h>
+@@ -17,8 +18,9 @@ void show_regs(struct pt_regs *regs)
+ {
+ printk("\n");
+ print_modules();
+- printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current),
+- current->comm, print_tainted(), init_utsname()->release);
++ printk(KERN_INFO "Pid: %d, comm: %.20s %s %s%s\n", task_pid_nr(current),
++ current->comm, print_tainted(), init_utsname()->release,
++ LINUX_PACKAGE_ID);
+ printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff,
+ PT_REGS_IP(regs));
+ printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs),
+Index: linux/arch/ia64/kernel/process.c
+===================================================================
+--- linux.orig/arch/ia64/kernel/process.c
++++ linux/arch/ia64/kernel/process.c
+@@ -34,6 +34,7 @@
+ #include <linux/utsname.h>
+ #include <linux/tracehook.h>
+ #include <linux/rcupdate.h>
++#include <generated/package.h>
+
+ #include <asm/cpu.h>
+ #include <asm/delay.h>
+@@ -104,9 +105,9 @@ show_regs (struct pt_regs *regs)
+ print_modules();
+ printk("\n");
+ show_regs_print_info(KERN_DEFAULT);
+- printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n",
++ printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s%s)\n",
+ regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(),
+- init_utsname()->release);
++ init_utsname()->release, LINUX_PACKAGE_ID);
+ printk("ip is at %pS\n", (void *)ip);
+ printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
+ regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
+Index: linux/arch/powerpc/kernel/process.c
+===================================================================
+--- linux.orig/arch/powerpc/kernel/process.c
++++ linux/arch/powerpc/kernel/process.c
+@@ -43,6 +43,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/elf-randomize.h>
+ #include <linux/pkeys.h>
++#include <generated/package.h>
+
+ #include <asm/pgtable.h>
+ #include <asm/io.h>
+@@ -1424,8 +1425,9 @@ void show_regs(struct pt_regs * regs)
+
+ printk("NIP: "REG" LR: "REG" CTR: "REG"\n",
+ regs->nip, regs->link, regs->ctr);
+- printk("REGS: %px TRAP: %04lx %s (%s)\n",
+- regs, regs->trap, print_tainted(), init_utsname()->release);
++ printk("REGS: %px TRAP: %04lx %s (%s%s)\n",
++ regs, regs->trap, print_tainted(), init_utsname()->release,
++ LINUX_PACKAGE_ID);
+ printk("MSR: "REG" ", regs->msr);
+ print_msr_bits(regs->msr);
+ pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer);
+Index: linux/kernel/hung_task.c
+===================================================================
+--- linux.orig/kernel/hung_task.c
++++ linux/kernel/hung_task.c
+@@ -21,6 +21,7 @@
+ #include <linux/sched/debug.h>
+
+ #include <trace/events/sched.h>
++#include <generated/package.h>
+
+ /*
+ * The number of tasks checked:
+@@ -127,10 +128,11 @@ static void check_hung_task(struct task_
+ sysctl_hung_task_warnings--;
+ pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n",
+ t->comm, t->pid, timeout);
+- pr_err(" %s %s %.*s\n",
++ pr_err(" %s %s %.*s%s\n",
+ print_tainted(), init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+- init_utsname()->version);
++ init_utsname()->version,
++ LINUX_PACKAGE_ID);
+ pr_err("\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\""
+ " disables this message.\n");
+ sched_show_task(t);
+Index: linux/lib/dump_stack.c
+===================================================================
+--- linux.orig/lib/dump_stack.c
++++ linux/lib/dump_stack.c
+@@ -12,6 +12,7 @@
+ #include <linux/atomic.h>
+ #include <linux/kexec.h>
+ #include <linux/utsname.h>
++#include <generated/package.h>
+
+ static char dump_stack_arch_desc_str[128];
+
+@@ -44,13 +45,14 @@ void __init dump_stack_set_arch_desc(con
+ */
+ void dump_stack_print_info(const char *log_lvl)
+ {
+- printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s\n",
++ printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s%s\n",
+ log_lvl, raw_smp_processor_id(), current->pid, current->comm,
+ kexec_crash_loaded() ? "Kdump: loaded " : "",
+ print_tainted(),
+ init_utsname()->release,
+ (int)strcspn(init_utsname()->version, " "),
+- init_utsname()->version);
++ init_utsname()->version,
++ LINUX_PACKAGE_ID);
+
+ if (dump_stack_arch_desc_str[0] != '\0')
+ printk("%sHardware name: %s\n",
diff --git a/debian/patches/debian/wireless-add-debian-wireless-regdb-certificates.patch b/debian/patches/debian/wireless-add-debian-wireless-regdb-certificates.patch
new file mode 100644
index 000000000..112683839
--- /dev/null
+++ b/debian/patches/debian/wireless-add-debian-wireless-regdb-certificates.patch
@@ -0,0 +1,963 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 13 Apr 2018 20:10:28 +0100
+Subject: wireless: Add Debian wireless-regdb certificates
+Forwarded: not-needed
+
+This hex dump is generated using:
+
+{
+ for cert in debian/certs/wireless-regdb-*.pem; do
+ openssl x509 -in $cert -outform der;
+ done
+} | hexdump -v -e '1/1 "0x%.2x," "\n"' > net/wireless/certs/debian.hex
+
+---
+Index: linux/net/wireless/certs/debian.hex
+===================================================================
+--- /dev/null
++++ linux/net/wireless/certs/debian.hex
+@@ -0,0 +1,944 @@
++0x30,
++0x82,
++0x03,
++0xac,
++0x30,
++0x82,
++0x02,
++0x94,
++0xa0,
++0x03,
++0x02,
++0x01,
++0x02,
++0x02,
++0x09,
++0x00,
++0xd9,
++0xb1,
++0xe4,
++0x6f,
++0x28,
++0xf3,
++0xd4,
++0x97,
++0x30,
++0x0d,
++0x06,
++0x09,
++0x2a,
++0x86,
++0x48,
++0x86,
++0xf7,
++0x0d,
++0x01,
++0x01,
++0x0b,
++0x05,
++0x00,
++0x30,
++0x6b,
++0x31,
++0x0b,
++0x30,
++0x09,
++0x06,
++0x03,
++0x55,
++0x04,
++0x06,
++0x13,
++0x02,
++0x47,
++0x42,
++0x31,
++0x13,
++0x30,
++0x11,
++0x06,
++0x03,
++0x55,
++0x04,
++0x07,
++0x0c,
++0x0a,
++0x4d,
++0x61,
++0x6e,
++0x63,
++0x68,
++0x65,
++0x73,
++0x74,
++0x65,
++0x72,
++0x31,
++0x0f,
++0x30,
++0x0d,
++0x06,
++0x03,
++0x55,
++0x04,
++0x0a,
++0x0c,
++0x06,
++0x44,
++0x65,
++0x62,
++0x69,
++0x61,
++0x6e,
++0x31,
++0x16,
++0x30,
++0x14,
++0x06,
++0x03,
++0x55,
++0x04,
++0x03,
++0x0c,
++0x0d,
++0x42,
++0x65,
++0x6e,
++0x20,
++0x48,
++0x75,
++0x74,
++0x63,
++0x68,
++0x69,
++0x6e,
++0x67,
++0x73,
++0x31,
++0x1e,
++0x30,
++0x1c,
++0x06,
++0x09,
++0x2a,
++0x86,
++0x48,
++0x86,
++0xf7,
++0x0d,
++0x01,
++0x09,
++0x01,
++0x16,
++0x0f,
++0x62,
++0x65,
++0x6e,
++0x68,
++0x40,
++0x64,
++0x65,
++0x62,
++0x69,
++0x61,
++0x6e,
++0x2e,
++0x6f,
++0x72,
++0x67,
++0x30,
++0x1e,
++0x17,
++0x0d,
++0x31,
++0x38,
++0x30,
++0x34,
++0x31,
++0x33,
++0x31,
++0x38,
++0x32,
++0x31,
++0x34,
++0x36,
++0x5a,
++0x17,
++0x0d,
++0x31,
++0x38,
++0x30,
++0x35,
++0x31,
++0x33,
++0x31,
++0x38,
++0x32,
++0x31,
++0x34,
++0x36,
++0x5a,
++0x30,
++0x6b,
++0x31,
++0x0b,
++0x30,
++0x09,
++0x06,
++0x03,
++0x55,
++0x04,
++0x06,
++0x13,
++0x02,
++0x47,
++0x42,
++0x31,
++0x13,
++0x30,
++0x11,
++0x06,
++0x03,
++0x55,
++0x04,
++0x07,
++0x0c,
++0x0a,
++0x4d,
++0x61,
++0x6e,
++0x63,
++0x68,
++0x65,
++0x73,
++0x74,
++0x65,
++0x72,
++0x31,
++0x0f,
++0x30,
++0x0d,
++0x06,
++0x03,
++0x55,
++0x04,
++0x0a,
++0x0c,
++0x06,
++0x44,
++0x65,
++0x62,
++0x69,
++0x61,
++0x6e,
++0x31,
++0x16,
++0x30,
++0x14,
++0x06,
++0x03,
++0x55,
++0x04,
++0x03,
++0x0c,
++0x0d,
++0x42,
++0x65,
++0x6e,
++0x20,
++0x48,
++0x75,
++0x74,
++0x63,
++0x68,
++0x69,
++0x6e,
++0x67,
++0x73,
++0x31,
++0x1e,
++0x30,
++0x1c,
++0x06,
++0x09,
++0x2a,
++0x86,
++0x48,
++0x86,
++0xf7,
++0x0d,
++0x01,
++0x09,
++0x01,
++0x16,
++0x0f,
++0x62,
++0x65,
++0x6e,
++0x68,
++0x40,
++0x64,
++0x65,
++0x62,
++0x69,
++0x61,
++0x6e,
++0x2e,
++0x6f,
++0x72,
++0x67,
++0x30,
++0x82,
++0x01,
++0x22,
++0x30,
++0x0d,
++0x06,
++0x09,
++0x2a,
++0x86,
++0x48,
++0x86,
++0xf7,
++0x0d,
++0x01,
++0x01,
++0x01,
++0x05,
++0x00,
++0x03,
++0x82,
++0x01,
++0x0f,
++0x00,
++0x30,
++0x82,
++0x01,
++0x0a,
++0x02,
++0x82,
++0x01,
++0x01,
++0x00,
++0x9d,
++0xe1,
++0x77,
++0xa0,
++0x24,
++0xa0,
++0xd5,
++0x79,
++0x65,
++0x3a,
++0x07,
++0x90,
++0xc9,
++0xf6,
++0xa5,
++0xa6,
++0x1f,
++0x84,
++0x1c,
++0x23,
++0x07,
++0x4b,
++0x4f,
++0xa5,
++0x03,
++0xc6,
++0x0f,
++0xf7,
++0x54,
++0xd5,
++0x8b,
++0x7e,
++0x79,
++0x81,
++0x00,
++0xd2,
++0xe9,
++0x3d,
++0xf4,
++0x97,
++0xfe,
++0x84,
++0xcd,
++0x55,
++0xbd,
++0xc9,
++0x8f,
++0x21,
++0x57,
++0x88,
++0x06,
++0x39,
++0x90,
++0x66,
++0x41,
++0x26,
++0x79,
++0x2c,
++0xca,
++0x3f,
++0x95,
++0x87,
++0x01,
++0x11,
++0x2f,
++0x2f,
++0xb0,
++0xe1,
++0x0b,
++0x43,
++0xfc,
++0x5f,
++0x2f,
++0x4f,
++0x67,
++0x04,
++0xdb,
++0x4d,
++0xb7,
++0x72,
++0x4d,
++0xd1,
++0xc5,
++0x76,
++0x73,
++0x4d,
++0x91,
++0x69,
++0xb0,
++0x71,
++0x17,
++0x36,
++0xea,
++0xab,
++0x0a,
++0x3a,
++0xcd,
++0x95,
++0x9b,
++0x76,
++0x1b,
++0x8e,
++0x21,
++0x17,
++0x8f,
++0xc5,
++0x02,
++0xbf,
++0x24,
++0xc7,
++0xc0,
++0x40,
++0xb1,
++0x3b,
++0xc4,
++0x80,
++0x7c,
++0x71,
++0xa5,
++0x51,
++0xdc,
++0xf7,
++0x3a,
++0x58,
++0x7f,
++0xb1,
++0x07,
++0x81,
++0x8a,
++0x10,
++0xd1,
++0xf6,
++0x93,
++0x17,
++0x71,
++0xe0,
++0xfa,
++0x51,
++0x79,
++0x15,
++0xd4,
++0xd7,
++0x8f,
++0xad,
++0xbd,
++0x6f,
++0x38,
++0xe1,
++0x26,
++0x7d,
++0xbc,
++0xf0,
++0x3e,
++0x80,
++0x89,
++0xb4,
++0xec,
++0x8e,
++0x69,
++0x90,
++0xdb,
++0x97,
++0x8a,
++0xf0,
++0x23,
++0x23,
++0x83,
++0x82,
++0x3b,
++0x6a,
++0xb1,
++0xac,
++0xeb,
++0xe7,
++0x99,
++0x74,
++0x2a,
++0x35,
++0x8e,
++0xa9,
++0x64,
++0xfd,
++0x46,
++0x9e,
++0xe8,
++0xe5,
++0x48,
++0x61,
++0x31,
++0x6e,
++0xe6,
++0xfc,
++0x19,
++0x18,
++0x54,
++0xc3,
++0x1b,
++0x4f,
++0xd6,
++0x00,
++0x44,
++0x87,
++0x1c,
++0x37,
++0x45,
++0xea,
++0xf5,
++0xc9,
++0xcb,
++0x0f,
++0x0c,
++0x55,
++0xec,
++0xcf,
++0x6a,
++0xc2,
++0x45,
++0x26,
++0x23,
++0xa2,
++0x31,
++0x52,
++0x4d,
++0xee,
++0x21,
++0x7d,
++0xfd,
++0x58,
++0x72,
++0xc2,
++0x28,
++0xc5,
++0x8e,
++0xa9,
++0xd0,
++0xee,
++0x01,
++0x77,
++0x08,
++0xa5,
++0xf0,
++0x22,
++0x2b,
++0x47,
++0x79,
++0x2b,
++0xcf,
++0x9a,
++0x46,
++0xb5,
++0x8f,
++0xfd,
++0x64,
++0xa2,
++0xb5,
++0xed,
++0x02,
++0x03,
++0x01,
++0x00,
++0x01,
++0xa3,
++0x53,
++0x30,
++0x51,
++0x30,
++0x1d,
++0x06,
++0x03,
++0x55,
++0x1d,
++0x0e,
++0x04,
++0x16,
++0x04,
++0x14,
++0xd3,
++0xfb,
++0x2d,
++0xdb,
++0xf0,
++0x8e,
++0xfa,
++0x67,
++0x6d,
++0x2f,
++0x21,
++0x99,
++0x4c,
++0xeb,
++0x41,
++0x59,
++0xe6,
++0x9d,
++0xd8,
++0xd5,
++0x30,
++0x1f,
++0x06,
++0x03,
++0x55,
++0x1d,
++0x23,
++0x04,
++0x18,
++0x30,
++0x16,
++0x80,
++0x14,
++0xd3,
++0xfb,
++0x2d,
++0xdb,
++0xf0,
++0x8e,
++0xfa,
++0x67,
++0x6d,
++0x2f,
++0x21,
++0x99,
++0x4c,
++0xeb,
++0x41,
++0x59,
++0xe6,
++0x9d,
++0xd8,
++0xd5,
++0x30,
++0x0f,
++0x06,
++0x03,
++0x55,
++0x1d,
++0x13,
++0x01,
++0x01,
++0xff,
++0x04,
++0x05,
++0x30,
++0x03,
++0x01,
++0x01,
++0xff,
++0x30,
++0x0d,
++0x06,
++0x09,
++0x2a,
++0x86,
++0x48,
++0x86,
++0xf7,
++0x0d,
++0x01,
++0x01,
++0x0b,
++0x05,
++0x00,
++0x03,
++0x82,
++0x01,
++0x01,
++0x00,
++0x71,
++0x71,
++0xe4,
++0xcd,
++0x40,
++0x84,
++0xf3,
++0x60,
++0x34,
++0x6a,
++0x78,
++0xdc,
++0xe7,
++0x81,
++0x20,
++0x8f,
++0x1e,
++0x7f,
++0x54,
++0x31,
++0x8e,
++0x4a,
++0xe5,
++0x69,
++0x91,
++0x1c,
++0x4c,
++0x77,
++0x00,
++0x47,
++0x09,
++0x98,
++0x91,
++0xf4,
++0x27,
++0x52,
++0x9a,
++0x2d,
++0x30,
++0x87,
++0x4c,
++0x51,
++0x51,
++0x1f,
++0xae,
++0xd8,
++0x8c,
++0xdb,
++0x3c,
++0x73,
++0x06,
++0x43,
++0xc6,
++0x1f,
++0x3a,
++0xba,
++0xaf,
++0x9e,
++0xd2,
++0xeb,
++0x3e,
++0x9f,
++0xd1,
++0xb2,
++0x8a,
++0xa2,
++0x16,
++0x08,
++0x26,
++0xa1,
++0x39,
++0x0c,
++0x63,
++0xe7,
++0x2d,
++0x78,
++0x9c,
++0xac,
++0x2c,
++0x4e,
++0x69,
++0xd5,
++0xa0,
++0xfd,
++0xbd,
++0xea,
++0x95,
++0xfe,
++0xe2,
++0x69,
++0x06,
++0xe1,
++0xb2,
++0x27,
++0x90,
++0x68,
++0xd8,
++0x3a,
++0xac,
++0xd6,
++0xa0,
++0x4e,
++0xe2,
++0x8a,
++0xfa,
++0xff,
++0x9c,
++0x98,
++0x6b,
++0x60,
++0x83,
++0xea,
++0xe7,
++0x46,
++0x24,
++0x09,
++0x21,
++0x12,
++0xa8,
++0xfe,
++0xaa,
++0x46,
++0x0d,
++0x24,
++0xa5,
++0xcf,
++0x52,
++0x37,
++0x48,
++0xb9,
++0xe2,
++0xb1,
++0xd6,
++0xb0,
++0xe4,
++0xbf,
++0x6f,
++0x59,
++0x7b,
++0x17,
++0x9e,
++0xdd,
++0x24,
++0x00,
++0xee,
++0xc6,
++0x89,
++0x76,
++0xe9,
++0x35,
++0x40,
++0x1f,
++0xeb,
++0x7d,
++0x23,
++0x8c,
++0xed,
++0x13,
++0x6c,
++0x66,
++0xbc,
++0xc4,
++0x88,
++0xb5,
++0x55,
++0x9a,
++0xec,
++0xbd,
++0x52,
++0x0d,
++0x0b,
++0xc5,
++0x40,
++0xe1,
++0xfe,
++0xb7,
++0x20,
++0xb1,
++0x22,
++0x16,
++0x32,
++0xed,
++0x28,
++0x3e,
++0x1f,
++0xbf,
++0xf2,
++0x00,
++0x12,
++0x75,
++0x92,
++0xd7,
++0x99,
++0x2e,
++0x25,
++0xfb,
++0xf2,
++0xe6,
++0xfd,
++0x2a,
++0x10,
++0xd1,
++0x75,
++0x89,
++0x31,
++0x52,
++0xe4,
++0xb2,
++0xc2,
++0xee,
++0xcd,
++0x41,
++0xa3,
++0x08,
++0x48,
++0x18,
++0x5e,
++0x66,
++0x42,
++0x67,
++0xcf,
++0x0b,
++0x2a,
++0x26,
++0x6b,
++0x65,
++0x87,
++0x4d,
++0xfa,
++0x04,
++0x51,
++0xec,
++0xed,
++0x03,
++0x8b,
++0x38,
++0x52,
++0x93,
++0x6d,
++0xc4,
++0x30,
++0x41,
++0x9a,
++0x6c,
++0x28,
++0x35,
++0xf0,
++0x87,
++0x15,
++0xce,
++0x78,
++0x4f,
++0x32,
++0xca,
++0x52,
++0xed,
diff --git a/debian/patches/debian/wireless-disable-regulatory.db-direct-loading.patch b/debian/patches/debian/wireless-disable-regulatory.db-direct-loading.patch
new file mode 100644
index 000000000..6815dc947
--- /dev/null
+++ b/debian/patches/debian/wireless-disable-regulatory.db-direct-loading.patch
@@ -0,0 +1,75 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 05 Apr 2018 18:13:52 +0200
+Subject: wireless: Disable regulatory.db direct loading
+Forwarded: not-needed
+Bug-Debian: https://bugs.debian.org/892229
+
+Don't complain about being unable to load regulatory.db directly.
+This is expected until we generate a signing key and update
+wireless-regdb to be signed with it.
+
+Index: linux/net/wireless/reg.c
+===================================================================
+--- linux.orig/net/wireless/reg.c
++++ linux/net/wireless/reg.c
+@@ -476,6 +476,7 @@ static void reg_regdb_apply(struct work_
+
+ static DECLARE_WORK(reg_regdb_work, reg_regdb_apply);
+
++#if 0
+ static int reg_schedule_apply(const struct ieee80211_regdomain *regdom)
+ {
+ struct reg_regdb_apply_request *request;
+@@ -495,6 +496,7 @@ static int reg_schedule_apply(const stru
+ schedule_work(&reg_regdb_work);
+ return 0;
+ }
++#endif
+
+ #ifdef CONFIG_CFG80211_CRDA_SUPPORT
+ /* Max number of consecutive attempts to communicate with CRDA */
+@@ -574,6 +576,35 @@ static inline int call_crda(const char *
+ /* code to directly load a firmware database through request_firmware */
+ static const struct fwdb_header *regdb;
+
++#if 1
++
++static int load_builtin_regdb_keys(void)
++{
++ return 0;
++}
++
++static void free_regdb_keyring(void)
++{
++}
++
++static int query_regdb_file(const char *alpha2)
++{
++ return -ENOENT;
++}
++
++int reg_reload_regdb(void)
++{
++ return -ENOENT;
++}
++
++int reg_query_regdb_wmm(char *alpha2, int freq, struct ieee80211_reg_rule *rule)
++{
++ return -ENODATA;
++}
++EXPORT_SYMBOL(reg_query_regdb_wmm);
++
++#else /* disabled until we update wireless-regdb */
++
+ struct fwdb_country {
+ u8 alpha2[2];
+ __be16 coll_ptr;
+@@ -1090,6 +1121,8 @@ int reg_reload_regdb(void)
+ return err;
+ }
+
++#endif
++
+ static bool reg_query_database(struct regulatory_request *request)
+ {
+ if (query_regdb_file(request->alpha2) == 0)
diff --git a/debian/patches/debian/yama-disable-by-default.patch b/debian/patches/debian/yama-disable-by-default.patch
new file mode 100644
index 000000000..f35a598ae
--- /dev/null
+++ b/debian/patches/debian/yama-disable-by-default.patch
@@ -0,0 +1,28 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: yama: Disable by default
+Date: Wed, 19 Jun 2013 04:35:28 +0100
+Bug-Debian: https://bugs.debian.org/712740
+Forwarded: not-needed
+
+Index: linux/security/yama/yama_lsm.c
+===================================================================
+--- linux.orig/security/yama/yama_lsm.c
++++ linux/security/yama/yama_lsm.c
+@@ -28,7 +28,7 @@
+ #define YAMA_SCOPE_CAPABILITY 2
+ #define YAMA_SCOPE_NO_ATTACH 3
+
+-static int ptrace_scope = YAMA_SCOPE_RELATIONAL;
++static int ptrace_scope = YAMA_SCOPE_DISABLED;
+
+ /* describe a ptrace relationship for potential exception */
+ struct ptrace_relation {
+@@ -481,7 +481,7 @@ static inline void yama_init_sysctl(void
+
+ void __init yama_add_hooks(void)
+ {
+- pr_info("Yama: becoming mindful.\n");
++ pr_info("Yama: disabled by default; enable with sysctl kernel.yama.*\n");
+ security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama");
+ yama_init_sysctl();
+ }
diff --git a/debian/patches/features/all/aufs4/aufs4-base.patch b/debian/patches/features/all/aufs4/aufs4-base.patch
new file mode 100644
index 000000000..c0e036a73
--- /dev/null
+++ b/debian/patches/features/all/aufs4/aufs4-base.patch
@@ -0,0 +1,328 @@
+From: J. R. Okajima <hooanon05@yahoo.co.jp>
+Date: Tue Sep 3 14:14:09 2019 +0900
+Subject: aufs4.19.63+ base patch
+Origin: https://github.com/sfjro/aufs4-standalone/tree/6c582cc629cbfb4fac5bfc7d20db128c7d201da6
+Bug-Debian: https://bugs.debian.org/541828
+
+Patch headers added by debian/bin/genpatch-aufs
+
+SPDX-License-Identifier: GPL-2.0
+aufs4.19.63+ base patch
+
+diff --git a/MAINTAINERS b/MAINTAINERS
+index 11a59e82d92e..573d5b42b28b 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -2605,6 +2605,19 @@ F: include/linux/audit.h
+ F: include/uapi/linux/audit.h
+ F: kernel/audit*
+
++AUFS (advanced multi layered unification filesystem) FILESYSTEM
++M: "J. R. Okajima" <hooanon05g@gmail.com>
++L: aufs-users@lists.sourceforge.net (members only)
++L: linux-unionfs@vger.kernel.org
++W: http://aufs.sourceforge.net
++T: git://github.com/sfjro/aufs4-linux.git
++S: Supported
++F: Documentation/filesystems/aufs/
++F: Documentation/ABI/testing/debugfs-aufs
++F: Documentation/ABI/testing/sysfs-aufs
++F: fs/aufs/
++F: include/uapi/linux/aufs_type.h
++
+ AUXILIARY DISPLAY DRIVERS
+ M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com>
+ S: Maintained
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index f1e63eb7cbca..b732df5f14f3 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -739,6 +739,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
+ return error;
+ }
+
++/*
++ * for AUFS
++ * no get/put for file.
++ */
++struct file *loop_backing_file(struct super_block *sb)
++{
++ struct file *ret;
++ struct loop_device *l;
++
++ ret = NULL;
++ if (MAJOR(sb->s_dev) == LOOP_MAJOR) {
++ l = sb->s_bdev->bd_disk->private_data;
++ ret = l->lo_backing_file;
++ }
++ return ret;
++}
++EXPORT_SYMBOL_GPL(loop_backing_file);
++
+ /* loop sysfs attributes */
+
+ static ssize_t loop_attr_show(struct device *dev, char *page,
+diff --git a/fs/dcache.c b/fs/dcache.c
+index 6e0022326afe..3bd53094ac3d 100644
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -1234,7 +1234,7 @@ enum d_walk_ret {
+ *
+ * The @enter() callbacks are called with d_lock held.
+ */
+-static void d_walk(struct dentry *parent, void *data,
++void d_walk(struct dentry *parent, void *data,
+ enum d_walk_ret (*enter)(void *, struct dentry *))
+ {
+ struct dentry *this_parent;
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index 4137d96534a6..c91b3e3c4580 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -32,7 +32,7 @@
+
+ #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
+
+-static int setfl(int fd, struct file * filp, unsigned long arg)
++int setfl(int fd, struct file * filp, unsigned long arg)
+ {
+ struct inode * inode = file_inode(filp);
+ int error = 0;
+@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
+
+ if (filp->f_op->check_flags)
+ error = filp->f_op->check_flags(arg);
++ if (!error && filp->f_op->setfl)
++ error = filp->f_op->setfl(filp, arg);
+ if (error)
+ return error;
+
+diff --git a/fs/inode.c b/fs/inode.c
+index 5c63693326bb..43046d7223e4 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(generic_update_time);
+ * This does the actual work of updating an inodes time or version. Must have
+ * had called mnt_want_write() before calling this.
+ */
+-static int update_time(struct inode *inode, struct timespec64 *time, int flags)
++int update_time(struct inode *inode, struct timespec64 *time, int flags)
+ {
+ int (*update_time)(struct inode *, struct timespec64 *, int);
+
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 1fce41ba3535..fbd7edd49a2f 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -770,6 +770,12 @@ static inline int check_mnt(struct mount *mnt)
+ return mnt->mnt_ns == current->nsproxy->mnt_ns;
+ }
+
++/* for aufs, CONFIG_AUFS_BR_FUSE */
++int is_current_mnt_ns(struct vfsmount *mnt)
++{
++ return check_mnt(real_mount(mnt));
++}
++
+ /*
+ * vfsmount lock must be held for write
+ */
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 85fd7a8ee29e..c1335b4f19c0 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -489,6 +489,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count,
+ return -EINVAL;
+ }
+
++vfs_readf_t vfs_readf(struct file *file)
++{
++ const struct file_operations *fop = file->f_op;
++
++ if (fop->read)
++ return fop->read;
++ if (fop->read_iter)
++ return new_sync_read;
++ return ERR_PTR(-ENOSYS);
++}
++
++vfs_writef_t vfs_writef(struct file *file)
++{
++ const struct file_operations *fop = file->f_op;
++
++ if (fop->write)
++ return fop->write;
++ if (fop->write_iter)
++ return new_sync_write;
++ return ERR_PTR(-ENOSYS);
++}
++
+ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
+ {
+ mm_segment_t old_fs;
+diff --git a/fs/splice.c b/fs/splice.c
+index 485e409ef841..b2c2d320565b 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -838,8 +838,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+ /*
+ * Attempt to initiate a splice from pipe to file.
+ */
+-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+- loff_t *ppos, size_t len, unsigned int flags)
++long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
++ loff_t *ppos, size_t len, unsigned int flags)
+ {
+ ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
+ loff_t *, size_t, unsigned int);
+@@ -855,9 +855,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+ /*
+ * Attempt to initiate a splice from a file to a pipe.
+ */
+-static long do_splice_to(struct file *in, loff_t *ppos,
+- struct pipe_inode_info *pipe, size_t len,
+- unsigned int flags)
++long do_splice_to(struct file *in, loff_t *ppos,
++ struct pipe_inode_info *pipe, size_t len,
++ unsigned int flags)
+ {
+ ssize_t (*splice_read)(struct file *, loff_t *,
+ struct pipe_inode_info *, size_t, unsigned int);
+diff --git a/fs/sync.c b/fs/sync.c
+index b54e0541ad89..28607828e96f 100644
+--- a/fs/sync.c
++++ b/fs/sync.c
+@@ -28,7 +28,7 @@
+ * wait == 1 case since in that case write_inode() functions do
+ * sync_dirty_buffer() and thus effectively write one block at a time.
+ */
+-static int __sync_filesystem(struct super_block *sb, int wait)
++int __sync_filesystem(struct super_block *sb, int wait)
+ {
+ if (wait)
+ sync_inodes_sb(sb);
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 92420009b9bc..ecad33c40cae 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1295,6 +1295,7 @@ extern void fasync_free(struct fasync_struct *);
+ /* can be called from interrupts */
+ extern void kill_fasync(struct fasync_struct **, int, int);
+
++extern int setfl(int fd, struct file * filp, unsigned long arg);
+ extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force);
+ extern int f_setown(struct file *filp, unsigned long arg, int force);
+ extern void f_delown(struct file *filp);
+@@ -1759,6 +1760,7 @@ struct file_operations {
+ ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
+ unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+ int (*check_flags)(int);
++ int (*setfl)(struct file *, unsigned long);
+ int (*flock) (struct file *, int, struct file_lock *);
+ ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
+ ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
+@@ -1830,6 +1832,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+ struct iovec *fast_pointer,
+ struct iovec **ret_pointer);
+
++typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *);
++typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t,
++ loff_t *);
++vfs_readf_t vfs_readf(struct file *file);
++vfs_writef_t vfs_writef(struct file *file);
++
+ extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *);
+ extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *);
+ extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *);
+@@ -2255,6 +2263,7 @@ extern int current_umask(void);
+ extern void ihold(struct inode * inode);
+ extern void iput(struct inode *);
+ extern int generic_update_time(struct inode *, struct timespec64 *, int);
++extern int update_time(struct inode *, struct timespec64 *, int);
+
+ /* /sys/fs */
+ extern struct kobject *fs_kobj;
+@@ -2542,6 +2551,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb)
+ return false;
+ }
+ #endif
++extern int __sync_filesystem(struct super_block *, int);
+ extern int sync_filesystem(struct super_block *);
+ extern const struct file_operations def_blk_fops;
+ extern const struct file_operations def_chr_fops;
+diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
+index b0d0b51c4d85..f73ffaa0199e 100644
+--- a/include/linux/lockdep.h
++++ b/include/linux/lockdep.h
+@@ -313,6 +313,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock,
+ return lock->key == key;
+ }
+
++struct lock_class *lockdep_hlock_class(struct held_lock *hlock);
++
+ /*
+ * Acquire a lock.
+ *
+@@ -439,6 +441,7 @@ struct lockdep_map { };
+
+ #define lockdep_depth(tsk) (0)
+
++#define lockdep_is_held(lock) (1)
+ #define lockdep_is_held_type(l, r) (1)
+
+ #define lockdep_assert_held(l) do { (void)(l); } while (0)
+diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h
+index 35942084cd40..24f5fd1a789d 100644
+--- a/include/linux/mnt_namespace.h
++++ b/include/linux/mnt_namespace.h
+@@ -6,11 +6,14 @@
+ struct mnt_namespace;
+ struct fs_struct;
+ struct user_namespace;
++struct vfsmount;
+
+ extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *,
+ struct user_namespace *, struct fs_struct *);
+ extern void put_mnt_ns(struct mnt_namespace *ns);
+
++extern int is_current_mnt_ns(struct vfsmount *mnt);
++
+ extern const struct file_operations proc_mounts_operations;
+ extern const struct file_operations proc_mountinfo_operations;
+ extern const struct file_operations proc_mountstats_operations;
+diff --git a/include/linux/splice.h b/include/linux/splice.h
+index 74b4911ac16d..19789fbea567 100644
+--- a/include/linux/splice.h
++++ b/include/linux/splice.h
+@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *);
+
+ extern const struct pipe_buf_operations page_cache_pipe_buf_ops;
+ extern const struct pipe_buf_operations default_pipe_buf_ops;
++
++extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
++ loff_t *ppos, size_t len, unsigned int flags);
++extern long do_splice_to(struct file *in, loff_t *ppos,
++ struct pipe_inode_info *pipe, size_t len,
++ unsigned int flags);
+ #endif
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index e810e8cb17e1..d0c9931e6531 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -140,7 +140,7 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES];
+ unsigned long nr_lock_classes;
+ static struct lock_class lock_classes[MAX_LOCKDEP_KEYS];
+
+-static inline struct lock_class *hlock_class(struct held_lock *hlock)
++inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
+ {
+ if (!hlock->class_idx) {
+ /*
+@@ -151,6 +151,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock)
+ }
+ return lock_classes + hlock->class_idx - 1;
+ }
++#define hlock_class(hlock) lockdep_hlock_class(hlock)
+
+ #ifdef CONFIG_LOCK_STAT
+ static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats);
diff --git a/debian/patches/features/all/aufs4/aufs4-mmap.patch b/debian/patches/features/all/aufs4/aufs4-mmap.patch
new file mode 100644
index 000000000..98fe007a8
--- /dev/null
+++ b/debian/patches/features/all/aufs4/aufs4-mmap.patch
@@ -0,0 +1,406 @@
+From: J. R. Okajima <hooanon05@yahoo.co.jp>
+Date: Tue Sep 3 14:14:09 2019 +0900
+Subject: aufs4.19.63+ mmap patch
+Origin: https://github.com/sfjro/aufs4-standalone/tree/6c582cc629cbfb4fac5bfc7d20db128c7d201da6
+Bug-Debian: https://bugs.debian.org/541828
+
+Patch headers added by debian/bin/genpatch-aufs
+
+SPDX-License-Identifier: GPL-2.0
+aufs4.19.63+ mmap patch
+
+diff --git a/fs/proc/base.c b/fs/proc/base.c
+index a7fbda72afeb..9c8439a01c5b 100644
+--- a/fs/proc/base.c
++++ b/fs/proc/base.c
+@@ -2018,7 +2018,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path)
+ rc = -ENOENT;
+ vma = find_exact_vma(mm, vm_start, vm_end);
+ if (vma && vma->vm_file) {
+- *path = vma->vm_file->f_path;
++ *path = vma_pr_or_file(vma)->f_path;
+ path_get(path);
+ rc = 0;
+ }
+diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c
+index 3b63be64e436..fb9913bf3d10 100644
+--- a/fs/proc/nommu.c
++++ b/fs/proc/nommu.c
+@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region)
+ file = region->vm_file;
+
+ if (file) {
+- struct inode *inode = file_inode(region->vm_file);
++ struct inode *inode;
++
++ file = vmr_pr_or_file(region);
++ inode = file_inode(file);
+ dev = inode->i_sb->s_dev;
+ ino = inode->i_ino;
+ }
+diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
+index 71aba44c4fa6..87cdce66a3f4 100644
+--- a/fs/proc/task_mmu.c
++++ b/fs/proc/task_mmu.c
+@@ -309,7 +309,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
+ const char *name = NULL;
+
+ if (file) {
+- struct inode *inode = file_inode(vma->vm_file);
++ struct inode *inode;
++
++ file = vma_pr_or_file(vma);
++ inode = file_inode(file);
+ dev = inode->i_sb->s_dev;
+ ino = inode->i_ino;
+ pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
+@@ -1766,7 +1769,7 @@ static int show_numa_map(struct seq_file *m, void *v)
+ struct proc_maps_private *proc_priv = &numa_priv->proc_maps;
+ struct vm_area_struct *vma = v;
+ struct numa_maps *md = &numa_priv->md;
+- struct file *file = vma->vm_file;
++ struct file *file = vma_pr_or_file(vma);
+ struct mm_struct *mm = vma->vm_mm;
+ struct mm_walk walk = {
+ .hugetlb_entry = gather_hugetlb_stats,
+diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
+index 5161894a6d62..b6d13cce45f3 100644
+--- a/fs/proc/task_nommu.c
++++ b/fs/proc/task_nommu.c
+@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma)
+ file = vma->vm_file;
+
+ if (file) {
+- struct inode *inode = file_inode(vma->vm_file);
++ struct inode *inode;
++
++ file = vma_pr_or_file(vma);
++ inode = file_inode(file);
+ dev = inode->i_sb->s_dev;
+ ino = inode->i_ino;
+ pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT;
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index bdec425c8e14..88cb95dc57dd 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1453,6 +1453,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
+ unmap_mapping_range(mapping, holebegin, holelen, 0);
+ }
+
++extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int);
++extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[],
++ int);
++extern void vma_do_get_file(struct vm_area_struct *, const char[], int);
++extern void vma_do_fput(struct vm_area_struct *, const char[], int);
++
++#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \
++ __LINE__)
++#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \
++ __LINE__)
++#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__)
++#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__)
++
++#ifndef CONFIG_MMU
++extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int);
++extern void vmr_do_fput(struct vm_region *, const char[], int);
++
++#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \
++ __LINE__)
++#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__)
++#endif /* !CONFIG_MMU */
++
+ extern int access_process_vm(struct task_struct *tsk, unsigned long addr,
+ void *buf, int len, unsigned int gup_flags);
+ extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index 5ed8f6292a53..01229754077f 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -239,6 +239,7 @@ struct vm_region {
+ unsigned long vm_top; /* region allocated to here */
+ unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */
+ struct file *vm_file; /* the backing file or NULL */
++ struct file *vm_prfile; /* the virtual backing file or NULL */
+
+ int vm_usage; /* region usage count (access under nommu_region_sem) */
+ bool vm_icache_flushed : 1; /* true if the icache has been flushed for
+@@ -313,6 +314,7 @@ struct vm_area_struct {
+ unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
+ units */
+ struct file * vm_file; /* File we map to (can be NULL). */
++ struct file *vm_prfile; /* shadow of vm_file */
+ void * vm_private_data; /* was vm_pte (shared mem) */
+
+ atomic_long_t swap_readahead_info;
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 69874db3fba8..757620e64e7b 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -505,7 +505,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm,
+ struct inode *inode = file_inode(file);
+ struct address_space *mapping = file->f_mapping;
+
+- get_file(file);
++ vma_get_file(tmp);
+ if (tmp->vm_flags & VM_DENYWRITE)
+ atomic_dec(&inode->i_writecount);
+ i_mmap_lock_write(mapping);
+diff --git a/mm/Makefile b/mm/Makefile
+index 26ef77a3883b..b2869af1ef08 100644
+--- a/mm/Makefile
++++ b/mm/Makefile
+@@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \
+ mm_init.o mmu_context.o percpu.o slab_common.o \
+ compaction.o vmacache.o \
+ interval_tree.o list_lru.o workingset.o \
+- debug.o $(mmu-y)
++ prfile.o debug.o $(mmu-y)
+
+ obj-y += init-mm.o
+
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 287f3fa02e5e..f96b6dd07b0b 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -2722,7 +2722,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
+ vm_fault_t ret = VM_FAULT_LOCKED;
+
+ sb_start_pagefault(inode->i_sb);
+- file_update_time(vmf->vma->vm_file);
++ vma_file_update_time(vmf->vma);
+ lock_page(page);
+ if (page->mapping != inode->i_mapping) {
+ unlock_page(page);
+diff --git a/mm/mmap.c b/mm/mmap.c
+index 1480880ff814..03ae15dfe614 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -181,7 +181,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
+ if (vma->vm_ops && vma->vm_ops->close)
+ vma->vm_ops->close(vma);
+ if (vma->vm_file)
+- fput(vma->vm_file);
++ vma_fput(vma);
+ mpol_put(vma_policy(vma));
+ vm_area_free(vma);
+ return next;
+@@ -906,7 +906,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start,
+ if (remove_next) {
+ if (file) {
+ uprobe_munmap(next, next->vm_start, next->vm_end);
+- fput(file);
++ vma_fput(vma);
+ }
+ if (next->anon_vma)
+ anon_vma_merge(vma, next);
+@@ -1822,8 +1822,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr,
+ return addr;
+
+ unmap_and_free_vma:
++ vma_fput(vma);
+ vma->vm_file = NULL;
+- fput(file);
+
+ /* Undo any partial mapping done by a device driver. */
+ unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
+@@ -2645,7 +2645,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+ goto out_free_mpol;
+
+ if (new->vm_file)
+- get_file(new->vm_file);
++ vma_get_file(new);
+
+ if (new->vm_ops && new->vm_ops->open)
+ new->vm_ops->open(new);
+@@ -2664,7 +2664,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma,
+ if (new->vm_ops && new->vm_ops->close)
+ new->vm_ops->close(new);
+ if (new->vm_file)
+- fput(new->vm_file);
++ vma_fput(new);
+ unlink_anon_vmas(new);
+ out_free_mpol:
+ mpol_put(vma_policy(new));
+@@ -2826,7 +2826,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+ struct vm_area_struct *vma;
+ unsigned long populate = 0;
+ unsigned long ret = -EINVAL;
+- struct file *file;
++ struct file *file, *prfile;
+
+ pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n",
+ current->comm, current->pid);
+@@ -2901,10 +2901,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+ }
+ }
+
+- file = get_file(vma->vm_file);
++ vma_get_file(vma);
++ file = vma->vm_file;
++ prfile = vma->vm_prfile;
+ ret = do_mmap_pgoff(vma->vm_file, start, size,
+ prot, flags, pgoff, &populate, NULL);
++ if (!IS_ERR_VALUE(ret) && file && prfile) {
++ struct vm_area_struct *new_vma;
++
++ new_vma = find_vma(mm, ret);
++ if (!new_vma->vm_prfile)
++ new_vma->vm_prfile = prfile;
++ if (new_vma != vma)
++ get_file(prfile);
++ }
++ /*
++ * two fput()s instead of vma_fput(vma),
++ * coz vma may not be available anymore.
++ */
+ fput(file);
++ if (prfile)
++ fput(prfile);
+ out:
+ up_write(&mm->mmap_sem);
+ if (populate)
+@@ -3210,7 +3227,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
+ if (anon_vma_clone(new_vma, vma))
+ goto out_free_mempol;
+ if (new_vma->vm_file)
+- get_file(new_vma->vm_file);
++ vma_get_file(new_vma);
+ if (new_vma->vm_ops && new_vma->vm_ops->open)
+ new_vma->vm_ops->open(new_vma);
+ vma_link(mm, new_vma, prev, rb_link, rb_parent);
+diff --git a/mm/nommu.c b/mm/nommu.c
+index 1d63ecfc98c5..15eafddeb944 100644
+--- a/mm/nommu.c
++++ b/mm/nommu.c
+@@ -625,7 +625,7 @@ static void __put_nommu_region(struct vm_region *region)
+ up_write(&nommu_region_sem);
+
+ if (region->vm_file)
+- fput(region->vm_file);
++ vmr_fput(region);
+
+ /* IO memory and memory shared directly out of the pagecache
+ * from ramfs/tmpfs mustn't be released here */
+@@ -763,7 +763,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma)
+ if (vma->vm_ops && vma->vm_ops->close)
+ vma->vm_ops->close(vma);
+ if (vma->vm_file)
+- fput(vma->vm_file);
++ vma_fput(vma);
+ put_nommu_region(vma->vm_region);
+ vm_area_free(vma);
+ }
+@@ -1286,7 +1286,7 @@ unsigned long do_mmap(struct file *file,
+ goto error_just_free;
+ }
+ }
+- fput(region->vm_file);
++ vmr_fput(region);
+ kmem_cache_free(vm_region_jar, region);
+ region = pregion;
+ result = start;
+@@ -1361,10 +1361,10 @@ unsigned long do_mmap(struct file *file,
+ up_write(&nommu_region_sem);
+ error:
+ if (region->vm_file)
+- fput(region->vm_file);
++ vmr_fput(region);
+ kmem_cache_free(vm_region_jar, region);
+ if (vma->vm_file)
+- fput(vma->vm_file);
++ vma_fput(vma);
+ vm_area_free(vma);
+ return ret;
+
+diff --git a/mm/prfile.c b/mm/prfile.c
+new file mode 100644
+index 000000000000..024cdcfae1b1
+--- /dev/null
++++ b/mm/prfile.c
+@@ -0,0 +1,86 @@
++// SPDX-License-Identifier: GPL-2.0
++/*
++ * Mainly for aufs which mmap(2) different file and wants to print different
++ * path in /proc/PID/maps.
++ * Call these functions via macros defined in linux/mm.h.
++ *
++ * See Documentation/filesystems/aufs/design/06mmap.txt
++ *
++ * Copyright (c) 2014-2019 Junjro R. Okajima
++ * Copyright (c) 2014 Ian Campbell
++ */
++
++#include <linux/mm.h>
++#include <linux/file.h>
++#include <linux/fs.h>
++
++/* #define PRFILE_TRACE */
++static inline void prfile_trace(struct file *f, struct file *pr,
++ const char func[], int line, const char func2[])
++{
++#ifdef PRFILE_TRACE
++ if (pr)
++ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f);
++#endif
++}
++
++void vma_do_file_update_time(struct vm_area_struct *vma, const char func[],
++ int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++
++ prfile_trace(f, pr, func, line, __func__);
++ file_update_time(f);
++ if (f && pr)
++ file_update_time(pr);
++}
++
++struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[],
++ int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++
++ prfile_trace(f, pr, func, line, __func__);
++ return (f && pr) ? pr : f;
++}
++
++void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++
++ prfile_trace(f, pr, func, line, __func__);
++ get_file(f);
++ if (f && pr)
++ get_file(pr);
++}
++
++void vma_do_fput(struct vm_area_struct *vma, const char func[], int line)
++{
++ struct file *f = vma->vm_file, *pr = vma->vm_prfile;
++
++ prfile_trace(f, pr, func, line, __func__);
++ fput(f);
++ if (f && pr)
++ fput(pr);
++}
++
++#ifndef CONFIG_MMU
++struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[],
++ int line)
++{
++ struct file *f = region->vm_file, *pr = region->vm_prfile;
++
++ prfile_trace(f, pr, func, line, __func__);
++ return (f && pr) ? pr : f;
++}
++
++void vmr_do_fput(struct vm_region *region, const char func[], int line)
++{
++ struct file *f = region->vm_file, *pr = region->vm_prfile;
++
++ prfile_trace(f, pr, func, line, __func__);
++ fput(f);
++ if (f && pr)
++ fput(pr);
++}
++#endif /* !CONFIG_MMU */
diff --git a/debian/patches/features/all/aufs4/aufs4-standalone.patch b/debian/patches/features/all/aufs4/aufs4-standalone.patch
new file mode 100644
index 000000000..0a682c2f5
--- /dev/null
+++ b/debian/patches/features/all/aufs4/aufs4-standalone.patch
@@ -0,0 +1,385 @@
+From: J. R. Okajima <hooanon05@yahoo.co.jp>
+Date: Tue Sep 3 14:14:09 2019 +0900
+Subject: aufs4.19.63+ standalone patch
+Origin: https://github.com/sfjro/aufs4-standalone/tree/6c582cc629cbfb4fac5bfc7d20db128c7d201da6
+Bug-Debian: https://bugs.debian.org/541828
+
+Patch headers added by debian/bin/genpatch-aufs
+
+SPDX-License-Identifier: GPL-2.0
+aufs4.19.63+ standalone patch
+
+diff --git a/fs/dcache.c b/fs/dcache.c
+index 3bd53094ac3d..d6b2f7a994f4 100644
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -1339,6 +1339,7 @@ void d_walk(struct dentry *parent, void *data,
+ seq = 1;
+ goto again;
+ }
++EXPORT_SYMBOL_GPL(d_walk);
+
+ struct check_mount {
+ struct vfsmount *mnt;
+@@ -2835,6 +2836,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2)
+
+ write_sequnlock(&rename_lock);
+ }
++EXPORT_SYMBOL_GPL(d_exchange);
+
+ /**
+ * d_ancestor - search for an ancestor
+diff --git a/fs/exec.c b/fs/exec.c
+index 433b1257694a..504c56308700 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path)
+ return (path->mnt->mnt_flags & MNT_NOEXEC) ||
+ (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC);
+ }
++EXPORT_SYMBOL_GPL(path_noexec);
+
+ #ifdef CONFIG_USELIB
+ /*
+diff --git a/fs/fcntl.c b/fs/fcntl.c
+index c91b3e3c4580..77513097f04c 100644
+--- a/fs/fcntl.c
++++ b/fs/fcntl.c
+@@ -85,6 +85,7 @@ int setfl(int fd, struct file * filp, unsigned long arg)
+ out:
+ return error;
+ }
++EXPORT_SYMBOL_GPL(setfl);
+
+ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
+ int force)
+diff --git a/fs/file_table.c b/fs/file_table.c
+index e49af4caf15d..569020fd1fb3 100644
+--- a/fs/file_table.c
++++ b/fs/file_table.c
+@@ -161,6 +161,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred)
+ }
+ return ERR_PTR(-ENFILE);
+ }
++EXPORT_SYMBOL_GPL(alloc_empty_file);
+
+ /*
+ * Variant of alloc_empty_file() that doesn't check and modify nr_files.
+@@ -323,6 +324,7 @@ void flush_delayed_fput(void)
+ {
+ delayed_fput(NULL);
+ }
++EXPORT_SYMBOL_GPL(flush_delayed_fput);
+
+ static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput);
+
+@@ -365,6 +367,7 @@ void __fput_sync(struct file *file)
+ }
+
+ EXPORT_SYMBOL(fput);
++EXPORT_SYMBOL_GPL(__fput_sync);
+
+ void __init files_init(void)
+ {
+diff --git a/fs/inode.c b/fs/inode.c
+index 43046d7223e4..36146c757aa2 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -1666,6 +1666,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags)
+
+ return update_time(inode, time, flags);
+ }
++EXPORT_SYMBOL_GPL(update_time);
+
+ /**
+ * touch_atime - update the access time
+diff --git a/fs/namespace.c b/fs/namespace.c
+index fbd7edd49a2f..d6eca814d9fc 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -437,6 +437,7 @@ void __mnt_drop_write(struct vfsmount *mnt)
+ mnt_dec_writers(real_mount(mnt));
+ preempt_enable();
+ }
++EXPORT_SYMBOL_GPL(__mnt_drop_write);
+
+ /**
+ * mnt_drop_write - give up write access to a mount
+@@ -775,6 +776,7 @@ int is_current_mnt_ns(struct vfsmount *mnt)
+ {
+ return check_mnt(real_mount(mnt));
+ }
++EXPORT_SYMBOL_GPL(is_current_mnt_ns);
+
+ /*
+ * vfsmount lock must be held for write
+@@ -1844,6 +1846,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
+ }
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(iterate_mounts);
+
+ static void cleanup_group_ids(struct mount *mnt, struct mount *end)
+ {
+diff --git a/fs/notify/group.c b/fs/notify/group.c
+index c03b83662876..94d210ca384a 100644
+--- a/fs/notify/group.c
++++ b/fs/notify/group.c
+@@ -112,6 +112,7 @@ void fsnotify_get_group(struct fsnotify_group *group)
+ {
+ refcount_inc(&group->refcnt);
+ }
++EXPORT_SYMBOL_GPL(fsnotify_get_group);
+
+ /*
+ * Drop a reference to a group. Free it if it's through.
+@@ -121,6 +122,7 @@ void fsnotify_put_group(struct fsnotify_group *group)
+ if (refcount_dec_and_test(&group->refcnt))
+ fsnotify_final_destroy_group(group);
+ }
++EXPORT_SYMBOL_GPL(fsnotify_put_group);
+
+ /*
+ * Create a new fsnotify_group and hold a reference for the group returned.
+@@ -150,6 +152,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops)
+
+ return group;
+ }
++EXPORT_SYMBOL_GPL(fsnotify_alloc_group);
+
+ int fsnotify_fasync(int fd, struct file *file, int on)
+ {
+diff --git a/fs/notify/mark.c b/fs/notify/mark.c
+index 09535f6423fc..e9401ec71fc7 100644
+--- a/fs/notify/mark.c
++++ b/fs/notify/mark.c
+@@ -285,6 +285,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark)
+ queue_delayed_work(system_unbound_wq, &reaper_work,
+ FSNOTIFY_REAPER_DELAY);
+ }
++EXPORT_SYMBOL_GPL(fsnotify_put_mark);
+
+ /*
+ * Get mark reference when we found the mark via lockless traversal of object
+@@ -439,6 +440,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark,
+ mutex_unlock(&group->mark_mutex);
+ fsnotify_free_mark(mark);
+ }
++EXPORT_SYMBOL_GPL(fsnotify_destroy_mark);
+
+ /*
+ * Sorting function for lists of fsnotify marks.
+@@ -654,6 +656,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp,
+ mutex_unlock(&group->mark_mutex);
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(fsnotify_add_mark);
+
+ /*
+ * Given a list of marks, find the mark associated with given group. If found
+@@ -777,6 +780,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark,
+ fsnotify_get_group(group);
+ mark->group = group;
+ }
++EXPORT_SYMBOL_GPL(fsnotify_init_mark);
+
+ /*
+ * Destroy all marks in destroy_list, waits for SRCU period to finish before
+diff --git a/fs/open.c b/fs/open.c
+index 878478745924..ab755f585f29 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
+ inode_unlock(dentry->d_inode);
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(do_truncate);
+
+ long vfs_truncate(const struct path *path, loff_t length)
+ {
+diff --git a/fs/read_write.c b/fs/read_write.c
+index c1335b4f19c0..6ed1f2ddcb03 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -459,6 +459,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
+
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(vfs_read);
+
+ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
+ {
+@@ -499,6 +500,7 @@ vfs_readf_t vfs_readf(struct file *file)
+ return new_sync_read;
+ return ERR_PTR(-ENOSYS);
+ }
++EXPORT_SYMBOL_GPL(vfs_readf);
+
+ vfs_writef_t vfs_writef(struct file *file)
+ {
+@@ -510,6 +512,7 @@ vfs_writef_t vfs_writef(struct file *file)
+ return new_sync_write;
+ return ERR_PTR(-ENOSYS);
+ }
++EXPORT_SYMBOL_GPL(vfs_writef);
+
+ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos)
+ {
+@@ -579,6 +582,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_
+
+ return ret;
+ }
++EXPORT_SYMBOL_GPL(vfs_write);
+
+ static inline loff_t file_pos_read(struct file *file)
+ {
+diff --git a/fs/splice.c b/fs/splice.c
+index b2c2d320565b..8250f2366329 100644
+--- a/fs/splice.c
++++ b/fs/splice.c
+@@ -851,6 +851,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+
+ return splice_write(pipe, out, ppos, len, flags);
+ }
++EXPORT_SYMBOL_GPL(do_splice_from);
+
+ /*
+ * Attempt to initiate a splice from a file to a pipe.
+@@ -880,6 +881,7 @@ long do_splice_to(struct file *in, loff_t *ppos,
+
+ return splice_read(in, ppos, pipe, len, flags);
+ }
++EXPORT_SYMBOL_GPL(do_splice_to);
+
+ /**
+ * splice_direct_to_actor - splices data directly between two non-pipes
+diff --git a/fs/sync.c b/fs/sync.c
+index 28607828e96f..ffd7ea43831e 100644
+--- a/fs/sync.c
++++ b/fs/sync.c
+@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block *sb, int wait)
+ sb->s_op->sync_fs(sb, wait);
+ return __sync_blockdev(sb->s_bdev, wait);
+ }
++EXPORT_SYMBOL_GPL(__sync_filesystem);
+
+ /*
+ * Write out and wait upon all dirty data associated with this
+diff --git a/fs/xattr.c b/fs/xattr.c
+index 0d6a6a4af861..7ce4701b7289 100644
+--- a/fs/xattr.c
++++ b/fs/xattr.c
+@@ -295,6 +295,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
+ *xattr_value = value;
+ return error;
+ }
++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc);
+
+ ssize_t
+ __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name,
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index d0c9931e6531..0e5d9706723c 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -151,6 +151,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock)
+ }
+ return lock_classes + hlock->class_idx - 1;
+ }
++EXPORT_SYMBOL_GPL(lockdep_hlock_class);
+ #define hlock_class(hlock) lockdep_hlock_class(hlock)
+
+ #ifdef CONFIG_LOCK_STAT
+diff --git a/kernel/task_work.c b/kernel/task_work.c
+index 0fef395662a6..83fb1ecfc33d 100644
+--- a/kernel/task_work.c
++++ b/kernel/task_work.c
+@@ -116,3 +116,4 @@ void task_work_run(void)
+ } while (work);
+ }
+ }
++EXPORT_SYMBOL_GPL(task_work_run);
+diff --git a/security/device_cgroup.c b/security/device_cgroup.c
+index dc28914fa72e..c2ddfea2b280 100644
+--- a/security/device_cgroup.c
++++ b/security/device_cgroup.c
+@@ -824,3 +824,4 @@ int __devcgroup_check_permission(short type, u32 major, u32 minor,
+
+ return 0;
+ }
++EXPORT_SYMBOL_GPL(__devcgroup_check_permission);
+diff --git a/security/security.c b/security/security.c
+index 5ce2448f3a45..3997af3462bc 100644
+--- a/security/security.c
++++ b/security/security.c
+@@ -542,6 +542,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry)
+ return 0;
+ return call_int_hook(path_rmdir, 0, dir, dentry);
+ }
++EXPORT_SYMBOL_GPL(security_path_rmdir);
+
+ int security_path_unlink(const struct path *dir, struct dentry *dentry)
+ {
+@@ -558,6 +559,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry,
+ return 0;
+ return call_int_hook(path_symlink, 0, dir, dentry, old_name);
+ }
++EXPORT_SYMBOL_GPL(security_path_symlink);
+
+ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
+ struct dentry *new_dentry)
+@@ -566,6 +568,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir,
+ return 0;
+ return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry);
+ }
++EXPORT_SYMBOL_GPL(security_path_link);
+
+ int security_path_rename(const struct path *old_dir, struct dentry *old_dentry,
+ const struct path *new_dir, struct dentry *new_dentry,
+@@ -593,6 +596,7 @@ int security_path_truncate(const struct path *path)
+ return 0;
+ return call_int_hook(path_truncate, 0, path);
+ }
++EXPORT_SYMBOL_GPL(security_path_truncate);
+
+ int security_path_chmod(const struct path *path, umode_t mode)
+ {
+@@ -600,6 +604,7 @@ int security_path_chmod(const struct path *path, umode_t mode)
+ return 0;
+ return call_int_hook(path_chmod, 0, path, mode);
+ }
++EXPORT_SYMBOL_GPL(security_path_chmod);
+
+ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
+ {
+@@ -607,6 +612,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid)
+ return 0;
+ return call_int_hook(path_chown, 0, path, uid, gid);
+ }
++EXPORT_SYMBOL_GPL(security_path_chown);
+
+ int security_path_chroot(const struct path *path)
+ {
+@@ -707,6 +713,7 @@ int security_inode_permission(struct inode *inode, int mask)
+ return 0;
+ return call_int_hook(inode_permission, 0, inode, mask);
+ }
++EXPORT_SYMBOL_GPL(security_inode_permission);
+
+ int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
+ {
+@@ -878,6 +885,7 @@ int security_file_permission(struct file *file, int mask)
+
+ return fsnotify_perm(file, mask);
+ }
++EXPORT_SYMBOL_GPL(security_file_permission);
+
+ int security_file_alloc(struct file *file)
+ {
+@@ -937,6 +945,7 @@ int security_mmap_file(struct file *file, unsigned long prot,
+ return ret;
+ return ima_file_mmap(file, prot);
+ }
++EXPORT_SYMBOL_GPL(security_mmap_file);
+
+ int security_mmap_addr(unsigned long addr)
+ {
diff --git a/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch
new file mode 100644
index 000000000..a67217c02
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch
@@ -0,0 +1,91 @@
+From: David Howells <dhowells@redhat.com>
+Date: Fri, 5 May 2017 08:21:56 +0100
+Subject: [PATCH 1/7] KEYS: Allow unrestricted boot-time addition of keys to
+ secondary keyring
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=40db8fc497d010ae6cee6297c3882d3dc3d76d48
+
+Allow keys to be added to the system secondary certificates keyring during
+kernel initialisation in an unrestricted fashion. Such keys are implicitly
+trusted and don't have their trust chains checked on link.
+
+This allows keys in the UEFI database to be added in secure boot mode for
+the purposes of module signing.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/internal.h | 18 ++++++++++++++++++
+ certs/system_keyring.c | 33 +++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+)
+ create mode 100644 certs/internal.h
+
+Index: linux/certs/internal.h
+===================================================================
+--- /dev/null
++++ linux/certs/internal.h
+@@ -0,0 +1,18 @@
++/* Internal definitions
++ *
++ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++/*
++ * system_keyring.c
++ */
++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
++extern void __init add_trusted_secondary_key(const char *source,
++ const void *data, size_t len);
++#endif
+Index: linux/certs/system_keyring.c
+===================================================================
+--- linux.orig/certs/system_keyring.c
++++ linux/certs/system_keyring.c
+@@ -19,6 +19,7 @@
+ #include <keys/asymmetric-type.h>
+ #include <keys/system_keyring.h>
+ #include <crypto/pkcs7.h>
++#include "internal.h"
+
+ static struct key *builtin_trusted_keys;
+ #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
+@@ -266,3 +267,35 @@ error:
+ EXPORT_SYMBOL_GPL(verify_pkcs7_signature);
+
+ #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */
++
++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING
++/**
++ * add_trusted_secondary_key - Add to secondary keyring with no validation
++ * @source: Source of key
++ * @data: The blob holding the key
++ * @len: The length of the data blob
++ *
++ * Add a key to the secondary keyring without checking its trust chain. This
++ * is available only during kernel initialisation.
++ */
++void __init add_trusted_secondary_key(const char *source,
++ const void *data, size_t len)
++{
++ key_ref_t key;
++
++ key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1),
++ "asymmetric",
++ NULL, data, len,
++ (KEY_POS_ALL & ~KEY_POS_SETATTR) |
++ KEY_USR_VIEW,
++ KEY_ALLOC_NOT_IN_QUOTA |
++ KEY_ALLOC_BYPASS_RESTRICTION);
++
++ if (IS_ERR(key))
++ pr_err("Problem loading %s X.509 certificate (%ld)\n",
++ source, PTR_ERR(key));
++ else
++ pr_notice("Loaded %s cert '%s' linked to secondary sys keyring\n",
++ source, key_ref_to_ptr(key)->description);
++}
++#endif /* CONFIG_SECONDARY_TRUSTED_KEYRING */
diff --git a/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch
new file mode 100644
index 000000000..d36028413
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch
@@ -0,0 +1,64 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:37:59 +0800
+Subject: [PATCH 1/5] MODSIGN: do not load mok when secure boot disabled
+Origin: https://lore.kernel.org/patchwork/patch/933173/
+
+The mok can not be trusted when the secure boot is disabled. Which
+means that the kernel embedded certificate is the only trusted key.
+
+Due to db/dbx are authenticated variables, they needs manufacturer's
+KEK for update. So db/dbx are secure when secureboot disabled.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ certs/load_uefi.c | 26 +++++++++++++++-----------
+ 1 file changed, 15 insertions(+), 11 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -171,17 +171,6 @@ static int __init load_uefi_certs(void)
+ }
+ }
+
+- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
+- if (rc < 0) {
+- pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
+- } else if (moksize != 0) {
+- rc = parse_efi_signature_list("UEFI:MokListRT",
+- mok, moksize, get_handler_for_db);
+- if (rc)
+- pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
+- kfree(mok);
+- }
+-
+ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
+@@ -194,6 +183,21 @@ static int __init load_uefi_certs(void)
+ kfree(dbx);
+ }
+
++ /* the MOK can not be trusted when secure boot is disabled */
++ if (!efi_enabled(EFI_SECURE_BOOT))
++ return 0;
++
++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
++ if (rc < 0) {
++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
++ } else if (moksize != 0) {
++ rc = parse_efi_signature_list("UEFI:MokListRT",
++ mok, moksize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
++ kfree(mok);
++ }
++
+ return rc;
+ }
+ late_initcall(load_uefi_certs);
diff --git a/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch
new file mode 100644
index 000000000..d23b7ac98
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch
@@ -0,0 +1,60 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:38:01 +0800
+Subject: [PATCH 2/4] MODSIGN: load blacklist from MOKx
+Origin: https://lore.kernel.org/patchwork/patch/933177/
+
+This patch adds the logic to load the blacklisted hash and
+certificates from MOKx which is maintained by shim bootloader.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ certs/load_uefi.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -148,8 +148,8 @@ static int __init load_uefi_certs(void)
+ {
+ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
+ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
+- void *db = NULL, *dbx = NULL, *mok = NULL;
+- unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
++ void *db = NULL, *dbx = NULL, *mok = NULL, *mokx = NULL;
++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0, mokxsize = 0;
+ int rc = 0;
+
+ if (!efi.get_variable)
+@@ -183,7 +183,7 @@ static int __init load_uefi_certs(void)
+ kfree(dbx);
+ }
+
+- /* the MOK can not be trusted when secure boot is disabled */
++ /* the MOK and MOKx can not be trusted when secure boot is disabled */
+ if (!efi_enabled(EFI_SECURE_BOOT))
+ return 0;
+
+@@ -198,6 +198,18 @@ static int __init load_uefi_certs(void)
+ kfree(mok);
+ }
+
++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx);
++ if (rc < 0) {
++ pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n");
++ } else if (mokxsize != 0) {
++ rc = parse_efi_signature_list("UEFI:mokx",
++ mokx, mokxsize,
++ get_handler_for_dbx);
++ if (rc)
++ pr_err("Couldn't parse MokListXRT signatures: %d\n", rc);
++ kfree(mokx);
++ }
++
+ return rc;
+ }
+ late_initcall(load_uefi_certs);
diff --git a/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch
new file mode 100644
index 000000000..bf8d40768
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch
@@ -0,0 +1,57 @@
+From: Dave Howells <dhowells@redhat.com>
+Date: Fri, 5 May 2017 08:21:58 +0100
+Subject: [PATCH 2/7] efi: Add EFI signature data types
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=446e0e29d7d53fe7786d33603df5a6682dd00c12
+
+Add the data types that are used for containing hashes, keys and
+certificates for cryptographic verification along with their corresponding
+type GUIDs.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ include/linux/efi.h | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+Index: linux/include/linux/efi.h
+===================================================================
+--- linux.orig/include/linux/efi.h
++++ linux/include/linux/efi.h
+@@ -663,6 +663,10 @@ void efi_native_runtime_setup(void);
+ #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
+ #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
+
++#define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28)
++#define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
++#define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed)
++
+ /*
+ * This GUID is used to pass to the kernel proper the struct screen_info
+ * structure that was populated by the stub based on the GOP protocol instance
+@@ -934,6 +938,27 @@ typedef struct {
+ efi_memory_desc_t entry[0];
+ } efi_memory_attributes_table_t;
+
++typedef struct {
++ efi_guid_t signature_owner;
++ u8 signature_data[];
++} efi_signature_data_t;
++
++typedef struct {
++ efi_guid_t signature_type;
++ u32 signature_list_size;
++ u32 signature_header_size;
++ u32 signature_size;
++ u8 signature_header[];
++ /* efi_signature_data_t signatures[][] */
++} efi_signature_list_t;
++
++typedef u8 efi_sha256_hash_t[32];
++
++typedef struct {
++ efi_sha256_hash_t to_be_signed_hash;
++ efi_time_t time_of_revocation;
++} efi_cert_x509_sha256_t;
++
+ /*
+ * All runtime access to EFI goes through this structure:
+ */
diff --git a/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch
new file mode 100644
index 000000000..1a43ca553
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch
@@ -0,0 +1,129 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:38:02 +0800
+Subject: [PATCH 3/4] MODSIGN: checking the blacklisted hash before loading a
+ kernel module
+Origin: https://lore.kernel.org/patchwork/patch/933175/
+
+This patch adds the logic for checking the kernel module's hash
+base on blacklist. The hash must be generated by sha256 and enrolled
+to dbx/mokx.
+
+For example:
+ sha256sum sample.ko
+ mokutil --mokx --import-hash $HASH_RESULT
+
+Whether the signature on ko file is stripped or not, the hash can be
+compared by kernel.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ kernel/module_signing.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 60 insertions(+), 2 deletions(-)
+
+Index: linux/kernel/module_signing.c
+===================================================================
+--- linux.orig/kernel/module_signing.c
++++ linux/kernel/module_signing.c
+@@ -11,9 +11,12 @@
+
+ #include <linux/kernel.h>
+ #include <linux/errno.h>
++#include <linux/module.h>
+ #include <linux/string.h>
+ #include <linux/verification.h>
+ #include <crypto/public_key.h>
++#include <crypto/hash.h>
++#include <keys/system_keyring.h>
+ #include "module-internal.h"
+
+ enum pkey_id_type {
+@@ -42,19 +45,67 @@ struct module_signature {
+ __be32 sig_len; /* Length of signature data */
+ };
+
++static int mod_is_hash_blacklisted(const void *mod, size_t verifylen)
++{
++ struct crypto_shash *tfm;
++ struct shash_desc *desc;
++ size_t digest_size, desc_size;
++ u8 *digest;
++ int ret = 0;
++
++ tfm = crypto_alloc_shash("sha256", 0, 0);
++ if (IS_ERR(tfm))
++ goto error_return;
++
++ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
++ digest_size = crypto_shash_digestsize(tfm);
++ digest = kzalloc(digest_size + desc_size, GFP_KERNEL);
++ if (!digest) {
++ pr_err("digest memory buffer allocate fail\n");
++ ret = -ENOMEM;
++ goto error_digest;
++ }
++ desc = (void *)digest + digest_size;
++ desc->tfm = tfm;
++ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
++ ret = crypto_shash_init(desc);
++ if (ret < 0)
++ goto error_shash;
++
++ ret = crypto_shash_finup(desc, mod, verifylen, digest);
++ if (ret < 0)
++ goto error_shash;
++
++ pr_debug("%ld digest: %*phN\n", verifylen, (int) digest_size, digest);
++
++ ret = is_hash_blacklisted(digest, digest_size, "bin");
++ if (ret == -EKEYREJECTED)
++ pr_err("Module hash %*phN is blacklisted\n",
++ (int) digest_size, digest);
++
++error_shash:
++ kfree(digest);
++error_digest:
++ crypto_free_shash(tfm);
++error_return:
++ return ret;
++}
++
+ /*
+ * Verify the signature on a module.
+ */
+ int mod_verify_sig(const void *mod, struct load_info *info)
+ {
+ struct module_signature ms;
+- size_t sig_len, modlen = info->len;
++ size_t sig_len, modlen = info->len, wholelen;
++ int ret;;
+
+ pr_devel("==>%s(,%zu)\n", __func__, modlen);
+
+ if (modlen <= sizeof(ms))
+ return -EBADMSG;
+
++ wholelen = modlen + sizeof(MODULE_SIG_STRING) - 1;
+ memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
+ modlen -= sizeof(ms);
+
+@@ -82,8 +133,15 @@ int mod_verify_sig(const void *mod, stru
+ return -EBADMSG;
+ }
+
+- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+ VERIFY_USE_SECONDARY_KEYRING,
+ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
++ pr_devel("verify_pkcs7_signature() = %d\n", ret);
++
++ /* checking hash of module is in blacklist */
++ if (!ret)
++ ret = mod_is_hash_blacklisted(mod, wholelen);
++
++ return ret;
+ }
diff --git a/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch
new file mode 100644
index 000000000..e82287cff
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch
@@ -0,0 +1,193 @@
+From: Dave Howells <dhowells@redhat.com>
+Date: Fri, 5 May 2017 08:21:58 +0100
+Subject: [PATCH 3/7] efi: Add an EFI signature blob parser
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=41a595bb0dc097c19ad377a0c32c993234aa2525
+
+Add a function to parse an EFI signature blob looking for elements of
+interest. A list is made up of a series of sublists, where all the
+elements in a sublist are of the same type, but sublists can be of
+different types.
+
+For each sublist encountered, the function pointed to by the
+get_handler_for_guid argument is called with the type specifier GUID and
+returns either a pointer to a function to handle elements of that type or
+NULL if the type is not of interest.
+
+If the sublist is of interest, each element is passed to the handler
+function in turn.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/Kconfig | 8 ++++
+ certs/Makefile | 1 +
+ certs/efi_parser.c | 112 ++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/efi.h | 9 ++++
+ 4 files changed, 130 insertions(+)
+ create mode 100644 certs/efi_parser.c
+
+Index: linux/certs/Kconfig
+===================================================================
+--- linux.orig/certs/Kconfig
++++ linux/certs/Kconfig
+@@ -83,4 +83,12 @@ config SYSTEM_BLACKLIST_HASH_LIST
+ wrapper to incorporate the list into the kernel. Each <hash> should
+ be a string of hex digits.
+
++config EFI_SIGNATURE_LIST_PARSER
++ bool "EFI signature list parser"
++ depends on EFI
++ select X509_CERTIFICATE_PARSER
++ help
++ This option provides support for parsing EFI signature lists for
++ X.509 certificates and turning them into keys.
++
+ endmenu
+Index: linux/certs/Makefile
+===================================================================
+--- linux.orig/certs/Makefile
++++ linux/certs/Makefile
+@@ -10,6 +10,7 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) +
+ else
+ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o
+ endif
++obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
+
+ ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
+
+Index: linux/certs/efi_parser.c
+===================================================================
+--- /dev/null
++++ linux/certs/efi_parser.c
+@@ -0,0 +1,112 @@
++/* EFI signature/key/certificate list parser
++ *
++ * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++#define pr_fmt(fmt) "EFI: "fmt
++#include <linux/module.h>
++#include <linux/printk.h>
++#include <linux/err.h>
++#include <linux/efi.h>
++
++/**
++ * parse_efi_signature_list - Parse an EFI signature list for certificates
++ * @source: The source of the key
++ * @data: The data blob to parse
++ * @size: The size of the data blob
++ * @get_handler_for_guid: Get the handler func for the sig type (or NULL)
++ *
++ * Parse an EFI signature list looking for elements of interest. A list is
++ * made up of a series of sublists, where all the elements in a sublist are of
++ * the same type, but sublists can be of different types.
++ *
++ * For each sublist encountered, the @get_handler_for_guid function is called
++ * with the type specifier GUID and returns either a pointer to a function to
++ * handle elements of that type or NULL if the type is not of interest.
++ *
++ * If the sublist is of interest, each element is passed to the handler
++ * function in turn.
++ *
++ * Error EBADMSG is returned if the list doesn't parse correctly and 0 is
++ * returned if the list was parsed correctly. No error can be returned from
++ * the @get_handler_for_guid function or the element handler function it
++ * returns.
++ */
++int __init parse_efi_signature_list(
++ const char *source,
++ const void *data, size_t size,
++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *))
++{
++ efi_element_handler_t handler;
++ unsigned offs = 0;
++
++ pr_devel("-->%s(,%zu)\n", __func__, size);
++
++ while (size > 0) {
++ const efi_signature_data_t *elem;
++ efi_signature_list_t list;
++ size_t lsize, esize, hsize, elsize;
++
++ if (size < sizeof(list))
++ return -EBADMSG;
++
++ memcpy(&list, data, sizeof(list));
++ pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n",
++ offs,
++ list.signature_type.b, list.signature_list_size,
++ list.signature_header_size, list.signature_size);
++
++ lsize = list.signature_list_size;
++ hsize = list.signature_header_size;
++ esize = list.signature_size;
++ elsize = lsize - sizeof(list) - hsize;
++
++ if (lsize > size) {
++ pr_devel("<--%s() = -EBADMSG [overrun @%x]\n",
++ __func__, offs);
++ return -EBADMSG;
++ }
++
++ if (lsize < sizeof(list) ||
++ lsize - sizeof(list) < hsize ||
++ esize < sizeof(*elem) ||
++ elsize < esize ||
++ elsize % esize != 0) {
++ pr_devel("- bad size combo @%x\n", offs);
++ return -EBADMSG;
++ }
++
++ handler = get_handler_for_guid(&list.signature_type);
++ if (!handler) {
++ data += lsize;
++ size -= lsize;
++ offs += lsize;
++ continue;
++ }
++
++ data += sizeof(list) + hsize;
++ size -= sizeof(list) + hsize;
++ offs += sizeof(list) + hsize;
++
++ for (; elsize > 0; elsize -= esize) {
++ elem = data;
++
++ pr_devel("ELEM[%04x]\n", offs);
++ handler(source,
++ &elem->signature_data,
++ esize - sizeof(*elem));
++
++ data += esize;
++ size -= esize;
++ offs += esize;
++ }
++ }
++
++ return 0;
++}
+Index: linux/include/linux/efi.h
+===================================================================
+--- linux.orig/include/linux/efi.h
++++ linux/include/linux/efi.h
+@@ -1139,6 +1139,15 @@ extern int efi_memattr_apply_permissions
+ char * __init efi_md_typeattr_format(char *buf, size_t size,
+ const efi_memory_desc_t *md);
+
++
++typedef void (*efi_element_handler_t)(const char *source,
++ const void *element_data,
++ size_t element_size);
++extern int __init parse_efi_signature_list(
++ const char *source,
++ const void *data, size_t size,
++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *));
++
+ /**
+ * efi_range_is_wc - check the WC bit on an address range
+ * @start: starting kvirt address
diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch
new file mode 100644
index 000000000..cdb3b7a22
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch
@@ -0,0 +1,242 @@
+From: Josh Boyer <jwboyer@fedoraproject.org>
+Date: Fri, 5 May 2017 08:21:59 +0100
+Subject: [PATCH 4/7] MODSIGN: Import certificates from UEFI Secure Boot
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=7b7aae2efea13b5a7b80305856c28f235ea8b2fa
+
+Secure Boot stores a list of allowed certificates in the 'db' variable.
+This imports those certificates into the system trusted keyring. This
+allows for a third party signing certificate to be used in conjunction
+with signed modules. By importing the public certificate into the 'db'
+variable, a user can allow a module signed with that certificate to
+load. The shim UEFI bootloader has a similar certificate list stored
+in the 'MokListRT' variable. We import those as well.
+
+Secure Boot also maintains a list of disallowed certificates in the 'dbx'
+variable. We load those certificates into the newly introduced system
+blacklist keyring and forbid any module signed with those from loading and
+forbid the use within the kernel of any key with a matching hash.
+
+This facility is enabled by setting CONFIG_LOAD_UEFI_KEYS.
+
+Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/Kconfig | 16 +++++
+ certs/Makefile | 4 ++
+ certs/load_uefi.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 188 insertions(+)
+ create mode 100644 certs/load_uefi.c
+
+Index: linux/certs/Kconfig
+===================================================================
+--- linux.orig/certs/Kconfig
++++ linux/certs/Kconfig
+@@ -91,4 +91,20 @@ config EFI_SIGNATURE_LIST_PARSER
+ This option provides support for parsing EFI signature lists for
+ X.509 certificates and turning them into keys.
+
++config LOAD_UEFI_KEYS
++ bool "Load certs and blacklist from UEFI db for module checking"
++ depends on SYSTEM_BLACKLIST_KEYRING
++ depends on SECONDARY_TRUSTED_KEYRING
++ depends on EFI
++ depends on EFI_SIGNATURE_LIST_PARSER
++ help
++ If the kernel is booted in secure boot mode, this option will cause
++ the kernel to load the certificates from the UEFI db and MokListRT
++ into the secondary trusted keyring. It will also load any X.509
++ SHA256 hashes in the dbx list into the blacklist.
++
++ The effect of this is that, if the kernel is booted in secure boot
++ mode, modules signed with UEFI-stored keys will be permitted to be
++ loaded and keys that match the blacklist will be rejected.
++
+ endmenu
+Index: linux/certs/Makefile
+===================================================================
+--- linux.orig/certs/Makefile
++++ linux/certs/Makefile
+@@ -12,6 +12,10 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) +
+ endif
+ obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o
+
++obj-$(CONFIG_LOAD_UEFI_KEYS) += load_uefi.o
++$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar
++
++
+ ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y)
+
+ $(eval $(call config_filename,SYSTEM_TRUSTED_KEYS))
+Index: linux/certs/load_uefi.c
+===================================================================
+--- /dev/null
++++ linux/certs/load_uefi.c
+@@ -0,0 +1,168 @@
++#include <linux/kernel.h>
++#include <linux/sched.h>
++#include <linux/cred.h>
++#include <linux/err.h>
++#include <linux/efi.h>
++#include <linux/slab.h>
++#include <keys/asymmetric-type.h>
++#include <keys/system_keyring.h>
++#include "internal.h"
++
++static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID;
++static __initdata efi_guid_t efi_cert_x509_sha256_guid = EFI_CERT_X509_SHA256_GUID;
++static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID;
++
++/*
++ * Get a certificate list blob from the named EFI variable.
++ */
++static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
++ unsigned long *size)
++{
++ efi_status_t status;
++ unsigned long lsize = 4;
++ unsigned long tmpdb[4];
++ void *db;
++
++ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
++ if (status != EFI_BUFFER_TOO_SMALL) {
++ pr_err("Couldn't get size: 0x%lx\n", status);
++ return NULL;
++ }
++
++ db = kmalloc(lsize, GFP_KERNEL);
++ if (!db) {
++ pr_err("Couldn't allocate memory for uefi cert list\n");
++ return NULL;
++ }
++
++ status = efi.get_variable(name, guid, NULL, &lsize, db);
++ if (status != EFI_SUCCESS) {
++ kfree(db);
++ pr_err("Error reading db var: 0x%lx\n", status);
++ return NULL;
++ }
++
++ *size = lsize;
++ return db;
++}
++
++/*
++ * Blacklist an X509 TBS hash.
++ */
++static __init void uefi_blacklist_x509_tbs(const char *source,
++ const void *data, size_t len)
++{
++ char *hash, *p;
++
++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL);
++ if (!hash)
++ return;
++ p = memcpy(hash, "tbs:", 4);
++ p += 4;
++ bin2hex(p, data, len);
++ p += len * 2;
++ *p = 0;
++
++ mark_hash_blacklisted(hash);
++ kfree(hash);
++}
++
++/*
++ * Blacklist the hash of an executable.
++ */
++static __init void uefi_blacklist_binary(const char *source,
++ const void *data, size_t len)
++{
++ char *hash, *p;
++
++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL);
++ if (!hash)
++ return;
++ p = memcpy(hash, "bin:", 4);
++ p += 4;
++ bin2hex(p, data, len);
++ p += len * 2;
++ *p = 0;
++
++ mark_hash_blacklisted(hash);
++ kfree(hash);
++}
++
++/*
++ * Return the appropriate handler for particular signature list types found in
++ * the UEFI db and MokListRT tables.
++ */
++static __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type)
++{
++ if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0)
++ return add_trusted_secondary_key;
++ return 0;
++}
++
++/*
++ * Return the appropriate handler for particular signature list types found in
++ * the UEFI dbx and MokListXRT tables.
++ */
++static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type)
++{
++ if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0)
++ return uefi_blacklist_x509_tbs;
++ if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0)
++ return uefi_blacklist_binary;
++ return 0;
++}
++
++/*
++ * Load the certs contained in the UEFI databases
++ */
++static int __init load_uefi_certs(void)
++{
++ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID;
++ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID;
++ void *db = NULL, *dbx = NULL, *mok = NULL;
++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0;
++ int rc = 0;
++
++ if (!efi.get_variable)
++ return false;
++
++ /* Get db, MokListRT, and dbx. They might not exist, so it isn't
++ * an error if we can't get them.
++ */
++ db = get_cert_list(L"db", &secure_var, &dbsize);
++ if (!db) {
++ pr_err("MODSIGN: Couldn't get UEFI db list\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:db",
++ db, dbsize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse db signatures: %d\n", rc);
++ kfree(db);
++ }
++
++ mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
++ if (!mok) {
++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:MokListRT",
++ mok, moksize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc);
++ kfree(mok);
++ }
++
++ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
++ if (!dbx) {
++ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:dbx",
++ dbx, dbxsize,
++ get_handler_for_dbx);
++ if (rc)
++ pr_err("Couldn't parse dbx signatures: %d\n", rc);
++ kfree(dbx);
++ }
++
++ return rc;
++}
++late_initcall(load_uefi_certs);
diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch
new file mode 100644
index 000000000..57b6e61ff
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch
@@ -0,0 +1,108 @@
+From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
+Date: Tue, 13 Mar 2018 18:38:03 +0800
+Subject: [PATCH 4/4] MODSIGN: check the attributes of db and mok
+Origin: https://lore.kernel.org/patchwork/patch/933176/
+
+That's better for checking the attributes of db and mok variables
+before loading certificates to kernel keyring.
+
+For db and dbx, both of them are authenticated variables. Which
+means that they can only be modified by manufacturer's key. So
+the kernel should checks EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
+attribute before we trust it.
+
+For mok-rt and mokx-rt, both of them are created by shim boot loader
+to forward the mok/mokx content to runtime. They must be runtime-volatile
+variables. So kernel should checks that the attributes map did not set
+EFI_VARIABLE_NON_VOLATILE bit before we trust it.
+
+Cc: David Howells <dhowells@redhat.com>
+Cc: Josh Boyer <jwboyer@fedoraproject.org>
+Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
+[Rebased by Luca Boccassi]
+---
+ certs/load_uefi.c | 35 +++++++++++++++++++++++------------
+ 1 file changed, 23 insertions(+), 12 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -36,12 +36,14 @@ static __init bool uefi_check_ignore_db(
+ * Get a certificate list blob from the named EFI variable.
+ */
+ static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid,
+- unsigned long *size, void **cert_list)
++ unsigned long *size, void **cert_list,
++ u32 pos_attr, u32 neg_attr)
+ {
+ efi_status_t status;
+ unsigned long lsize = 4;
+ unsigned long tmpdb[4];
+ void *db;
++ u32 attr = 0;
+
+ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
+ if (status == EFI_NOT_FOUND) {
+@@ -61,12 +63,19 @@ static __init int get_cert_list(efi_char
+ return -ENOMEM;
+ }
+
+- status = efi.get_variable(name, guid, NULL, &lsize, db);
++ status = efi.get_variable(name, guid, &attr, &lsize, db);
+ if (status != EFI_SUCCESS) {
+ kfree(db);
+ pr_err("Error reading db var: 0x%lx\n", status);
+ return efi_status_to_err(status);
+ }
++ /* must have positive attributes and no negative attributes */
++ if ((pos_attr && !(attr & pos_attr)) ||
++ (neg_attr && (attr & neg_attr))) {
++ kfree(db);
++ pr_err("Error reading db var attributes: 0x%016x\n", attr);
++ return -1;
++ }
+
+ *size = lsize;
+ *cert_list = db;
+@@ -159,7 +168,8 @@ static int __init load_uefi_certs(void)
+ * an error if we can't get them.
+ */
+ if (!uefi_check_ignore_db()) {
+- rc = get_cert_list(L"db", &secure_var, &dbsize, &db);
++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db,
++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0);
+ if (rc < 0) {
+ pr_err("MODSIGN: Couldn't get UEFI db list\n");
+ } else if (dbsize != 0) {
+@@ -171,7 +181,8 @@ static int __init load_uefi_certs(void)
+ }
+ }
+
+- rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx);
++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx,
++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
+ } else if (dbxsize != 0) {
+@@ -187,7 +198,8 @@ static int __init load_uefi_certs(void)
+ if (!efi_enabled(EFI_SECURE_BOOT))
+ return 0;
+
+- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok,
++ 0, EFI_VARIABLE_NON_VOLATILE);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
+ } else if (moksize != 0) {
+@@ -198,7 +210,8 @@ static int __init load_uefi_certs(void)
+ kfree(mok);
+ }
+
+- rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx);
++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx,
++ 0, EFI_VARIABLE_NON_VOLATILE);
+ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n");
+ } else if (mokxsize != 0) {
diff --git a/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch
new file mode 100644
index 000000000..b5e2e843c
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch
@@ -0,0 +1,85 @@
+From: Josh Boyer <jwboyer@fedoraproject.org>
+Date: Fri, 5 May 2017 08:21:59 +0100
+Subject: [PATCH 5/7] MODSIGN: Allow the "db" UEFI variable to be suppressed
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=b51ca4e4d6c0c8000789de31a1184a41ac611d33
+
+If a user tells shim to not use the certs/hashes in the UEFI db variable
+for verification purposes, shim will set a UEFI variable called
+MokIgnoreDB. Have the uefi import code look for this and ignore the db
+variable if it is found.
+
+Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ certs/load_uefi.c | 44 ++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 34 insertions(+), 10 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -13,6 +13,26 @@ static __initdata efi_guid_t efi_cert_x5
+ static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID;
+
+ /*
++ * Look to see if a UEFI variable called MokIgnoreDB exists and return true if
++ * it does.
++ *
++ * This UEFI variable is set by the shim if a user tells the shim to not use
++ * the certs/hashes in the UEFI db variable for verification purposes. If it
++ * is set, we should ignore the db variable also and the true return indicates
++ * this.
++ */
++static __init bool uefi_check_ignore_db(void)
++{
++ efi_status_t status;
++ unsigned int db = 0;
++ unsigned long size = sizeof(db);
++ efi_guid_t guid = EFI_SHIM_LOCK_GUID;
++
++ status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db);
++ return status == EFI_SUCCESS;
++}
++
++/*
+ * Get a certificate list blob from the named EFI variable.
+ */
+ static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
+@@ -113,7 +133,9 @@ static __init efi_element_handler_t get_
+ }
+
+ /*
+- * Load the certs contained in the UEFI databases
++ * Load the certs contained in the UEFI databases into the secondary trusted
++ * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist
++ * keyring.
+ */
+ static int __init load_uefi_certs(void)
+ {
+@@ -129,15 +151,17 @@ static int __init load_uefi_certs(void)
+ /* Get db, MokListRT, and dbx. They might not exist, so it isn't
+ * an error if we can't get them.
+ */
+- db = get_cert_list(L"db", &secure_var, &dbsize);
+- if (!db) {
+- pr_err("MODSIGN: Couldn't get UEFI db list\n");
+- } else {
+- rc = parse_efi_signature_list("UEFI:db",
+- db, dbsize, get_handler_for_db);
+- if (rc)
+- pr_err("Couldn't parse db signatures: %d\n", rc);
+- kfree(db);
++ if (!uefi_check_ignore_db()) {
++ db = get_cert_list(L"db", &secure_var, &dbsize);
++ if (!db) {
++ pr_err("MODSIGN: Couldn't get UEFI db list\n");
++ } else {
++ rc = parse_efi_signature_list("UEFI:db",
++ db, dbsize, get_handler_for_db);
++ if (rc)
++ pr_err("Couldn't parse db signatures: %d\n", rc);
++ kfree(db);
++ }
+ }
+
+ mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
diff --git a/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch
new file mode 100644
index 000000000..c348e2f04
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch
@@ -0,0 +1,106 @@
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 2 Oct 2017 18:25:29 -0400
+Subject: [PATCH 6/7] Make get_cert_list() not complain about cert lists that
+ aren't present.
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=0f4d5c7b49b45e7cf038bb769e33451b78a6445d
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+---
+ certs/load_uefi.c | 37 ++++++++++++++++++++++---------------
+ 1 file changed, 22 insertions(+), 15 deletions(-)
+
+Index: linux/certs/load_uefi.c
+===================================================================
+--- linux.orig/certs/load_uefi.c
++++ linux/certs/load_uefi.c
+@@ -35,8 +35,8 @@ static __init bool uefi_check_ignore_db(
+ /*
+ * Get a certificate list blob from the named EFI variable.
+ */
+-static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid,
+- unsigned long *size)
++static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid,
++ unsigned long *size, void **cert_list)
+ {
+ efi_status_t status;
+ unsigned long lsize = 4;
+@@ -44,26 +44,33 @@ static __init void *get_cert_list(efi_ch
+ void *db;
+
+ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
++ if (status == EFI_NOT_FOUND) {
++ *size = 0;
++ *cert_list = NULL;
++ return 0;
++ }
++
+ if (status != EFI_BUFFER_TOO_SMALL) {
+ pr_err("Couldn't get size: 0x%lx\n", status);
+- return NULL;
++ return efi_status_to_err(status);
+ }
+
+ db = kmalloc(lsize, GFP_KERNEL);
+ if (!db) {
+ pr_err("Couldn't allocate memory for uefi cert list\n");
+- return NULL;
++ return -ENOMEM;
+ }
+
+ status = efi.get_variable(name, guid, NULL, &lsize, db);
+ if (status != EFI_SUCCESS) {
+ kfree(db);
+ pr_err("Error reading db var: 0x%lx\n", status);
+- return NULL;
++ return efi_status_to_err(status);
+ }
+
+ *size = lsize;
+- return db;
++ *cert_list = db;
++ return 0;
+ }
+
+ /*
+@@ -152,10 +159,10 @@ static int __init load_uefi_certs(void)
+ * an error if we can't get them.
+ */
+ if (!uefi_check_ignore_db()) {
+- db = get_cert_list(L"db", &secure_var, &dbsize);
+- if (!db) {
++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db);
++ if (rc < 0) {
+ pr_err("MODSIGN: Couldn't get UEFI db list\n");
+- } else {
++ } else if (dbsize != 0) {
+ rc = parse_efi_signature_list("UEFI:db",
+ db, dbsize, get_handler_for_db);
+ if (rc)
+@@ -164,10 +171,10 @@ static int __init load_uefi_certs(void)
+ }
+ }
+
+- mok = get_cert_list(L"MokListRT", &mok_var, &moksize);
+- if (!mok) {
++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
++ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
+- } else {
++ } else if (moksize != 0) {
+ rc = parse_efi_signature_list("UEFI:MokListRT",
+ mok, moksize, get_handler_for_db);
+ if (rc)
+@@ -175,10 +182,10 @@ static int __init load_uefi_certs(void)
+ kfree(mok);
+ }
+
+- dbx = get_cert_list(L"dbx", &secure_var, &dbxsize);
+- if (!dbx) {
++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx);
++ if (rc < 0) {
+ pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
+- } else {
++ } else if (dbxsize != 0) {
+ rc = parse_efi_signature_list("UEFI:dbx",
+ dbx, dbxsize,
+ get_handler_for_dbx);
diff --git a/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch
new file mode 100644
index 000000000..b831869e4
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch
@@ -0,0 +1,28 @@
+From: Ke Wu <mikewu@google.com>
+Date: Tue, 6 Nov 2018 15:21:30 -0800
+Subject: modsign: use all trusted keys to verify module signature
+Origin: https://git.kernel.org/linus/e84cd7ee630e44a2cc8ae49e85920a271b214cb3
+
+Make mod_verify_sig to use all trusted keys. This allows keys in
+secondary_trusted_keys to be used to verify PKCS#7 signature on a
+kernel module.
+
+Signed-off-by: Ke Wu <mikewu@google.com>
+Signed-off-by: Jessica Yu <jeyu@kernel.org>
+---
+ kernel/module_signing.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: linux/kernel/module_signing.c
+===================================================================
+--- linux.orig/kernel/module_signing.c
++++ linux/kernel/module_signing.c
+@@ -83,6 +83,7 @@ int mod_verify_sig(const void *mod, stru
+ }
+
+ return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
+- NULL, VERIFYING_MODULE_SIGNATURE,
++ VERIFY_USE_SECONDARY_KEYRING,
++ VERIFYING_MODULE_SIGNATURE,
+ NULL, NULL);
+ }
diff --git a/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch
new file mode 100644
index 000000000..a0aea95a2
--- /dev/null
+++ b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch
@@ -0,0 +1,30 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 05 May 2019 13:45:06 +0100
+Subject: MODSIGN: Make shash allocation failure fatal
+
+mod_is_hash_blacklisted() currently returns 0 (suceess) if
+crypto_alloc_shash() fails. This should instead be a fatal error,
+so unwrap and pass up the error code.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/kernel/module_signing.c
+===================================================================
+--- linux.orig/kernel/module_signing.c
++++ linux/kernel/module_signing.c
+@@ -51,11 +51,13 @@ static int mod_is_hash_blacklisted(const
+ struct shash_desc *desc;
+ size_t digest_size, desc_size;
+ u8 *digest;
+- int ret = 0;
++ int ret;
+
+ tfm = crypto_alloc_shash("sha256", 0, 0);
+- if (IS_ERR(tfm))
++ if (IS_ERR(tfm)) {
++ ret = PTR_ERR(tfm);
+ goto error_return;
++ }
+
+ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
+ digest_size = crypto_shash_digestsize(tfm);
diff --git a/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch
new file mode 100644
index 000000000..2d3b1a5da
--- /dev/null
+++ b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch
@@ -0,0 +1,149 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 24 Aug 2009 23:19:58 +0100
+Subject: af9005: Use request_firmware() to load register init script
+Forwarded: no
+
+Read the register init script from the Windows driver. This is sick
+but should avoid the potential copyright infringement in distributing
+a version of the script which is directly derived from the driver.
+---
+ drivers/media/dvb/dvb-usb/Kconfig | 2 +-
+ drivers/media/dvb/dvb-usb/af9005-fe.c | 66 ++++++++++++++++++++++++++------
+ 2 files changed, 54 insertions(+), 14 deletions(-)
+
+Index: linux/drivers/media/usb/dvb-usb/Kconfig
+===================================================================
+--- linux.orig/drivers/media/usb/dvb-usb/Kconfig
++++ linux/drivers/media/usb/dvb-usb/Kconfig
+@@ -246,10 +246,10 @@ config DVB_USB_OPERA1
+
+ config DVB_USB_AF9005
+ tristate "Afatech AF9005 DVB-T USB1.1 support"
+- depends on BROKEN
+ depends on DVB_USB
+ select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT
+ select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT
++ select FW_LOADER
+ help
+ Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
+ and the TerraTec Cinergy T USB XE (Rev.1)
+Index: linux/drivers/media/usb/dvb-usb/af9005-fe.c
+===================================================================
+--- linux.orig/drivers/media/usb/dvb-usb/af9005-fe.c
++++ linux/drivers/media/usb/dvb-usb/af9005-fe.c
+@@ -18,10 +18,26 @@
+ * see Documentation/media/dvb-drivers/dvb-usb.rst for more information
+ */
+ #include "af9005.h"
+-#include "af9005-script.h"
+ #include "mt2060.h"
+ #include "qt1010.h"
+ #include <asm/div64.h>
++#include <linux/firmware.h>
++
++/* Register initialisation script to be extracted from the Windows driver */
++
++typedef struct {
++ __le16 reg;
++ u8 pos;
++ u8 len;
++ u8 val;
++ u8 pad;
++} __packed RegDesc;
++
++#define WIN_DRV_NAME "AF05BDA.sys"
++#define WIN_DRV_VERSION "6.3.2.1"
++#define WIN_DRV_SIZE 133504
++#define WIN_DRV_SCRIPT_OFFSET 88316
++#define WIN_DRV_SCRIPT_SIZE 1110
+
+ struct af9005_fe_state {
+ struct dvb_usb_device *d;
+@@ -813,6 +829,8 @@ static int af9005_fe_init(struct dvb_fro
+ {
+ struct af9005_fe_state *state = fe->demodulator_priv;
+ struct dvb_usb_adapter *adap = fe->dvb->priv;
++ const struct firmware *fw;
++ const RegDesc *script;
+ int ret, i, scriptlen;
+ u8 temp, temp0 = 0, temp1 = 0, temp2 = 0;
+ u8 buf[2];
+@@ -965,37 +983,55 @@ static int af9005_fe_init(struct dvb_fro
+ if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01)))
+ return ret;
+
+- /* load init script */
+- deb_info("load init script\n");
+- scriptlen = sizeof(script) / sizeof(RegDesc);
++ /* load and validate init script */
++ deb_info("load init script from Windows driver\n");
++ ret = request_firmware(&fw, WIN_DRV_NAME, &state->d->udev->dev);
++ if (ret)
++ return ret;
++ BUILD_BUG_ON(sizeof(RegDesc) != 6);
++ if (fw->size != WIN_DRV_SIZE ||
++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET,
++ "\x80\xa1\x00\x08\x0a\x00", 6) ||
++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET + WIN_DRV_SCRIPT_SIZE - 6,
++ "\x49\xa3\x00\x06\x02\x00", 6)) {
++ err("%s is invalid - should be version %s, size %u bytes\n",
++ WIN_DRV_NAME, WIN_DRV_VERSION, WIN_DRV_SIZE);
++ ret = -EINVAL;
++ goto fail_release;
++ }
++
++ script = (const RegDesc *)(fw->data + WIN_DRV_SCRIPT_OFFSET);
++ scriptlen = WIN_DRV_SCRIPT_SIZE / sizeof(RegDesc);
+ for (i = 0; i < scriptlen; i++) {
++ u16 reg = le16_to_cpu(script[i].reg);
+ if ((ret =
+- af9005_write_register_bits(state->d, script[i].reg,
++ af9005_write_register_bits(state->d, reg,
+ script[i].pos,
+ script[i].len, script[i].val)))
+- return ret;
++ goto fail_release;
+ /* save 3 bytes of original fcw */
+- if (script[i].reg == 0xae18)
++ if (reg == 0xae18)
+ temp2 = script[i].val;
+- if (script[i].reg == 0xae19)
++ if (reg == 0xae19)
+ temp1 = script[i].val;
+- if (script[i].reg == 0xae1a)
++ if (reg == 0xae1a)
+ temp0 = script[i].val;
+
+ /* save original unplug threshold */
+- if (script[i].reg == xd_p_reg_unplug_th)
++ if (reg == xd_p_reg_unplug_th)
+ state->original_if_unplug_th = script[i].val;
+- if (script[i].reg == xd_p_reg_unplug_rf_gain_th)
++ if (reg == xd_p_reg_unplug_rf_gain_th)
+ state->original_rf_unplug_th = script[i].val;
+- if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th)
++ if (reg == xd_p_reg_unplug_dtop_if_gain_th)
+ state->original_dtop_if_unplug_th = script[i].val;
+- if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th)
++ if (reg == xd_p_reg_unplug_dtop_rf_gain_th)
+ state->original_dtop_rf_unplug_th = script[i].val;
+
+ }
+ state->original_fcw =
+ ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0;
+
++ release_firmware(fw);
+
+ /* save original TOPs */
+ deb_info("save original TOPs\n");
+@@ -1075,6 +1111,10 @@ static int af9005_fe_init(struct dvb_fro
+
+ deb_info("profit!\n");
+ return 0;
++
++fail_release:
++ release_firmware(fw);
++ return ret;
+ }
+
+ static int af9005_fe_sleep(struct dvb_frontend *fe)
diff --git a/debian/patches/features/all/e1000e-Add-support-for-Comet-Lake.patch b/debian/patches/features/all/e1000e-Add-support-for-Comet-Lake.patch
new file mode 100644
index 000000000..2cb42334d
--- /dev/null
+++ b/debian/patches/features/all/e1000e-Add-support-for-Comet-Lake.patch
@@ -0,0 +1,54 @@
+From: Sasha Neftin <sasha.neftin@intel.com>
+Date: Thu, 10 Oct 2019 13:15:39 +0300
+Subject: e1000e: Add support for Comet Lake
+Origin: https://git.kernel.org/linus/914ee9c436cbe90c8ca8a46ec8433cb614a2ada5
+
+Add devices ID's for the next LOM generations that will be
+available on the next Intel Client platform (Comet Lake)
+This patch provides the initial support for these devices
+
+Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+---
+ drivers/net/ethernet/intel/e1000e/hw.h | 6 ++++++
+ drivers/net/ethernet/intel/e1000e/netdev.c | 6 ++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
+index eff75bd8a8f0..11fdc27faa82 100644
+--- a/drivers/net/ethernet/intel/e1000e/hw.h
++++ b/drivers/net/ethernet/intel/e1000e/hw.h
+@@ -86,6 +86,12 @@ struct e1000_hw;
+ #define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0
+ #define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1
+ #define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2
++#define E1000_DEV_ID_PCH_CMP_I219_LM10 0x0D4E
++#define E1000_DEV_ID_PCH_CMP_I219_V10 0x0D4F
++#define E1000_DEV_ID_PCH_CMP_I219_LM11 0x0D4C
++#define E1000_DEV_ID_PCH_CMP_I219_V11 0x0D4D
++#define E1000_DEV_ID_PCH_CMP_I219_LM12 0x0D53
++#define E1000_DEV_ID_PCH_CMP_I219_V12 0x0D55
+
+ #define E1000_REVISION_4 4
+
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index 42f57ab8fb8e..731e1b3e103a 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -7749,6 +7749,12 @@ static const struct pci_device_id e1000_pci_tbl[] = {
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_V8), board_pch_cnp },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_LM9), board_pch_cnp },
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_V9), board_pch_cnp },
++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM10), board_pch_cnp },
++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V10), board_pch_cnp },
++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM11), board_pch_cnp },
++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V11), board_pch_cnp },
++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM12), board_pch_spt },
++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V12), board_pch_spt },
+
+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
+ };
+--
+2.27.0
+
diff --git a/debian/patches/features/all/ena/0001-net-ethernet-remove-redundant-include.patch b/debian/patches/features/all/ena/0001-net-ethernet-remove-redundant-include.patch
new file mode 100644
index 000000000..0c681dd2a
--- /dev/null
+++ b/debian/patches/features/all/ena/0001-net-ethernet-remove-redundant-include.patch
@@ -0,0 +1,34 @@
+From: zhong jiang <zhongjiang@huawei.com>
+Date: Wed, 28 Nov 2018 23:04:48 -0800
+Subject: [PATCH 01/19] net: ethernet: remove redundant include
+Origin: https://git.kernel.org/linus/e641e99f261f5203a911a9e0db54a214460d2cc4
+
+Manual cherry-pick from e641e99f261f5203a911a9e0db54a214460d2cc4:
+
+ module.h already contained moduleparam.h, so it is safe to remove
+ the redundant include.
+
+ The issue is detected with the help of Coccinelle.
+
+ Signed-off-by: zhong jiang <zhongjiang@huawei.com>
+ Signed-off-by: David S. Miller <davem@davemloft.net>
+
+limited only to the amazon/ena driver
+
+Signed-off-by: Noah Meyerhans <noahm@debian.org>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -39,7 +39,6 @@
+ #include <linux/if_vlan.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/moduleparam.h>
+ #include <linux/numa.h>
+ #include <linux/pci.h>
+ #include <linux/utsname.h>
diff --git a/debian/patches/features/all/ena/0002-net-ena-minor-performance-improvement.patch b/debian/patches/features/all/ena/0002-net-ena-minor-performance-improvement.patch
new file mode 100644
index 000000000..f4f95e9fa
--- /dev/null
+++ b/debian/patches/features/all/ena/0002-net-ena-minor-performance-improvement.patch
@@ -0,0 +1,139 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:16 +0300
+Subject: [PATCH 02/19] net: ena: minor performance improvement
+Origin: https://git.kernel.org/linus/0e575f8542d1f4d74df30b5a9ba419c5373d01a1
+
+Reduce fastpath overhead by making ena_com_tx_comp_req_id_get() inline.
+Also move it to ena_eth_com.h file with its dependency function
+ena_com_cq_inc_head().
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_eth_com.c | 43 -----------------
+ drivers/net/ethernet/amazon/ena/ena_eth_com.h | 46 ++++++++++++++++++-
+ 2 files changed, 44 insertions(+), 45 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+@@ -59,15 +59,6 @@ static inline struct ena_eth_io_rx_cdesc
+ return cdesc;
+ }
+
+-static inline void ena_com_cq_inc_head(struct ena_com_io_cq *io_cq)
+-{
+- io_cq->head++;
+-
+- /* Switch phase bit in case of wrap around */
+- if (unlikely((io_cq->head & (io_cq->q_depth - 1)) == 0))
+- io_cq->phase ^= 1;
+-}
+-
+ static inline void *get_sq_desc(struct ena_com_io_sq *io_sq)
+ {
+ u16 tail_masked;
+@@ -476,40 +467,6 @@ int ena_com_add_single_rx_desc(struct en
+
+ return 0;
+ }
+-
+-int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id)
+-{
+- u8 expected_phase, cdesc_phase;
+- struct ena_eth_io_tx_cdesc *cdesc;
+- u16 masked_head;
+-
+- masked_head = io_cq->head & (io_cq->q_depth - 1);
+- expected_phase = io_cq->phase;
+-
+- cdesc = (struct ena_eth_io_tx_cdesc *)
+- ((uintptr_t)io_cq->cdesc_addr.virt_addr +
+- (masked_head * io_cq->cdesc_entry_size_in_bytes));
+-
+- /* When the current completion descriptor phase isn't the same as the
+- * expected, it mean that the device still didn't update
+- * this completion.
+- */
+- cdesc_phase = READ_ONCE(cdesc->flags) & ENA_ETH_IO_TX_CDESC_PHASE_MASK;
+- if (cdesc_phase != expected_phase)
+- return -EAGAIN;
+-
+- dma_rmb();
+- if (unlikely(cdesc->req_id >= io_cq->q_depth)) {
+- pr_err("Invalid req id %d\n", cdesc->req_id);
+- return -EINVAL;
+- }
+-
+- ena_com_cq_inc_head(io_cq);
+-
+- *req_id = READ_ONCE(cdesc->req_id);
+-
+- return 0;
+-}
+
+ bool ena_com_cq_empty(struct ena_com_io_cq *io_cq)
+ {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+@@ -86,8 +86,6 @@ int ena_com_add_single_rx_desc(struct en
+ struct ena_com_buf *ena_buf,
+ u16 req_id);
+
+-int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id);
+-
+ bool ena_com_cq_empty(struct ena_com_io_cq *io_cq);
+
+ static inline void ena_com_unmask_intr(struct ena_com_io_cq *io_cq,
+@@ -159,4 +157,48 @@ static inline void ena_com_comp_ack(stru
+ io_sq->next_to_comp += elem;
+ }
+
++static inline void ena_com_cq_inc_head(struct ena_com_io_cq *io_cq)
++{
++ io_cq->head++;
++
++ /* Switch phase bit in case of wrap around */
++ if (unlikely((io_cq->head & (io_cq->q_depth - 1)) == 0))
++ io_cq->phase ^= 1;
++}
++
++static inline int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq,
++ u16 *req_id)
++{
++ u8 expected_phase, cdesc_phase;
++ struct ena_eth_io_tx_cdesc *cdesc;
++ u16 masked_head;
++
++ masked_head = io_cq->head & (io_cq->q_depth - 1);
++ expected_phase = io_cq->phase;
++
++ cdesc = (struct ena_eth_io_tx_cdesc *)
++ ((uintptr_t)io_cq->cdesc_addr.virt_addr +
++ (masked_head * io_cq->cdesc_entry_size_in_bytes));
++
++ /* When the current completion descriptor phase isn't the same as the
++ * expected, it mean that the device still didn't update
++ * this completion.
++ */
++ cdesc_phase = READ_ONCE(cdesc->flags) & ENA_ETH_IO_TX_CDESC_PHASE_MASK;
++ if (cdesc_phase != expected_phase)
++ return -EAGAIN;
++
++ dma_rmb();
++
++ *req_id = READ_ONCE(cdesc->req_id);
++ if (unlikely(*req_id >= io_cq->q_depth)) {
++ pr_err("Invalid req id %d\n", cdesc->req_id);
++ return -EINVAL;
++ }
++
++ ena_com_cq_inc_head(io_cq);
++
++ return 0;
++}
++
+ #endif /* ENA_ETH_COM_H_ */
diff --git a/debian/patches/features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch b/debian/patches/features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch
new file mode 100644
index 000000000..a7e02fd9e
--- /dev/null
+++ b/debian/patches/features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch
@@ -0,0 +1,178 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:17 +0300
+Subject: [PATCH 03/19] net: ena: complete host info to match latest ENA spec
+Origin: https://git.kernel.org/linus/095f2f1facba0c78f23750dba65c78cef722c1ea
+
+Add new fields and definitions to host info and fill them
+according to the latest ENA spec version.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/amazon/ena/ena_admin_defs.h | 31 ++++++++++++++++++-
+ drivers/net/ethernet/amazon/ena/ena_com.c | 12 +++----
+ .../net/ethernet/amazon/ena/ena_common_defs.h | 4 +--
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 ++++--
+ 4 files changed, 43 insertions(+), 14 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+@@ -63,6 +63,8 @@ enum ena_admin_aq_completion_status {
+ ENA_ADMIN_ILLEGAL_PARAMETER = 5,
+
+ ENA_ADMIN_UNKNOWN_ERROR = 6,
++
++ ENA_ADMIN_RESOURCE_BUSY = 7,
+ };
+
+ enum ena_admin_aq_feature_id {
+@@ -702,6 +704,10 @@ enum ena_admin_os_type {
+ ENA_ADMIN_OS_FREEBSD = 4,
+
+ ENA_ADMIN_OS_IPXE = 5,
++
++ ENA_ADMIN_OS_ESXI = 6,
++
++ ENA_ADMIN_OS_GROUPS_NUM = 6,
+ };
+
+ struct ena_admin_host_info {
+@@ -723,11 +729,27 @@ struct ena_admin_host_info {
+ /* 7:0 : major
+ * 15:8 : minor
+ * 23:16 : sub_minor
++ * 31:24 : module_type
+ */
+ u32 driver_version;
+
+ /* features bitmap */
+- u32 supported_network_features[4];
++ u32 supported_network_features[2];
++
++ /* ENA spec version of driver */
++ u16 ena_spec_version;
++
++ /* ENA device's Bus, Device and Function
++ * 2:0 : function
++ * 7:3 : device
++ * 15:8 : bus
++ */
++ u16 bdf;
++
++ /* Number of CPUs */
++ u16 num_cpus;
++
++ u16 reserved;
+ };
+
+ struct ena_admin_rss_ind_table_entry {
+@@ -1008,6 +1030,13 @@ struct ena_admin_ena_mmio_req_read_less_
+ #define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8)
+ #define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16
+ #define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16)
++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT 24
++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_MASK GENMASK(31, 24)
++#define ENA_ADMIN_HOST_INFO_FUNCTION_MASK GENMASK(2, 0)
++#define ENA_ADMIN_HOST_INFO_DEVICE_SHIFT 3
++#define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3)
++#define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8
++#define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8)
+
+ /* aenq_common_desc */
+ #define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0)
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -41,9 +41,6 @@
+ #define ENA_ASYNC_QUEUE_DEPTH 16
+ #define ENA_ADMIN_QUEUE_DEPTH 32
+
+-#define MIN_ENA_VER (((ENA_COMMON_SPEC_VERSION_MAJOR) << \
+- ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) \
+- | (ENA_COMMON_SPEC_VERSION_MINOR))
+
+ #define ENA_CTRL_MAJOR 0
+ #define ENA_CTRL_MINOR 0
+@@ -1400,11 +1397,6 @@ int ena_com_validate_version(struct ena_
+ ENA_REGS_VERSION_MAJOR_VERSION_SHIFT,
+ ver & ENA_REGS_VERSION_MINOR_VERSION_MASK);
+
+- if (ver < MIN_ENA_VER) {
+- pr_err("ENA version is lower than the minimal version the driver supports\n");
+- return -1;
+- }
+-
+ pr_info("ena controller version: %d.%d.%d implementation version %d\n",
+ (ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK) >>
+ ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT,
+@@ -2441,6 +2433,10 @@ int ena_com_allocate_host_info(struct en
+ if (unlikely(!host_attr->host_info))
+ return -ENOMEM;
+
++ host_attr->host_info->ena_spec_version =
++ ((ENA_COMMON_SPEC_VERSION_MAJOR << ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) |
++ (ENA_COMMON_SPEC_VERSION_MINOR));
++
+ return 0;
+ }
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_common_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_common_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_common_defs.h
+@@ -32,8 +32,8 @@
+ #ifndef _ENA_COMMON_H_
+ #define _ENA_COMMON_H_
+
+-#define ENA_COMMON_SPEC_VERSION_MAJOR 0 /* */
+-#define ENA_COMMON_SPEC_VERSION_MINOR 10 /* */
++#define ENA_COMMON_SPEC_VERSION_MAJOR 2
++#define ENA_COMMON_SPEC_VERSION_MINOR 0
+
+ /* ENA operates with 48-bit memory addresses. ena_mem_addr_t */
+ struct ena_common_mem_addr {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2206,7 +2206,8 @@ static u16 ena_select_queue(struct net_d
+ return qid;
+ }
+
+-static void ena_config_host_info(struct ena_com_dev *ena_dev)
++static void ena_config_host_info(struct ena_com_dev *ena_dev,
++ struct pci_dev *pdev)
+ {
+ struct ena_admin_host_info *host_info;
+ int rc;
+@@ -2220,6 +2221,7 @@ static void ena_config_host_info(struct
+
+ host_info = ena_dev->host_attr.host_info;
+
++ host_info->bdf = (pdev->bus->number << 8) | pdev->devfn;
+ host_info->os_type = ENA_ADMIN_OS_LINUX;
+ host_info->kernel_ver = LINUX_VERSION_CODE;
+ strlcpy(host_info->kernel_ver_str, utsname()->version,
+@@ -2230,7 +2232,9 @@ static void ena_config_host_info(struct
+ host_info->driver_version =
+ (DRV_MODULE_VER_MAJOR) |
+ (DRV_MODULE_VER_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) |
+- (DRV_MODULE_VER_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT);
++ (DRV_MODULE_VER_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT) |
++ ("K"[0] << ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT);
++ host_info->num_cpus = num_online_cpus();
+
+ rc = ena_com_set_host_attributes(ena_dev);
+ if (rc) {
+@@ -2454,7 +2458,7 @@ static int ena_device_init(struct ena_co
+ */
+ ena_com_set_admin_polling_mode(ena_dev, true);
+
+- ena_config_host_info(ena_dev);
++ ena_config_host_info(ena_dev, pdev);
+
+ /* Get Device Attributes*/
+ rc = ena_com_get_dev_attr_feat(ena_dev, get_feat_ctx);
diff --git a/debian/patches/features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch b/debian/patches/features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch
new file mode 100644
index 000000000..51e655bab
--- /dev/null
+++ b/debian/patches/features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch
@@ -0,0 +1,271 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:18 +0300
+Subject: [PATCH 04/19] net: ena: introduce Low Latency Queues data structures
+ according to ENA spec
+Origin: https://git.kernel.org/linus/a7982b8ec947052df6d4467b3a81571f02f528e0
+
+Low Latency Queues(LLQ) allow usage of device's memory for descriptors
+and headers. Such queues decrease processing time since data is already
+located on the device when driver rings the doorbell.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/amazon/ena/ena_admin_defs.h | 90 ++++++++++++++++++-
+ drivers/net/ethernet/amazon/ena/ena_com.h | 38 ++++++++
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 6 +-
+ 3 files changed, 128 insertions(+), 6 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+@@ -74,6 +74,8 @@ enum ena_admin_aq_feature_id {
+
+ ENA_ADMIN_HW_HINTS = 3,
+
++ ENA_ADMIN_LLQ = 4,
++
+ ENA_ADMIN_RSS_HASH_FUNCTION = 10,
+
+ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11,
+@@ -485,8 +487,85 @@ struct ena_admin_device_attr_feature_des
+ u32 max_mtu;
+ };
+
++enum ena_admin_llq_header_location {
++ /* header is in descriptor list */
++ ENA_ADMIN_INLINE_HEADER = 1,
++ /* header in a separate ring, implies 16B descriptor list entry */
++ ENA_ADMIN_HEADER_RING = 2,
++};
++
++enum ena_admin_llq_ring_entry_size {
++ ENA_ADMIN_LIST_ENTRY_SIZE_128B = 1,
++ ENA_ADMIN_LIST_ENTRY_SIZE_192B = 2,
++ ENA_ADMIN_LIST_ENTRY_SIZE_256B = 4,
++};
++
++enum ena_admin_llq_num_descs_before_header {
++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_0 = 0,
++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1 = 1,
++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2 = 2,
++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4 = 4,
++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8 = 8,
++};
++
++/* packet descriptor list entry always starts with one or more descriptors,
++ * followed by a header. The rest of the descriptors are located in the
++ * beginning of the subsequent entry. Stride refers to how the rest of the
++ * descriptors are placed. This field is relevant only for inline header
++ * mode
++ */
++enum ena_admin_llq_stride_ctrl {
++ ENA_ADMIN_SINGLE_DESC_PER_ENTRY = 1,
++ ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY = 2,
++};
++
++struct ena_admin_feature_llq_desc {
++ u32 max_llq_num;
++
++ u32 max_llq_depth;
++
++ /* specify the header locations the device supports. bitfield of
++ * enum ena_admin_llq_header_location.
++ */
++ u16 header_location_ctrl_supported;
++
++ /* the header location the driver selected to use. */
++ u16 header_location_ctrl_enabled;
++
++ /* if inline header is specified - this is the size of descriptor
++ * list entry. If header in a separate ring is specified - this is
++ * the size of header ring entry. bitfield of enum
++ * ena_admin_llq_ring_entry_size. specify the entry sizes the device
++ * supports
++ */
++ u16 entry_size_ctrl_supported;
++
++ /* the entry size the driver selected to use. */
++ u16 entry_size_ctrl_enabled;
++
++ /* valid only if inline header is specified. First entry associated
++ * with the packet includes descriptors and header. Rest of the
++ * entries occupied by descriptors. This parameter defines the max
++ * number of descriptors precedding the header in the first entry.
++ * The field is bitfield of enum
++ * ena_admin_llq_num_descs_before_header and specify the values the
++ * device supports
++ */
++ u16 desc_num_before_header_supported;
++
++ /* the desire field the driver selected to use */
++ u16 desc_num_before_header_enabled;
++
++ /* valid only if inline was chosen. bitfield of enum
++ * ena_admin_llq_stride_ctrl
++ */
++ u16 descriptors_stride_ctrl_supported;
++
++ /* the stride control the driver selected to use */
++ u16 descriptors_stride_ctrl_enabled;
++};
++
+ struct ena_admin_queue_feature_desc {
+- /* including LLQs */
+ u32 max_sq_num;
+
+ u32 max_sq_depth;
+@@ -495,9 +574,9 @@ struct ena_admin_queue_feature_desc {
+
+ u32 max_cq_depth;
+
+- u32 max_llq_num;
++ u32 max_legacy_llq_num;
+
+- u32 max_llq_depth;
++ u32 max_legacy_llq_depth;
+
+ u32 max_header_size;
+
+@@ -822,6 +901,8 @@ struct ena_admin_get_feat_resp {
+
+ struct ena_admin_device_attr_feature_desc dev_attr;
+
++ struct ena_admin_feature_llq_desc llq;
++
+ struct ena_admin_queue_feature_desc max_queue;
+
+ struct ena_admin_feature_aenq_desc aenq;
+@@ -869,6 +950,9 @@ struct ena_admin_set_feat_cmd {
+
+ /* rss indirection table */
+ struct ena_admin_feature_rss_ind_table ind_table;
++
++ /* LLQ configuration */
++ struct ena_admin_feature_llq_desc llq;
+ } u;
+ };
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -108,6 +108,14 @@ enum ena_intr_moder_level {
+ ENA_INTR_MAX_NUM_OF_LEVELS,
+ };
+
++struct ena_llq_configurations {
++ enum ena_admin_llq_header_location llq_header_location;
++ enum ena_admin_llq_ring_entry_size llq_ring_entry_size;
++ enum ena_admin_llq_stride_ctrl llq_stride_ctrl;
++ enum ena_admin_llq_num_descs_before_header llq_num_decs_before_header;
++ u16 llq_ring_entry_size_value;
++};
++
+ struct ena_intr_moder_entry {
+ unsigned int intr_moder_interval;
+ unsigned int pkts_per_interval;
+@@ -142,6 +150,15 @@ struct ena_com_tx_meta {
+ u16 l4_hdr_len; /* In words */
+ };
+
++struct ena_com_llq_info {
++ u16 header_location_ctrl;
++ u16 desc_stride_ctrl;
++ u16 desc_list_entry_size_ctrl;
++ u16 desc_list_entry_size;
++ u16 descs_num_before_header;
++ u16 descs_per_entry;
++};
++
+ struct ena_com_io_cq {
+ struct ena_com_io_desc_addr cdesc_addr;
+
+@@ -179,6 +196,20 @@ struct ena_com_io_cq {
+
+ } ____cacheline_aligned;
+
++struct ena_com_io_bounce_buffer_control {
++ u8 *base_buffer;
++ u16 next_to_use;
++ u16 buffer_size;
++ u16 buffers_num; /* Must be a power of 2 */
++};
++
++/* This struct is to keep tracking the current location of the next llq entry */
++struct ena_com_llq_pkt_ctrl {
++ u8 *curr_bounce_buf;
++ u16 idx;
++ u16 descs_left_in_line;
++};
++
+ struct ena_com_io_sq {
+ struct ena_com_io_desc_addr desc_addr;
+
+@@ -190,6 +221,9 @@ struct ena_com_io_sq {
+
+ u32 msix_vector;
+ struct ena_com_tx_meta cached_tx_meta;
++ struct ena_com_llq_info llq_info;
++ struct ena_com_llq_pkt_ctrl llq_buf_ctrl;
++ struct ena_com_io_bounce_buffer_control bounce_buf_ctrl;
+
+ u16 q_depth;
+ u16 qid;
+@@ -197,6 +231,7 @@ struct ena_com_io_sq {
+ u16 idx;
+ u16 tail;
+ u16 next_to_comp;
++ u16 llq_last_copy_tail;
+ u32 tx_max_header_size;
+ u8 phase;
+ u8 desc_entry_size;
+@@ -334,6 +369,8 @@ struct ena_com_dev {
+ u16 intr_delay_resolution;
+ u32 intr_moder_tx_interval;
+ struct ena_intr_moder_entry *intr_moder_tbl;
++
++ struct ena_com_llq_info llq_info;
+ };
+
+ struct ena_com_dev_get_features_ctx {
+@@ -342,6 +379,7 @@ struct ena_com_dev_get_features_ctx {
+ struct ena_admin_feature_aenq_desc aenq;
+ struct ena_admin_feature_offload_desc offload;
+ struct ena_admin_ena_hw_hints hw_hints;
++ struct ena_admin_feature_llq_desc llq;
+ };
+
+ struct ena_com_create_io_ctx {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2959,7 +2959,7 @@ static int ena_calc_io_queue_num(struct
+
+ /* In case of LLQ use the llq number in the get feature cmd */
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+- io_sq_num = get_feat_ctx->max_queues.max_llq_num;
++ io_sq_num = get_feat_ctx->max_queues.max_legacy_llq_num;
+
+ if (io_sq_num == 0) {
+ dev_err(&pdev->dev,
+@@ -2995,7 +2995,7 @@ static void ena_set_push_mode(struct pci
+ has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR);
+
+ /* Enable push mode if device supports LLQ */
+- if (has_mem_bar && (get_feat_ctx->max_queues.max_llq_num > 0))
++ if (has_mem_bar && get_feat_ctx->max_queues.max_legacy_llq_num > 0)
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV;
+ else
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+@@ -3131,7 +3131,7 @@ static int ena_calc_queue_size(struct pc
+
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+ queue_size = min_t(u32, queue_size,
+- get_feat_ctx->max_queues.max_llq_depth);
++ get_feat_ctx->max_queues.max_legacy_llq_depth);
+
+ queue_size = rounddown_pow_of_two(queue_size);
+
diff --git a/debian/patches/features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch b/debian/patches/features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch
new file mode 100644
index 000000000..375541b10
--- /dev/null
+++ b/debian/patches/features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch
@@ -0,0 +1,832 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:19 +0300
+Subject: [PATCH 05/19] net: ena: add functions for handling Low Latency Queues
+ in ena_com
+Origin: https://git.kernel.org/linus/689b2bdaaa1480ad2c14bdc4c6eaf38284549022
+
+This patch introduces APIs for detection, initialization, configuration
+and actual usage of low latency queues(LLQ). It extends transmit API with
+creation of LLQ descriptors in device memory (which include host buffers
+descriptors as well as packet header)
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 249 +++++++++++++++++-
+ drivers/net/ethernet/amazon/ena/ena_com.h | 28 ++
+ drivers/net/ethernet/amazon/ena/ena_eth_com.c | 231 ++++++++++++----
+ drivers/net/ethernet/amazon/ena/ena_eth_com.h | 25 +-
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 21 +-
+ 5 files changed, 474 insertions(+), 80 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -58,6 +58,8 @@
+
+ #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF
+
++#define ENA_COM_BOUNCE_BUFFER_CNTRL_CNT 4
++
+ #define ENA_REGS_ADMIN_INTR_MASK 1
+
+ #define ENA_POLL_MS 5
+@@ -352,21 +354,48 @@ static int ena_com_init_io_sq(struct ena
+ &io_sq->desc_addr.phys_addr,
+ GFP_KERNEL);
+ }
+- } else {
++
++ if (!io_sq->desc_addr.virt_addr) {
++ pr_err("memory allocation failed");
++ return -ENOMEM;
++ }
++ }
++
++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
++ /* Allocate bounce buffers */
++ io_sq->bounce_buf_ctrl.buffer_size =
++ ena_dev->llq_info.desc_list_entry_size;
++ io_sq->bounce_buf_ctrl.buffers_num =
++ ENA_COM_BOUNCE_BUFFER_CNTRL_CNT;
++ io_sq->bounce_buf_ctrl.next_to_use = 0;
++
++ size = io_sq->bounce_buf_ctrl.buffer_size *
++ io_sq->bounce_buf_ctrl.buffers_num;
++
+ dev_node = dev_to_node(ena_dev->dmadev);
+ set_dev_node(ena_dev->dmadev, ctx->numa_node);
+- io_sq->desc_addr.virt_addr =
++ io_sq->bounce_buf_ctrl.base_buffer =
+ devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
+ set_dev_node(ena_dev->dmadev, dev_node);
+- if (!io_sq->desc_addr.virt_addr) {
+- io_sq->desc_addr.virt_addr =
++ if (!io_sq->bounce_buf_ctrl.base_buffer)
++ io_sq->bounce_buf_ctrl.base_buffer =
+ devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
++
++ if (!io_sq->bounce_buf_ctrl.base_buffer) {
++ pr_err("bounce buffer memory allocation failed");
++ return -ENOMEM;
+ }
+- }
+
+- if (!io_sq->desc_addr.virt_addr) {
+- pr_err("memory allocation failed");
+- return -ENOMEM;
++ memcpy(&io_sq->llq_info, &ena_dev->llq_info,
++ sizeof(io_sq->llq_info));
++
++ /* Initiate the first bounce buffer */
++ io_sq->llq_buf_ctrl.curr_bounce_buf =
++ ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl);
++ memset(io_sq->llq_buf_ctrl.curr_bounce_buf,
++ 0x0, io_sq->llq_info.desc_list_entry_size);
++ io_sq->llq_buf_ctrl.descs_left_in_line =
++ io_sq->llq_info.descs_num_before_header;
+ }
+
+ io_sq->tail = 0;
+@@ -554,6 +583,156 @@ err:
+ return ret;
+ }
+
++/**
++ * Set the LLQ configurations of the firmware
++ *
++ * The driver provides only the enabled feature values to the device,
++ * which in turn, checks if they are supported.
++ */
++static int ena_com_set_llq(struct ena_com_dev *ena_dev)
++{
++ struct ena_com_admin_queue *admin_queue;
++ struct ena_admin_set_feat_cmd cmd;
++ struct ena_admin_set_feat_resp resp;
++ struct ena_com_llq_info *llq_info = &ena_dev->llq_info;
++ int ret;
++
++ memset(&cmd, 0x0, sizeof(cmd));
++ admin_queue = &ena_dev->admin_queue;
++
++ cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE;
++ cmd.feat_common.feature_id = ENA_ADMIN_LLQ;
++
++ cmd.u.llq.header_location_ctrl_enabled = llq_info->header_location_ctrl;
++ cmd.u.llq.entry_size_ctrl_enabled = llq_info->desc_list_entry_size_ctrl;
++ cmd.u.llq.desc_num_before_header_enabled = llq_info->descs_num_before_header;
++ cmd.u.llq.descriptors_stride_ctrl_enabled = llq_info->desc_stride_ctrl;
++
++ ret = ena_com_execute_admin_command(admin_queue,
++ (struct ena_admin_aq_entry *)&cmd,
++ sizeof(cmd),
++ (struct ena_admin_acq_entry *)&resp,
++ sizeof(resp));
++
++ if (unlikely(ret))
++ pr_err("Failed to set LLQ configurations: %d\n", ret);
++
++ return ret;
++}
++
++static int ena_com_config_llq_info(struct ena_com_dev *ena_dev,
++ struct ena_admin_feature_llq_desc *llq_features,
++ struct ena_llq_configurations *llq_default_cfg)
++{
++ struct ena_com_llq_info *llq_info = &ena_dev->llq_info;
++ u16 supported_feat;
++ int rc;
++
++ memset(llq_info, 0, sizeof(*llq_info));
++
++ supported_feat = llq_features->header_location_ctrl_supported;
++
++ if (likely(supported_feat & llq_default_cfg->llq_header_location)) {
++ llq_info->header_location_ctrl =
++ llq_default_cfg->llq_header_location;
++ } else {
++ pr_err("Invalid header location control, supported: 0x%x\n",
++ supported_feat);
++ return -EINVAL;
++ }
++
++ if (likely(llq_info->header_location_ctrl == ENA_ADMIN_INLINE_HEADER)) {
++ supported_feat = llq_features->descriptors_stride_ctrl_supported;
++ if (likely(supported_feat & llq_default_cfg->llq_stride_ctrl)) {
++ llq_info->desc_stride_ctrl = llq_default_cfg->llq_stride_ctrl;
++ } else {
++ if (supported_feat & ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY) {
++ llq_info->desc_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY;
++ } else if (supported_feat & ENA_ADMIN_SINGLE_DESC_PER_ENTRY) {
++ llq_info->desc_stride_ctrl = ENA_ADMIN_SINGLE_DESC_PER_ENTRY;
++ } else {
++ pr_err("Invalid desc_stride_ctrl, supported: 0x%x\n",
++ supported_feat);
++ return -EINVAL;
++ }
++
++ pr_err("Default llq stride ctrl is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n",
++ llq_default_cfg->llq_stride_ctrl, supported_feat,
++ llq_info->desc_stride_ctrl);
++ }
++ } else {
++ llq_info->desc_stride_ctrl = 0;
++ }
++
++ supported_feat = llq_features->entry_size_ctrl_supported;
++ if (likely(supported_feat & llq_default_cfg->llq_ring_entry_size)) {
++ llq_info->desc_list_entry_size_ctrl = llq_default_cfg->llq_ring_entry_size;
++ llq_info->desc_list_entry_size = llq_default_cfg->llq_ring_entry_size_value;
++ } else {
++ if (supported_feat & ENA_ADMIN_LIST_ENTRY_SIZE_128B) {
++ llq_info->desc_list_entry_size_ctrl = ENA_ADMIN_LIST_ENTRY_SIZE_128B;
++ llq_info->desc_list_entry_size = 128;
++ } else if (supported_feat & ENA_ADMIN_LIST_ENTRY_SIZE_192B) {
++ llq_info->desc_list_entry_size_ctrl = ENA_ADMIN_LIST_ENTRY_SIZE_192B;
++ llq_info->desc_list_entry_size = 192;
++ } else if (supported_feat & ENA_ADMIN_LIST_ENTRY_SIZE_256B) {
++ llq_info->desc_list_entry_size_ctrl = ENA_ADMIN_LIST_ENTRY_SIZE_256B;
++ llq_info->desc_list_entry_size = 256;
++ } else {
++ pr_err("Invalid entry_size_ctrl, supported: 0x%x\n",
++ supported_feat);
++ return -EINVAL;
++ }
++
++ pr_err("Default llq ring entry size is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n",
++ llq_default_cfg->llq_ring_entry_size, supported_feat,
++ llq_info->desc_list_entry_size);
++ }
++ if (unlikely(llq_info->desc_list_entry_size & 0x7)) {
++ /* The desc list entry size should be whole multiply of 8
++ * This requirement comes from __iowrite64_copy()
++ */
++ pr_err("illegal entry size %d\n",
++ llq_info->desc_list_entry_size);
++ return -EINVAL;
++ }
++
++ if (llq_info->desc_stride_ctrl == ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY)
++ llq_info->descs_per_entry = llq_info->desc_list_entry_size /
++ sizeof(struct ena_eth_io_tx_desc);
++ else
++ llq_info->descs_per_entry = 1;
++
++ supported_feat = llq_features->desc_num_before_header_supported;
++ if (likely(supported_feat & llq_default_cfg->llq_num_decs_before_header)) {
++ llq_info->descs_num_before_header = llq_default_cfg->llq_num_decs_before_header;
++ } else {
++ if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2) {
++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2;
++ } else if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1) {
++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1;
++ } else if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4) {
++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4;
++ } else if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8) {
++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8;
++ } else {
++ pr_err("Invalid descs_num_before_header, supported: 0x%x\n",
++ supported_feat);
++ return -EINVAL;
++ }
++
++ pr_err("Default llq num descs before header is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n",
++ llq_default_cfg->llq_num_decs_before_header,
++ supported_feat, llq_info->descs_num_before_header);
++ }
++
++ rc = ena_com_set_llq(ena_dev);
++ if (rc)
++ pr_err("Cannot set LLQ configuration: %d\n", rc);
++
++ return 0;
++}
++
+ static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx,
+ struct ena_com_admin_queue *admin_queue)
+ {
+@@ -725,15 +904,17 @@ static void ena_com_io_queue_free(struct
+ if (io_sq->desc_addr.virt_addr) {
+ size = io_sq->desc_entry_size * io_sq->q_depth;
+
+- if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
+- dma_free_coherent(ena_dev->dmadev, size,
+- io_sq->desc_addr.virt_addr,
+- io_sq->desc_addr.phys_addr);
+- else
+- devm_kfree(ena_dev->dmadev, io_sq->desc_addr.virt_addr);
++ dma_free_coherent(ena_dev->dmadev, size,
++ io_sq->desc_addr.virt_addr,
++ io_sq->desc_addr.phys_addr);
+
+ io_sq->desc_addr.virt_addr = NULL;
+ }
++
++ if (io_sq->bounce_buf_ctrl.base_buffer) {
++ devm_kfree(ena_dev->dmadev, io_sq->bounce_buf_ctrl.base_buffer);
++ io_sq->bounce_buf_ctrl.base_buffer = NULL;
++ }
+ }
+
+ static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout,
+@@ -1740,6 +1921,15 @@ int ena_com_get_dev_attr_feat(struct ena
+ else
+ return rc;
+
++ rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ);
++ if (!rc)
++ memcpy(&get_feat_ctx->llq, &get_resp.u.llq,
++ sizeof(get_resp.u.llq));
++ else if (rc == -EOPNOTSUPP)
++ memset(&get_feat_ctx->llq, 0x0, sizeof(get_feat_ctx->llq));
++ else
++ return rc;
++
+ return 0;
+ }
+
+@@ -2708,3 +2898,34 @@ void ena_com_get_intr_moderation_entry(s
+ intr_moder_tbl[level].pkts_per_interval;
+ entry->bytes_per_interval = intr_moder_tbl[level].bytes_per_interval;
+ }
++
++int ena_com_config_dev_mode(struct ena_com_dev *ena_dev,
++ struct ena_admin_feature_llq_desc *llq_features,
++ struct ena_llq_configurations *llq_default_cfg)
++{
++ int rc;
++ int size;
++
++ if (!llq_features->max_llq_num) {
++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
++ return 0;
++ }
++
++ rc = ena_com_config_llq_info(ena_dev, llq_features, llq_default_cfg);
++ if (rc)
++ return rc;
++
++ /* Validate the descriptor is not too big */
++ size = ena_dev->tx_max_header_size;
++ size += ena_dev->llq_info.descs_num_before_header *
++ sizeof(struct ena_eth_io_tx_desc);
++
++ if (unlikely(ena_dev->llq_info.desc_list_entry_size < size)) {
++ pr_err("the size of the LLQ entry is smaller than needed\n");
++ return -EINVAL;
++ }
++
++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV;
++
++ return 0;
++}
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -37,6 +37,7 @@
+ #include <linux/delay.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/gfp.h>
++#include <linux/io.h>
+ #include <linux/sched.h>
+ #include <linux/sizes.h>
+ #include <linux/spinlock.h>
+@@ -973,6 +974,16 @@ void ena_com_get_intr_moderation_entry(s
+ enum ena_intr_moder_level level,
+ struct ena_intr_moder_entry *entry);
+
++/* ena_com_config_dev_mode - Configure the placement policy of the device.
++ * @ena_dev: ENA communication layer struct
++ * @llq_features: LLQ feature descriptor, retrieve via
++ * ena_com_get_dev_attr_feat.
++ * @ena_llq_config: The default driver LLQ parameters configurations
++ */
++int ena_com_config_dev_mode(struct ena_com_dev *ena_dev,
++ struct ena_admin_feature_llq_desc *llq_features,
++ struct ena_llq_configurations *llq_default_config);
++
+ static inline bool ena_com_get_adaptive_moderation_enabled(struct ena_com_dev *ena_dev)
+ {
+ return ena_dev->adaptive_coalescing;
+@@ -1082,4 +1093,21 @@ static inline void ena_com_update_intr_r
+ intr_reg->intr_control |= ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK;
+ }
+
++static inline u8 *ena_com_get_next_bounce_buffer(struct ena_com_io_bounce_buffer_control *bounce_buf_ctrl)
++{
++ u16 size, buffers_num;
++ u8 *buf;
++
++ size = bounce_buf_ctrl->buffer_size;
++ buffers_num = bounce_buf_ctrl->buffers_num;
++
++ buf = bounce_buf_ctrl->base_buffer +
++ (bounce_buf_ctrl->next_to_use++ & (buffers_num - 1)) * size;
++
++ prefetchw(bounce_buf_ctrl->base_buffer +
++ (bounce_buf_ctrl->next_to_use & (buffers_num - 1)) * size);
++
++ return buf;
++}
++
+ #endif /* !(ENA_COM) */
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+@@ -59,7 +59,7 @@ static inline struct ena_eth_io_rx_cdesc
+ return cdesc;
+ }
+
+-static inline void *get_sq_desc(struct ena_com_io_sq *io_sq)
++static inline void *get_sq_desc_regular_queue(struct ena_com_io_sq *io_sq)
+ {
+ u16 tail_masked;
+ u32 offset;
+@@ -71,45 +71,159 @@ static inline void *get_sq_desc(struct e
+ return (void *)((uintptr_t)io_sq->desc_addr.virt_addr + offset);
+ }
+
+-static inline void ena_com_copy_curr_sq_desc_to_dev(struct ena_com_io_sq *io_sq)
++static inline int ena_com_write_bounce_buffer_to_dev(struct ena_com_io_sq *io_sq,
++ u8 *bounce_buffer)
+ {
+- u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1);
+- u32 offset = tail_masked * io_sq->desc_entry_size;
++ struct ena_com_llq_info *llq_info = &io_sq->llq_info;
+
+- /* In case this queue isn't a LLQ */
+- if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
+- return;
++ u16 dst_tail_mask;
++ u32 dst_offset;
+
+- memcpy_toio(io_sq->desc_addr.pbuf_dev_addr + offset,
+- io_sq->desc_addr.virt_addr + offset,
+- io_sq->desc_entry_size);
+-}
++ dst_tail_mask = io_sq->tail & (io_sq->q_depth - 1);
++ dst_offset = dst_tail_mask * llq_info->desc_list_entry_size;
++
++ /* Make sure everything was written into the bounce buffer before
++ * writing the bounce buffer to the device
++ */
++ wmb();
++
++ /* The line is completed. Copy it to dev */
++ __iowrite64_copy(io_sq->desc_addr.pbuf_dev_addr + dst_offset,
++ bounce_buffer, (llq_info->desc_list_entry_size) / 8);
+
+-static inline void ena_com_sq_update_tail(struct ena_com_io_sq *io_sq)
+-{
+ io_sq->tail++;
+
+ /* Switch phase bit in case of wrap around */
+ if (unlikely((io_sq->tail & (io_sq->q_depth - 1)) == 0))
+ io_sq->phase ^= 1;
++
++ return 0;
+ }
+
+-static inline int ena_com_write_header(struct ena_com_io_sq *io_sq,
+- u8 *head_src, u16 header_len)
++static inline int ena_com_write_header_to_bounce(struct ena_com_io_sq *io_sq,
++ u8 *header_src,
++ u16 header_len)
++{
++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl;
++ struct ena_com_llq_info *llq_info = &io_sq->llq_info;
++ u8 *bounce_buffer = pkt_ctrl->curr_bounce_buf;
++ u16 header_offset;
++
++ if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST))
++ return 0;
++
++ header_offset =
++ llq_info->descs_num_before_header * io_sq->desc_entry_size;
++
++ if (unlikely((header_offset + header_len) >
++ llq_info->desc_list_entry_size)) {
++ pr_err("trying to write header larger than llq entry can accommodate\n");
++ return -EFAULT;
++ }
++
++ if (unlikely(!bounce_buffer)) {
++ pr_err("bounce buffer is NULL\n");
++ return -EFAULT;
++ }
++
++ memcpy(bounce_buffer + header_offset, header_src, header_len);
++
++ return 0;
++}
++
++static inline void *get_sq_desc_llq(struct ena_com_io_sq *io_sq)
++{
++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl;
++ u8 *bounce_buffer;
++ void *sq_desc;
++
++ bounce_buffer = pkt_ctrl->curr_bounce_buf;
++
++ if (unlikely(!bounce_buffer)) {
++ pr_err("bounce buffer is NULL\n");
++ return NULL;
++ }
++
++ sq_desc = bounce_buffer + pkt_ctrl->idx * io_sq->desc_entry_size;
++ pkt_ctrl->idx++;
++ pkt_ctrl->descs_left_in_line--;
++
++ return sq_desc;
++}
++
++static inline int ena_com_close_bounce_buffer(struct ena_com_io_sq *io_sq)
+ {
+- u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1);
+- u8 __iomem *dev_head_addr =
+- io_sq->header_addr + (tail_masked * io_sq->tx_max_header_size);
++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl;
++ struct ena_com_llq_info *llq_info = &io_sq->llq_info;
++ int rc;
+
+- if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
++ if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST))
+ return 0;
+
+- if (unlikely(!io_sq->header_addr)) {
+- pr_err("Push buffer header ptr is NULL\n");
+- return -EINVAL;
++ /* bounce buffer was used, so write it and get a new one */
++ if (pkt_ctrl->idx) {
++ rc = ena_com_write_bounce_buffer_to_dev(io_sq,
++ pkt_ctrl->curr_bounce_buf);
++ if (unlikely(rc))
++ return rc;
++
++ pkt_ctrl->curr_bounce_buf =
++ ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl);
++ memset(io_sq->llq_buf_ctrl.curr_bounce_buf,
++ 0x0, llq_info->desc_list_entry_size);
+ }
+
+- memcpy_toio(dev_head_addr, head_src, header_len);
++ pkt_ctrl->idx = 0;
++ pkt_ctrl->descs_left_in_line = llq_info->descs_num_before_header;
++ return 0;
++}
++
++static inline void *get_sq_desc(struct ena_com_io_sq *io_sq)
++{
++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
++ return get_sq_desc_llq(io_sq);
++
++ return get_sq_desc_regular_queue(io_sq);
++}
++
++static inline int ena_com_sq_update_llq_tail(struct ena_com_io_sq *io_sq)
++{
++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl;
++ struct ena_com_llq_info *llq_info = &io_sq->llq_info;
++ int rc;
++
++ if (!pkt_ctrl->descs_left_in_line) {
++ rc = ena_com_write_bounce_buffer_to_dev(io_sq,
++ pkt_ctrl->curr_bounce_buf);
++ if (unlikely(rc))
++ return rc;
++
++ pkt_ctrl->curr_bounce_buf =
++ ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl);
++ memset(io_sq->llq_buf_ctrl.curr_bounce_buf,
++ 0x0, llq_info->desc_list_entry_size);
++
++ pkt_ctrl->idx = 0;
++ if (unlikely(llq_info->desc_stride_ctrl == ENA_ADMIN_SINGLE_DESC_PER_ENTRY))
++ pkt_ctrl->descs_left_in_line = 1;
++ else
++ pkt_ctrl->descs_left_in_line =
++ llq_info->desc_list_entry_size / io_sq->desc_entry_size;
++ }
++
++ return 0;
++}
++
++static inline int ena_com_sq_update_tail(struct ena_com_io_sq *io_sq)
++{
++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
++ return ena_com_sq_update_llq_tail(io_sq);
++
++ io_sq->tail++;
++
++ /* Switch phase bit in case of wrap around */
++ if (unlikely((io_sq->tail & (io_sq->q_depth - 1)) == 0))
++ io_sq->phase ^= 1;
+
+ return 0;
+ }
+@@ -177,8 +291,8 @@ static inline bool ena_com_meta_desc_cha
+ return false;
+ }
+
+-static inline void ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
+- struct ena_com_tx_ctx *ena_tx_ctx)
++static inline int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
++ struct ena_com_tx_ctx *ena_tx_ctx)
+ {
+ struct ena_eth_io_tx_meta_desc *meta_desc = NULL;
+ struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta;
+@@ -223,8 +337,7 @@ static inline void ena_com_create_and_st
+ memcpy(&io_sq->cached_tx_meta, ena_meta,
+ sizeof(struct ena_com_tx_meta));
+
+- ena_com_copy_curr_sq_desc_to_dev(io_sq);
+- ena_com_sq_update_tail(io_sq);
++ return ena_com_sq_update_tail(io_sq);
+ }
+
+ static inline void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx,
+@@ -262,18 +375,19 @@ int ena_com_prepare_tx(struct ena_com_io
+ {
+ struct ena_eth_io_tx_desc *desc = NULL;
+ struct ena_com_buf *ena_bufs = ena_tx_ctx->ena_bufs;
+- void *push_header = ena_tx_ctx->push_header;
++ void *buffer_to_push = ena_tx_ctx->push_header;
+ u16 header_len = ena_tx_ctx->header_len;
+ u16 num_bufs = ena_tx_ctx->num_bufs;
+- int total_desc, i, rc;
++ u16 start_tail = io_sq->tail;
++ int i, rc;
+ bool have_meta;
+ u64 addr_hi;
+
+ WARN(io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_TX, "wrong Q type");
+
+ /* num_bufs +1 for potential meta desc */
+- if (ena_com_sq_empty_space(io_sq) < (num_bufs + 1)) {
+- pr_err("Not enough space in the tx queue\n");
++ if (unlikely(!ena_com_sq_have_enough_space(io_sq, num_bufs + 1))) {
++ pr_debug("Not enough space in the tx queue\n");
+ return -ENOMEM;
+ }
+
+@@ -283,23 +397,32 @@ int ena_com_prepare_tx(struct ena_com_io
+ return -EINVAL;
+ }
+
+- /* start with pushing the header (if needed) */
+- rc = ena_com_write_header(io_sq, push_header, header_len);
++ if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV &&
++ !buffer_to_push))
++ return -EINVAL;
++
++ rc = ena_com_write_header_to_bounce(io_sq, buffer_to_push, header_len);
+ if (unlikely(rc))
+ return rc;
+
+ have_meta = ena_tx_ctx->meta_valid && ena_com_meta_desc_changed(io_sq,
+ ena_tx_ctx);
+- if (have_meta)
+- ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx);
++ if (have_meta) {
++ rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx);
++ if (unlikely(rc))
++ return rc;
++ }
+
+- /* If the caller doesn't want send packets */
++ /* If the caller doesn't want to send packets */
+ if (unlikely(!num_bufs && !header_len)) {
+- *nb_hw_desc = have_meta ? 0 : 1;
+- return 0;
++ rc = ena_com_close_bounce_buffer(io_sq);
++ *nb_hw_desc = io_sq->tail - start_tail;
++ return rc;
+ }
+
+ desc = get_sq_desc(io_sq);
++ if (unlikely(!desc))
++ return -EFAULT;
+ memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc));
+
+ /* Set first desc when we don't have meta descriptor */
+@@ -351,10 +474,14 @@ int ena_com_prepare_tx(struct ena_com_io
+ for (i = 0; i < num_bufs; i++) {
+ /* The first desc share the same desc as the header */
+ if (likely(i != 0)) {
+- ena_com_copy_curr_sq_desc_to_dev(io_sq);
+- ena_com_sq_update_tail(io_sq);
++ rc = ena_com_sq_update_tail(io_sq);
++ if (unlikely(rc))
++ return rc;
+
+ desc = get_sq_desc(io_sq);
++ if (unlikely(!desc))
++ return -EFAULT;
++
+ memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc));
+
+ desc->len_ctrl |= (io_sq->phase <<
+@@ -377,15 +504,14 @@ int ena_com_prepare_tx(struct ena_com_io
+ /* set the last desc indicator */
+ desc->len_ctrl |= ENA_ETH_IO_TX_DESC_LAST_MASK;
+
+- ena_com_copy_curr_sq_desc_to_dev(io_sq);
+-
+- ena_com_sq_update_tail(io_sq);
++ rc = ena_com_sq_update_tail(io_sq);
++ if (unlikely(rc))
++ return rc;
+
+- total_desc = max_t(u16, num_bufs, 1);
+- total_desc += have_meta ? 1 : 0;
++ rc = ena_com_close_bounce_buffer(io_sq);
+
+- *nb_hw_desc = total_desc;
+- return 0;
++ *nb_hw_desc = io_sq->tail - start_tail;
++ return rc;
+ }
+
+ int ena_com_rx_pkt(struct ena_com_io_cq *io_cq,
+@@ -444,15 +570,18 @@ int ena_com_add_single_rx_desc(struct en
+
+ WARN(io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type");
+
+- if (unlikely(ena_com_sq_empty_space(io_sq) == 0))
++ if (unlikely(!ena_com_sq_have_enough_space(io_sq, 1)))
+ return -ENOSPC;
+
+ desc = get_sq_desc(io_sq);
++ if (unlikely(!desc))
++ return -EFAULT;
++
+ memset(desc, 0x0, sizeof(struct ena_eth_io_rx_desc));
+
+ desc->length = ena_buf->len;
+
+- desc->ctrl |= ENA_ETH_IO_RX_DESC_FIRST_MASK;
++ desc->ctrl = ENA_ETH_IO_RX_DESC_FIRST_MASK;
+ desc->ctrl |= ENA_ETH_IO_RX_DESC_LAST_MASK;
+ desc->ctrl |= io_sq->phase & ENA_ETH_IO_RX_DESC_PHASE_MASK;
+ desc->ctrl |= ENA_ETH_IO_RX_DESC_COMP_REQ_MASK;
+@@ -463,9 +592,7 @@ int ena_com_add_single_rx_desc(struct en
+ desc->buff_addr_hi =
+ ((ena_buf->paddr & GENMASK_ULL(io_sq->dma_addr_bits - 1, 32)) >> 32);
+
+- ena_com_sq_update_tail(io_sq);
+-
+- return 0;
++ return ena_com_sq_update_tail(io_sq);
+ }
+
+ bool ena_com_cq_empty(struct ena_com_io_cq *io_cq)
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+@@ -94,7 +94,7 @@ static inline void ena_com_unmask_intr(s
+ writel(intr_reg->intr_control, io_cq->unmask_reg);
+ }
+
+-static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq)
++static inline int ena_com_free_desc(struct ena_com_io_sq *io_sq)
+ {
+ u16 tail, next_to_comp, cnt;
+
+@@ -105,11 +105,28 @@ static inline int ena_com_sq_empty_space
+ return io_sq->q_depth - 1 - cnt;
+ }
+
+-static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
++/* Check if the submission queue has enough space to hold required_buffers */
++static inline bool ena_com_sq_have_enough_space(struct ena_com_io_sq *io_sq,
++ u16 required_buffers)
+ {
+- u16 tail;
++ int temp;
+
+- tail = io_sq->tail;
++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
++ return ena_com_free_desc(io_sq) >= required_buffers;
++
++ /* This calculation doesn't need to be 100% accurate. So to reduce
++ * the calculation overhead just Subtract 2 lines from the free descs
++ * (one for the header line and one to compensate the devision
++ * down calculation.
++ */
++ temp = required_buffers / io_sq->llq_info.descs_per_entry + 2;
++
++ return ena_com_free_desc(io_sq) > temp;
++}
++
++static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
++{
++ u16 tail = io_sq->tail;
+
+ pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
+ io_sq->qid, tail);
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -804,12 +804,13 @@ static int ena_clean_tx_irq(struct ena_r
+ */
+ smp_mb();
+
+- above_thresh = ena_com_sq_empty_space(tx_ring->ena_com_io_sq) >
+- ENA_TX_WAKEUP_THRESH;
++ above_thresh = ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq,
++ ENA_TX_WAKEUP_THRESH);
+ if (unlikely(netif_tx_queue_stopped(txq) && above_thresh)) {
+ __netif_tx_lock(txq, smp_processor_id());
+- above_thresh = ena_com_sq_empty_space(tx_ring->ena_com_io_sq) >
+- ENA_TX_WAKEUP_THRESH;
++ above_thresh =
++ ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq,
++ ENA_TX_WAKEUP_THRESH);
+ if (netif_tx_queue_stopped(txq) && above_thresh) {
+ netif_tx_wake_queue(txq);
+ u64_stats_update_begin(&tx_ring->syncp);
+@@ -1101,7 +1102,7 @@ static int ena_clean_rx_irq(struct ena_r
+
+ rx_ring->next_to_clean = next_to_clean;
+
+- refill_required = ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
++ refill_required = ena_com_free_desc(rx_ring->ena_com_io_sq);
+ refill_threshold = rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER;
+
+ /* Optimization, try to batch new rx buffers */
+@@ -2115,8 +2116,8 @@ static netdev_tx_t ena_start_xmit(struct
+ * to sgl_size + 2. one for the meta descriptor and one for header
+ * (if the header is larger than tx_max_header_size).
+ */
+- if (unlikely(ena_com_sq_empty_space(tx_ring->ena_com_io_sq) <
+- (tx_ring->sgl_size + 2))) {
++ if (unlikely(!ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq,
++ tx_ring->sgl_size + 2))) {
+ netif_dbg(adapter, tx_queued, dev, "%s stop queue %d\n",
+ __func__, qid);
+
+@@ -2135,8 +2136,8 @@ static netdev_tx_t ena_start_xmit(struct
+ */
+ smp_mb();
+
+- if (ena_com_sq_empty_space(tx_ring->ena_com_io_sq)
+- > ENA_TX_WAKEUP_THRESH) {
++ if (ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq,
++ ENA_TX_WAKEUP_THRESH)) {
+ netif_tx_wake_queue(txq);
+ u64_stats_update_begin(&tx_ring->syncp);
+ tx_ring->tx_stats.queue_wakeup++;
+@@ -2813,7 +2814,7 @@ static void check_for_empty_rx_ring(stru
+ rx_ring = &adapter->rx_ring[i];
+
+ refill_required =
+- ena_com_sq_empty_space(rx_ring->ena_com_io_sq);
++ ena_com_free_desc(rx_ring->ena_com_io_sq);
+ if (unlikely(refill_required == (rx_ring->ring_size - 1))) {
+ rx_ring->empty_rx_queue++;
+
diff --git a/debian/patches/features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch b/debian/patches/features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch
new file mode 100644
index 000000000..8f288529e
--- /dev/null
+++ b/debian/patches/features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch
@@ -0,0 +1,655 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:20 +0300
+Subject: [PATCH 06/19] net: ena: add functions for handling Low Latency Queues
+ in ena_netdev
+Origin: https://git.kernel.org/linus/38005ca816a7ef5516dc8e59ae95716739aa75b0
+
+This patch includes all code changes necessary in ena_netdev to enable
+packet sending via the LLQ placemnt mode.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 1 +
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 387 +++++++++++-------
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 +
+ 3 files changed, 251 insertions(+), 143 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -81,6 +81,7 @@ static const struct ena_stats ena_stats_
+ ENA_STAT_TX_ENTRY(doorbells),
+ ENA_STAT_TX_ENTRY(prepare_ctx_err),
+ ENA_STAT_TX_ENTRY(bad_req_id),
++ ENA_STAT_TX_ENTRY(llq_buffer_copy),
+ ENA_STAT_TX_ENTRY(missed_tx),
+ };
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -237,6 +237,17 @@ static int ena_setup_tx_resources(struct
+ }
+ }
+
++ size = tx_ring->tx_max_header_size;
++ tx_ring->push_buf_intermediate_buf = vzalloc_node(size, node);
++ if (!tx_ring->push_buf_intermediate_buf) {
++ tx_ring->push_buf_intermediate_buf = vzalloc(size);
++ if (!tx_ring->push_buf_intermediate_buf) {
++ vfree(tx_ring->tx_buffer_info);
++ vfree(tx_ring->free_tx_ids);
++ return -ENOMEM;
++ }
++ }
++
+ /* Req id ring for TX out of order completions */
+ for (i = 0; i < tx_ring->ring_size; i++)
+ tx_ring->free_tx_ids[i] = i;
+@@ -265,6 +276,9 @@ static void ena_free_tx_resources(struct
+
+ vfree(tx_ring->free_tx_ids);
+ tx_ring->free_tx_ids = NULL;
++
++ vfree(tx_ring->push_buf_intermediate_buf);
++ tx_ring->push_buf_intermediate_buf = NULL;
+ }
+
+ /* ena_setup_all_tx_resources - allocate I/O Tx queues resources for All queues
+@@ -602,6 +616,36 @@ static void ena_free_all_rx_bufs(struct
+ ena_free_rx_bufs(adapter, i);
+ }
+
++static inline void ena_unmap_tx_skb(struct ena_ring *tx_ring,
++ struct ena_tx_buffer *tx_info)
++{
++ struct ena_com_buf *ena_buf;
++ u32 cnt;
++ int i;
++
++ ena_buf = tx_info->bufs;
++ cnt = tx_info->num_of_bufs;
++
++ if (unlikely(!cnt))
++ return;
++
++ if (tx_info->map_linear_data) {
++ dma_unmap_single(tx_ring->dev,
++ dma_unmap_addr(ena_buf, paddr),
++ dma_unmap_len(ena_buf, len),
++ DMA_TO_DEVICE);
++ ena_buf++;
++ cnt--;
++ }
++
++ /* unmap remaining mapped pages */
++ for (i = 0; i < cnt; i++) {
++ dma_unmap_page(tx_ring->dev, dma_unmap_addr(ena_buf, paddr),
++ dma_unmap_len(ena_buf, len), DMA_TO_DEVICE);
++ ena_buf++;
++ }
++}
++
+ /* ena_free_tx_bufs - Free Tx Buffers per Queue
+ * @tx_ring: TX ring for which buffers be freed
+ */
+@@ -612,9 +656,6 @@ static void ena_free_tx_bufs(struct ena_
+
+ for (i = 0; i < tx_ring->ring_size; i++) {
+ struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i];
+- struct ena_com_buf *ena_buf;
+- int nr_frags;
+- int j;
+
+ if (!tx_info->skb)
+ continue;
+@@ -630,21 +671,7 @@ static void ena_free_tx_bufs(struct ena_
+ tx_ring->qid, i);
+ }
+
+- ena_buf = tx_info->bufs;
+- dma_unmap_single(tx_ring->dev,
+- ena_buf->paddr,
+- ena_buf->len,
+- DMA_TO_DEVICE);
+-
+- /* unmap remaining mapped pages */
+- nr_frags = tx_info->num_of_bufs - 1;
+- for (j = 0; j < nr_frags; j++) {
+- ena_buf++;
+- dma_unmap_page(tx_ring->dev,
+- ena_buf->paddr,
+- ena_buf->len,
+- DMA_TO_DEVICE);
+- }
++ ena_unmap_tx_skb(tx_ring, tx_info);
+
+ dev_kfree_skb_any(tx_info->skb);
+ }
+@@ -735,8 +762,6 @@ static int ena_clean_tx_irq(struct ena_r
+ while (tx_pkts < budget) {
+ struct ena_tx_buffer *tx_info;
+ struct sk_buff *skb;
+- struct ena_com_buf *ena_buf;
+- int i, nr_frags;
+
+ rc = ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq,
+ &req_id);
+@@ -756,24 +781,7 @@ static int ena_clean_tx_irq(struct ena_r
+ tx_info->skb = NULL;
+ tx_info->last_jiffies = 0;
+
+- if (likely(tx_info->num_of_bufs != 0)) {
+- ena_buf = tx_info->bufs;
+-
+- dma_unmap_single(tx_ring->dev,
+- dma_unmap_addr(ena_buf, paddr),
+- dma_unmap_len(ena_buf, len),
+- DMA_TO_DEVICE);
+-
+- /* unmap remaining mapped pages */
+- nr_frags = tx_info->num_of_bufs - 1;
+- for (i = 0; i < nr_frags; i++) {
+- ena_buf++;
+- dma_unmap_page(tx_ring->dev,
+- dma_unmap_addr(ena_buf, paddr),
+- dma_unmap_len(ena_buf, len),
+- DMA_TO_DEVICE);
+- }
+- }
++ ena_unmap_tx_skb(tx_ring, tx_info);
+
+ netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev,
+ "tx_poll: q %d skb %p completed\n", tx_ring->qid,
+@@ -1300,7 +1308,6 @@ static int ena_enable_msix(struct ena_ad
+
+ /* Reserved the max msix vectors we might need */
+ msix_vecs = ENA_MAX_MSIX_VEC(num_queues);
+-
+ netif_dbg(adapter, probe, adapter->netdev,
+ "trying to enable MSI-X, vectors %d\n", msix_vecs);
+
+@@ -1591,7 +1598,7 @@ static int ena_up_complete(struct ena_ad
+
+ static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid)
+ {
+- struct ena_com_create_io_ctx ctx = { 0 };
++ struct ena_com_create_io_ctx ctx;
+ struct ena_com_dev *ena_dev;
+ struct ena_ring *tx_ring;
+ u32 msix_vector;
+@@ -1604,6 +1611,8 @@ static int ena_create_io_tx_queue(struct
+ msix_vector = ENA_IO_IRQ_IDX(qid);
+ ena_qid = ENA_IO_TXQ_IDX(qid);
+
++ memset(&ctx, 0x0, sizeof(ctx));
++
+ ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX;
+ ctx.qid = ena_qid;
+ ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
+@@ -1657,7 +1666,7 @@ create_err:
+ static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid)
+ {
+ struct ena_com_dev *ena_dev;
+- struct ena_com_create_io_ctx ctx = { 0 };
++ struct ena_com_create_io_ctx ctx;
+ struct ena_ring *rx_ring;
+ u32 msix_vector;
+ u16 ena_qid;
+@@ -1669,6 +1678,8 @@ static int ena_create_io_rx_queue(struct
+ msix_vector = ENA_IO_IRQ_IDX(qid);
+ ena_qid = ENA_IO_RXQ_IDX(qid);
+
++ memset(&ctx, 0x0, sizeof(ctx));
++
+ ctx.qid = ena_qid;
+ ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX;
+ ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+@@ -1986,73 +1997,70 @@ static int ena_check_and_linearize_skb(s
+ return rc;
+ }
+
+-/* Called with netif_tx_lock. */
+-static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
++static int ena_tx_map_skb(struct ena_ring *tx_ring,
++ struct ena_tx_buffer *tx_info,
++ struct sk_buff *skb,
++ void **push_hdr,
++ u16 *header_len)
+ {
+- struct ena_adapter *adapter = netdev_priv(dev);
+- struct ena_tx_buffer *tx_info;
+- struct ena_com_tx_ctx ena_tx_ctx;
+- struct ena_ring *tx_ring;
+- struct netdev_queue *txq;
++ struct ena_adapter *adapter = tx_ring->adapter;
+ struct ena_com_buf *ena_buf;
+- void *push_hdr;
+- u32 len, last_frag;
+- u16 next_to_use;
+- u16 req_id;
+- u16 push_len;
+- u16 header_len;
+ dma_addr_t dma;
+- int qid, rc, nb_hw_desc;
+- int i = -1;
+-
+- netif_dbg(adapter, tx_queued, dev, "%s skb %p\n", __func__, skb);
+- /* Determine which tx ring we will be placed on */
+- qid = skb_get_queue_mapping(skb);
+- tx_ring = &adapter->tx_ring[qid];
+- txq = netdev_get_tx_queue(dev, qid);
+-
+- rc = ena_check_and_linearize_skb(tx_ring, skb);
+- if (unlikely(rc))
+- goto error_drop_packet;
+-
+- skb_tx_timestamp(skb);
+- len = skb_headlen(skb);
++ u32 skb_head_len, frag_len, last_frag;
++ u16 push_len = 0;
++ u16 delta = 0;
++ int i = 0;
+
+- next_to_use = tx_ring->next_to_use;
+- req_id = tx_ring->free_tx_ids[next_to_use];
+- tx_info = &tx_ring->tx_buffer_info[req_id];
+- tx_info->num_of_bufs = 0;
+-
+- WARN(tx_info->skb, "SKB isn't NULL req_id %d\n", req_id);
+- ena_buf = tx_info->bufs;
++ skb_head_len = skb_headlen(skb);
+ tx_info->skb = skb;
++ ena_buf = tx_info->bufs;
+
+ if (tx_ring->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+- /* prepared the push buffer */
+- push_len = min_t(u32, len, tx_ring->tx_max_header_size);
+- header_len = push_len;
+- push_hdr = skb->data;
++ /* When the device is LLQ mode, the driver will copy
++ * the header into the device memory space.
++ * the ena_com layer assume the header is in a linear
++ * memory space.
++ * This assumption might be wrong since part of the header
++ * can be in the fragmented buffers.
++ * Use skb_header_pointer to make sure the header is in a
++ * linear memory space.
++ */
++
++ push_len = min_t(u32, skb->len, tx_ring->tx_max_header_size);
++ *push_hdr = skb_header_pointer(skb, 0, push_len,
++ tx_ring->push_buf_intermediate_buf);
++ *header_len = push_len;
++ if (unlikely(skb->data != *push_hdr)) {
++ u64_stats_update_begin(&tx_ring->syncp);
++ tx_ring->tx_stats.llq_buffer_copy++;
++ u64_stats_update_end(&tx_ring->syncp);
++
++ delta = push_len - skb_head_len;
++ }
+ } else {
+- push_len = 0;
+- header_len = min_t(u32, len, tx_ring->tx_max_header_size);
+- push_hdr = NULL;
++ *push_hdr = NULL;
++ *header_len = min_t(u32, skb_head_len,
++ tx_ring->tx_max_header_size);
+ }
+
+- netif_dbg(adapter, tx_queued, dev,
++ netif_dbg(adapter, tx_queued, adapter->netdev,
+ "skb: %p header_buf->vaddr: %p push_len: %d\n", skb,
+- push_hdr, push_len);
++ *push_hdr, push_len);
+
+- if (len > push_len) {
++ if (skb_head_len > push_len) {
+ dma = dma_map_single(tx_ring->dev, skb->data + push_len,
+- len - push_len, DMA_TO_DEVICE);
+- if (dma_mapping_error(tx_ring->dev, dma))
++ skb_head_len - push_len, DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(tx_ring->dev, dma)))
+ goto error_report_dma_error;
+
+ ena_buf->paddr = dma;
+- ena_buf->len = len - push_len;
++ ena_buf->len = skb_head_len - push_len;
+
+ ena_buf++;
+ tx_info->num_of_bufs++;
++ tx_info->map_linear_data = 1;
++ } else {
++ tx_info->map_linear_data = 0;
+ }
+
+ last_frag = skb_shinfo(skb)->nr_frags;
+@@ -2060,18 +2068,75 @@ static netdev_tx_t ena_start_xmit(struct
+ for (i = 0; i < last_frag; i++) {
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+- len = skb_frag_size(frag);
+- dma = skb_frag_dma_map(tx_ring->dev, frag, 0, len,
+- DMA_TO_DEVICE);
+- if (dma_mapping_error(tx_ring->dev, dma))
++ frag_len = skb_frag_size(frag);
++
++ if (unlikely(delta >= frag_len)) {
++ delta -= frag_len;
++ continue;
++ }
++
++ dma = skb_frag_dma_map(tx_ring->dev, frag, delta,
++ frag_len - delta, DMA_TO_DEVICE);
++ if (unlikely(dma_mapping_error(tx_ring->dev, dma)))
+ goto error_report_dma_error;
+
+ ena_buf->paddr = dma;
+- ena_buf->len = len;
++ ena_buf->len = frag_len - delta;
+ ena_buf++;
++ tx_info->num_of_bufs++;
++ delta = 0;
+ }
+
+- tx_info->num_of_bufs += last_frag;
++ return 0;
++
++error_report_dma_error:
++ u64_stats_update_begin(&tx_ring->syncp);
++ tx_ring->tx_stats.dma_mapping_err++;
++ u64_stats_update_end(&tx_ring->syncp);
++ netdev_warn(adapter->netdev, "failed to map skb\n");
++
++ tx_info->skb = NULL;
++
++ tx_info->num_of_bufs += i;
++ ena_unmap_tx_skb(tx_ring, tx_info);
++
++ return -EINVAL;
++}
++
++/* Called with netif_tx_lock. */
++static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
++{
++ struct ena_adapter *adapter = netdev_priv(dev);
++ struct ena_tx_buffer *tx_info;
++ struct ena_com_tx_ctx ena_tx_ctx;
++ struct ena_ring *tx_ring;
++ struct netdev_queue *txq;
++ void *push_hdr;
++ u16 next_to_use, req_id, header_len;
++ int qid, rc, nb_hw_desc;
++
++ netif_dbg(adapter, tx_queued, dev, "%s skb %p\n", __func__, skb);
++ /* Determine which tx ring we will be placed on */
++ qid = skb_get_queue_mapping(skb);
++ tx_ring = &adapter->tx_ring[qid];
++ txq = netdev_get_tx_queue(dev, qid);
++
++ rc = ena_check_and_linearize_skb(tx_ring, skb);
++ if (unlikely(rc))
++ goto error_drop_packet;
++
++ skb_tx_timestamp(skb);
++
++ next_to_use = tx_ring->next_to_use;
++ req_id = tx_ring->free_tx_ids[next_to_use];
++ tx_info = &tx_ring->tx_buffer_info[req_id];
++ tx_info->num_of_bufs = 0;
++
++ WARN(tx_info->skb, "SKB isn't NULL req_id %d\n", req_id);
++
++ rc = ena_tx_map_skb(tx_ring, tx_info, skb, &push_hdr, &header_len);
++ if (unlikely(rc))
++ goto error_drop_packet;
+
+ memset(&ena_tx_ctx, 0x0, sizeof(struct ena_com_tx_ctx));
+ ena_tx_ctx.ena_bufs = tx_info->bufs;
+@@ -2087,14 +2152,22 @@ static netdev_tx_t ena_start_xmit(struct
+ rc = ena_com_prepare_tx(tx_ring->ena_com_io_sq, &ena_tx_ctx,
+ &nb_hw_desc);
+
++ /* ena_com_prepare_tx() can't fail due to overflow of tx queue,
++ * since the number of free descriptors in the queue is checked
++ * after sending the previous packet. In case there isn't enough
++ * space in the queue for the next packet, it is stopped
++ * until there is again enough available space in the queue.
++ * All other failure reasons of ena_com_prepare_tx() are fatal
++ * and therefore require a device reset.
++ */
+ if (unlikely(rc)) {
+ netif_err(adapter, tx_queued, dev,
+ "failed to prepare tx bufs\n");
+ u64_stats_update_begin(&tx_ring->syncp);
+- tx_ring->tx_stats.queue_stop++;
+ tx_ring->tx_stats.prepare_ctx_err++;
+ u64_stats_update_end(&tx_ring->syncp);
+- netif_tx_stop_queue(txq);
++ adapter->reset_reason = ENA_REGS_RESET_DRIVER_INVALID_STATE;
++ set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+ goto error_unmap_dma;
+ }
+
+@@ -2157,35 +2230,11 @@ static netdev_tx_t ena_start_xmit(struct
+
+ return NETDEV_TX_OK;
+
+-error_report_dma_error:
+- u64_stats_update_begin(&tx_ring->syncp);
+- tx_ring->tx_stats.dma_mapping_err++;
+- u64_stats_update_end(&tx_ring->syncp);
+- netdev_warn(adapter->netdev, "failed to map skb\n");
+-
+- tx_info->skb = NULL;
+-
+ error_unmap_dma:
+- if (i >= 0) {
+- /* save value of frag that failed */
+- last_frag = i;
+-
+- /* start back at beginning and unmap skb */
+- tx_info->skb = NULL;
+- ena_buf = tx_info->bufs;
+- dma_unmap_single(tx_ring->dev, dma_unmap_addr(ena_buf, paddr),
+- dma_unmap_len(ena_buf, len), DMA_TO_DEVICE);
+-
+- /* unmap remaining mapped pages */
+- for (i = 0; i < last_frag; i++) {
+- ena_buf++;
+- dma_unmap_page(tx_ring->dev, dma_unmap_addr(ena_buf, paddr),
+- dma_unmap_len(ena_buf, len), DMA_TO_DEVICE);
+- }
+- }
++ ena_unmap_tx_skb(tx_ring, tx_info);
++ tx_info->skb = NULL;
+
+ error_drop_packet:
+-
+ dev_kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+@@ -2621,7 +2670,9 @@ static int ena_restore_device(struct ena
+ netif_carrier_on(adapter->netdev);
+
+ mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
+- dev_err(&pdev->dev, "Device reset completed successfully\n");
++ dev_err(&pdev->dev,
++ "Device reset completed successfully, Driver info: %s\n",
++ version);
+
+ return rc;
+ err_disable_msix:
+@@ -2988,18 +3039,52 @@ static int ena_calc_io_queue_num(struct
+ return io_queue_num;
+ }
+
+-static void ena_set_push_mode(struct pci_dev *pdev, struct ena_com_dev *ena_dev,
+- struct ena_com_dev_get_features_ctx *get_feat_ctx)
++static int ena_set_queues_placement_policy(struct pci_dev *pdev,
++ struct ena_com_dev *ena_dev,
++ struct ena_admin_feature_llq_desc *llq,
++ struct ena_llq_configurations *llq_default_configurations)
+ {
+ bool has_mem_bar;
++ int rc;
++ u32 llq_feature_mask;
++
++ llq_feature_mask = 1 << ENA_ADMIN_LLQ;
++ if (!(ena_dev->supported_features & llq_feature_mask)) {
++ dev_err(&pdev->dev,
++ "LLQ is not supported Fallback to host mode policy.\n");
++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
++ return 0;
++ }
+
+ has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR);
+
+- /* Enable push mode if device supports LLQ */
+- if (has_mem_bar && get_feat_ctx->max_queues.max_legacy_llq_num > 0)
+- ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV;
+- else
++ rc = ena_com_config_dev_mode(ena_dev, llq, llq_default_configurations);
++ if (unlikely(rc)) {
++ dev_err(&pdev->dev,
++ "Failed to configure the device mode. Fallback to host mode policy.\n");
++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
++ return 0;
++ }
++
++ /* Nothing to config, exit */
++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
++ return 0;
++
++ if (!has_mem_bar) {
++ dev_err(&pdev->dev,
++ "ENA device does not expose LLQ bar. Fallback to host mode policy.\n");
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
++ return 0;
++ }
++
++ ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
++ pci_resource_start(pdev, ENA_MEM_BAR),
++ pci_resource_len(pdev, ENA_MEM_BAR));
++
++ if (!ena_dev->mem_bar)
++ return -EFAULT;
++
++ return 0;
+ }
+
+ static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat,
+@@ -3117,6 +3202,15 @@ static void ena_release_bars(struct ena_
+ pci_release_selected_regions(pdev, release_bars);
+ }
+
++static inline void set_default_llq_configurations(struct ena_llq_configurations *llq_config)
++{
++ llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER;
++ llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B;
++ llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY;
++ llq_config->llq_num_decs_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2;
++ llq_config->llq_ring_entry_size_value = 128;
++}
++
+ static int ena_calc_queue_size(struct pci_dev *pdev,
+ struct ena_com_dev *ena_dev,
+ u16 *max_tx_sgl_size,
+@@ -3165,7 +3259,9 @@ static int ena_probe(struct pci_dev *pde
+ static int version_printed;
+ struct net_device *netdev;
+ struct ena_adapter *adapter;
++ struct ena_llq_configurations llq_config;
+ struct ena_com_dev *ena_dev = NULL;
++ char *queue_type_str;
+ static int adapters_found;
+ int io_queue_num, bars, rc;
+ int queue_size;
+@@ -3219,16 +3315,13 @@ static int ena_probe(struct pci_dev *pde
+ goto err_free_region;
+ }
+
+- ena_set_push_mode(pdev, ena_dev, &get_feat_ctx);
++ set_default_llq_configurations(&llq_config);
+
+- if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+- ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev,
+- pci_resource_start(pdev, ENA_MEM_BAR),
+- pci_resource_len(pdev, ENA_MEM_BAR));
+- if (!ena_dev->mem_bar) {
+- rc = -EFAULT;
+- goto err_device_destroy;
+- }
++ rc = ena_set_queues_placement_policy(pdev, ena_dev, &get_feat_ctx.llq,
++ &llq_config);
++ if (rc) {
++ dev_err(&pdev->dev, "ena device init failed\n");
++ goto err_device_destroy;
+ }
+
+ /* initial Tx interrupt delay, Assumes 1 usec granularity.
+@@ -3243,8 +3336,10 @@ static int ena_probe(struct pci_dev *pde
+ goto err_device_destroy;
+ }
+
+- dev_info(&pdev->dev, "creating %d io queues. queue size: %d\n",
+- io_queue_num, queue_size);
++ dev_info(&pdev->dev, "creating %d io queues. queue size: %d. LLQ is %s\n",
++ io_queue_num, queue_size,
++ (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ?
++ "ENABLED" : "DISABLED");
+
+ /* dev zeroed in init_etherdev */
+ netdev = alloc_etherdev_mq(sizeof(struct ena_adapter), io_queue_num);
+@@ -3334,9 +3429,15 @@ static int ena_probe(struct pci_dev *pde
+ timer_setup(&adapter->timer_service, ena_timer_service, 0);
+ mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
+
+- dev_info(&pdev->dev, "%s found at mem %lx, mac addr %pM Queues %d\n",
++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)
++ queue_type_str = "Regular";
++ else
++ queue_type_str = "Low Latency";
++
++ dev_info(&pdev->dev,
++ "%s found at mem %lx, mac addr %pM Queues %d, Placement policy: %s\n",
+ DEVICE_NAME, (long)pci_resource_start(pdev, 0),
+- netdev->dev_addr, io_queue_num);
++ netdev->dev_addr, io_queue_num, queue_type_str);
+
+ set_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -151,6 +151,9 @@ struct ena_tx_buffer {
+ /* num of buffers used by this skb */
+ u32 num_of_bufs;
+
++ /* Indicate if bufs[0] map the linear data of the skb. */
++ u8 map_linear_data;
++
+ /* Used for detect missing tx packets to limit the number of prints */
+ u32 print_once;
+ /* Save the last jiffies to detect missing tx packets
+@@ -186,6 +189,7 @@ struct ena_stats_tx {
+ u64 tx_poll;
+ u64 doorbells;
+ u64 bad_req_id;
++ u64 llq_buffer_copy;
+ u64 missed_tx;
+ };
+
+@@ -257,6 +261,8 @@ struct ena_ring {
+ struct ena_stats_tx tx_stats;
+ struct ena_stats_rx rx_stats;
+ };
++
++ u8 *push_buf_intermediate_buf;
+ int empty_rx_queue;
+ } ____cacheline_aligned;
+
diff --git a/debian/patches/features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch b/debian/patches/features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch
new file mode 100644
index 000000000..cc25333b8
--- /dev/null
+++ b/debian/patches/features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch
@@ -0,0 +1,125 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:21 +0300
+Subject: [PATCH 07/19] net: ena: use CSUM_CHECKED device indication to report
+ skb's checksum status
+Origin: https://git.kernel.org/linus/cb36bb36e1f17d2a7b9a9751e5cfec4235b46c93
+
+Set skb->ip_summed to the correct value as reported by the device.
+Add counter for the case where rx csum offload is enabled but
+device didn't check it.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_eth_com.c | 7 +++++--
+ drivers/net/ethernet/amazon/ena/ena_eth_com.h | 1 +
+ drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h | 10 ++++++++--
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 1 +
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 ++++++++++++-
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 1 +
+ 6 files changed, 28 insertions(+), 5 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+@@ -354,6 +354,9 @@ static inline void ena_com_rx_set_flags(
+ ena_rx_ctx->l4_csum_err =
+ !!((cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK) >>
+ ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT);
++ ena_rx_ctx->l4_csum_checked =
++ !!((cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK) >>
++ ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT);
+ ena_rx_ctx->hash = cdesc->hash;
+ ena_rx_ctx->frag =
+ (cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK) >>
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+@@ -67,6 +67,7 @@ struct ena_com_rx_ctx {
+ enum ena_eth_io_l4_proto_index l4_proto;
+ bool l3_csum_err;
+ bool l4_csum_err;
++ u8 l4_csum_checked;
+ /* fragmented packet */
+ bool frag;
+ u32 hash;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
+@@ -242,9 +242,13 @@ struct ena_eth_io_rx_cdesc_base {
+ * checksum error detected, or, the controller didn't
+ * validate the checksum. This bit is valid only when
+ * l4_proto_idx indicates TCP/UDP packet, and,
+- * ipv4_frag is not set
++ * ipv4_frag is not set. This bit is valid only when
++ * l4_csum_checked below is set.
+ * 15 : ipv4_frag - Indicates IPv4 fragmented packet
+- * 23:16 : reserved16
++ * 16 : l4_csum_checked - L4 checksum was verified
++ * (could be OK or error), when cleared the status of
++ * checksum is unknown
++ * 23:17 : reserved17 - MBZ
+ * 24 : phase
+ * 25 : l3_csum2 - second checksum engine result
+ * 26 : first - Indicates first descriptor in
+@@ -390,6 +394,8 @@ struct ena_eth_io_numa_node_cfg_reg {
+ #define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14)
+ #define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15
+ #define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15)
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT 16
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK BIT(16)
+ #define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24
+ #define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24)
+ #define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -97,6 +97,7 @@ static const struct ena_stats ena_stats_
+ ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+ ENA_STAT_RX_ENTRY(bad_req_id),
+ ENA_STAT_RX_ENTRY(empty_rx_ring),
++ ENA_STAT_RX_ENTRY(csum_unchecked),
+ };
+
+ static const struct ena_stats ena_stats_ena_com_strings[] = {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -994,8 +994,19 @@ static inline void ena_rx_checksum(struc
+ return;
+ }
+
+- skb->ip_summed = CHECKSUM_UNNECESSARY;
++ if (likely(ena_rx_ctx->l4_csum_checked)) {
++ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ } else {
++ u64_stats_update_begin(&rx_ring->syncp);
++ rx_ring->rx_stats.csum_unchecked++;
++ u64_stats_update_end(&rx_ring->syncp);
++ skb->ip_summed = CHECKSUM_NONE;
++ }
++ } else {
++ skb->ip_summed = CHECKSUM_NONE;
++ return;
+ }
++
+ }
+
+ static void ena_set_rx_hash(struct ena_ring *rx_ring,
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -205,6 +205,7 @@ struct ena_stats_rx {
+ u64 rx_copybreak_pkt;
+ u64 bad_req_id;
+ u64 empty_rx_ring;
++ u64 csum_unchecked;
+ };
+
+ struct ena_ring {
diff --git a/debian/patches/features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch b/debian/patches/features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch
new file mode 100644
index 000000000..59ea0566a
--- /dev/null
+++ b/debian/patches/features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch
@@ -0,0 +1,223 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:22 +0300
+Subject: [PATCH 08/19] net: ena: explicit casting and initialization, and
+ clearer error handling
+Origin: https://git.kernel.org/linus/bd791175a6432d24fc5d7b348304276027372545
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 39 ++++++++++++--------
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 5 +--
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 22 +++++------
+ 3 files changed, 36 insertions(+), 30 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -235,7 +235,7 @@ static struct ena_comp_ctx *__ena_com_su
+ tail_masked = admin_queue->sq.tail & queue_size_mask;
+
+ /* In case of queue FULL */
+- cnt = atomic_read(&admin_queue->outstanding_cmds);
++ cnt = (u16)atomic_read(&admin_queue->outstanding_cmds);
+ if (cnt >= admin_queue->q_depth) {
+ pr_debug("admin queue is full.\n");
+ admin_queue->stats.out_of_space++;
+@@ -304,7 +304,7 @@ static struct ena_comp_ctx *ena_com_subm
+ struct ena_admin_acq_entry *comp,
+ size_t comp_size_in_bytes)
+ {
+- unsigned long flags;
++ unsigned long flags = 0;
+ struct ena_comp_ctx *comp_ctx;
+
+ spin_lock_irqsave(&admin_queue->q_lock, flags);
+@@ -332,7 +332,7 @@ static int ena_com_init_io_sq(struct ena
+
+ memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr));
+
+- io_sq->dma_addr_bits = ena_dev->dma_addr_bits;
++ io_sq->dma_addr_bits = (u8)ena_dev->dma_addr_bits;
+ io_sq->desc_entry_size =
+ (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ?
+ sizeof(struct ena_eth_io_tx_desc) :
+@@ -486,7 +486,7 @@ static void ena_com_handle_admin_complet
+
+ /* Go over all the completions */
+ while ((READ_ONCE(cqe->acq_common_descriptor.flags) &
+- ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) {
++ ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) {
+ /* Do not read the rest of the completion entry before the
+ * phase bit was validated
+ */
+@@ -537,7 +537,8 @@ static int ena_com_comp_status_to_errno(
+ static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx,
+ struct ena_com_admin_queue *admin_queue)
+ {
+- unsigned long flags, timeout;
++ unsigned long flags = 0;
++ unsigned long timeout;
+ int ret;
+
+ timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout);
+@@ -736,7 +737,7 @@ static int ena_com_config_llq_info(struc
+ static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx,
+ struct ena_com_admin_queue *admin_queue)
+ {
+- unsigned long flags;
++ unsigned long flags = 0;
+ int ret;
+
+ wait_for_completion_timeout(&comp_ctx->wait_event,
+@@ -782,7 +783,7 @@ static u32 ena_com_reg_bar_read32(struct
+ volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp =
+ mmio_read->read_resp;
+ u32 mmio_read_reg, ret, i;
+- unsigned long flags;
++ unsigned long flags = 0;
+ u32 timeout = mmio_read->reg_read_to;
+
+ might_sleep();
+@@ -1426,7 +1427,7 @@ void ena_com_abort_admin_commands(struct
+ void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev)
+ {
+ struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+- unsigned long flags;
++ unsigned long flags = 0;
+
+ spin_lock_irqsave(&admin_queue->q_lock, flags);
+ while (atomic_read(&admin_queue->outstanding_cmds) != 0) {
+@@ -1470,7 +1471,7 @@ bool ena_com_get_admin_running_state(str
+ void ena_com_set_admin_running_state(struct ena_com_dev *ena_dev, bool state)
+ {
+ struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+- unsigned long flags;
++ unsigned long flags = 0;
+
+ spin_lock_irqsave(&admin_queue->q_lock, flags);
+ ena_dev->admin_queue.running_state = state;
+@@ -1504,7 +1505,7 @@ int ena_com_set_aenq_config(struct ena_c
+ }
+
+ if ((get_resp.u.aenq.supported_groups & groups_flag) != groups_flag) {
+- pr_warn("Trying to set unsupported aenq events. supported flag: %x asked flag: %x\n",
++ pr_warn("Trying to set unsupported aenq events. supported flag: 0x%x asked flag: 0x%x\n",
+ get_resp.u.aenq.supported_groups, groups_flag);
+ return -EOPNOTSUPP;
+ }
+@@ -1652,7 +1653,7 @@ int ena_com_mmio_reg_read_request_init(s
+ sizeof(*mmio_read->read_resp),
+ &mmio_read->read_resp_dma_addr, GFP_KERNEL);
+ if (unlikely(!mmio_read->read_resp))
+- return -ENOMEM;
++ goto err;
+
+ ena_com_mmio_reg_read_request_write_dev_addr(ena_dev);
+
+@@ -1661,6 +1662,10 @@ int ena_com_mmio_reg_read_request_init(s
+ mmio_read->readless_supported = true;
+
+ return 0;
++
++err:
++
++ return -ENOMEM;
+ }
+
+ void ena_com_set_mmio_read_mode(struct ena_com_dev *ena_dev, bool readless_supported)
+@@ -1961,6 +1966,7 @@ void ena_com_aenq_intr_handler(struct en
+ struct ena_admin_aenq_entry *aenq_e;
+ struct ena_admin_aenq_common_desc *aenq_common;
+ struct ena_com_aenq *aenq = &dev->aenq;
++ unsigned long long timestamp;
+ ena_aenq_handler handler_cb;
+ u16 masked_head, processed = 0;
+ u8 phase;
+@@ -1978,10 +1984,11 @@ void ena_com_aenq_intr_handler(struct en
+ */
+ dma_rmb();
+
++ timestamp =
++ (unsigned long long)aenq_common->timestamp_low |
++ ((unsigned long long)aenq_common->timestamp_high << 32);
+ pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n",
+- aenq_common->group, aenq_common->syndrom,
+- (u64)aenq_common->timestamp_low +
+- ((u64)aenq_common->timestamp_high << 32));
++ aenq_common->group, aenq_common->syndrom, timestamp);
+
+ /* Handle specific event*/
+ handler_cb = ena_com_get_specific_aenq_cb(dev,
+@@ -2623,8 +2630,8 @@ int ena_com_allocate_host_info(struct en
+ if (unlikely(!host_attr->host_info))
+ return -ENOMEM;
+
+- host_attr->host_info->ena_spec_version =
+- ((ENA_COMMON_SPEC_VERSION_MAJOR << ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) |
++ host_attr->host_info->ena_spec_version = ((ENA_COMMON_SPEC_VERSION_MAJOR <<
++ ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) |
+ (ENA_COMMON_SPEC_VERSION_MINOR));
+
+ return 0;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2604,15 +2604,14 @@ static void ena_destroy_device(struct en
+
+ dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
+ adapter->dev_up_before_reset = dev_up;
+-
+ if (!graceful)
+ ena_com_set_admin_running_state(ena_dev, false);
+
+ if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+ ena_down(adapter);
+
+- /* Before releasing the ENA resources, a device reset is required.
+- * (to prevent the device from accessing them).
++ /* Stop the device from sending AENQ events (in case reset flag is set
++ * and device is up, ena_close already reset the device
+ * In case the reset flag is set and the device is up, ena_down()
+ * already perform the reset, so it can be skipped.
+ */
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -61,6 +61,17 @@
+ #define ENA_ADMIN_MSIX_VEC 1
+ #define ENA_MAX_MSIX_VEC(io_queues) (ENA_ADMIN_MSIX_VEC + (io_queues))
+
++/* The ENA buffer length fields is 16 bit long. So when PAGE_SIZE == 64kB the
++ * driver passes 0.
++ * Since the max packet size the ENA handles is ~9kB limit the buffer length to
++ * 16kB.
++ */
++#if PAGE_SIZE > SZ_16K
++#define ENA_PAGE_SIZE SZ_16K
++#else
++#define ENA_PAGE_SIZE PAGE_SIZE
++#endif
++
+ #define ENA_MIN_MSIX_VEC 2
+
+ #define ENA_REG_BAR 0
+@@ -362,15 +373,4 @@ void ena_dump_stats_to_buf(struct ena_ad
+
+ int ena_get_sset_count(struct net_device *netdev, int sset);
+
+-/* The ENA buffer length fields is 16 bit long. So when PAGE_SIZE == 64kB the
+- * driver passas 0.
+- * Since the max packet size the ENA handles is ~9kB limit the buffer length to
+- * 16kB.
+- */
+-#if PAGE_SIZE > SZ_16K
+-#define ENA_PAGE_SIZE SZ_16K
+-#else
+-#define ENA_PAGE_SIZE PAGE_SIZE
+-#endif
+-
+ #endif /* !(ENA_H) */
diff --git a/debian/patches/features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch b/debian/patches/features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch
new file mode 100644
index 000000000..3eaae9950
--- /dev/null
+++ b/debian/patches/features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch
@@ -0,0 +1,54 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:23 +0300
+Subject: [PATCH 09/19] net: ena: limit refill Rx threshold to 256 to avoid
+ latency issues
+Origin: https://git.kernel.org/linus/0574bb806dad29a3dada0ee42b01645477d48282
+
+Currently Rx refill is done when the number of required descriptors is
+above 1/8 queue size. With a default of 1024 entries per queue the
+threshold is 128 descriptors.
+There is intention to increase the queue size to 8196 entries.
+In this case threshold of 1024 descriptors is too large and can hurt
+latency.
+Add another limitation to Rx threshold to be at most 256 descriptors.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 +++-
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 5 +++--
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1122,7 +1122,9 @@ static int ena_clean_rx_irq(struct ena_r
+ rx_ring->next_to_clean = next_to_clean;
+
+ refill_required = ena_com_free_desc(rx_ring->ena_com_io_sq);
+- refill_threshold = rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER;
++ refill_threshold =
++ min_t(int, rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER,
++ ENA_RX_REFILL_THRESH_PACKET);
+
+ /* Optimization, try to batch new rx buffers */
+ if (refill_required > refill_threshold) {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -106,10 +106,11 @@
+ */
+ #define ENA_TX_POLL_BUDGET_DIVIDER 4
+
+-/* Refill Rx queue when number of available descriptors is below
+- * QUEUE_SIZE / ENA_RX_REFILL_THRESH_DIVIDER
++/* Refill Rx queue when number of required descriptors is above
++ * QUEUE_SIZE / ENA_RX_REFILL_THRESH_DIVIDER or ENA_RX_REFILL_THRESH_PACKET
+ */
+ #define ENA_RX_REFILL_THRESH_DIVIDER 8
++#define ENA_RX_REFILL_THRESH_PACKET 256
+
+ /* Number of queues to check for missing queues per timer service */
+ #define ENA_MONITORED_TX_QUEUES 4
diff --git a/debian/patches/features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch b/debian/patches/features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch
new file mode 100644
index 000000000..6e493b217
--- /dev/null
+++ b/debian/patches/features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch
@@ -0,0 +1,28 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:24 +0300
+Subject: [PATCH 10/19] net: ena: change rx copybreak default to reduce kernel
+ memory pressure
+Origin: https://git.kernel.org/linus/87731f0c681c9682c5521e5197d89e561b7da395
+
+Improves socket memory utilization when receiving packets larger
+than 128 bytes (the previous rx copybreak) and smaller than 256 bytes.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -81,7 +81,7 @@
+ #define ENA_DEFAULT_RING_SIZE (1024)
+
+ #define ENA_TX_WAKEUP_THRESH (MAX_SKB_FRAGS + 2)
+-#define ENA_DEFAULT_RX_COPYBREAK (128 - NET_IP_ALIGN)
++#define ENA_DEFAULT_RX_COPYBREAK (256 - NET_IP_ALIGN)
+
+ /* limit the buffer size to 600 bytes to handle MTU changes from very
+ * small to very large, in which case the number of buffers per packet
diff --git a/debian/patches/features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch b/debian/patches/features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch
new file mode 100644
index 000000000..ac5ab95e5
--- /dev/null
+++ b/debian/patches/features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch
@@ -0,0 +1,76 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:25 +0300
+Subject: [PATCH 11/19] net: ena: remove redundant parameter in
+ ena_com_admin_init()
+Origin: https://git.kernel.org/linus/f1e90f6e2c1fb0e491f910540314015324fed1e2
+
+Remove redundant spinlock acquire parameter from ena_com_admin_init()
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++----
+ drivers/net/ethernet/amazon/ena/ena_com.h | 5 +----
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +-
+ 3 files changed, 4 insertions(+), 9 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -1701,8 +1701,7 @@ void ena_com_mmio_reg_read_request_write
+ }
+
+ int ena_com_admin_init(struct ena_com_dev *ena_dev,
+- struct ena_aenq_handlers *aenq_handlers,
+- bool init_spinlock)
++ struct ena_aenq_handlers *aenq_handlers)
+ {
+ struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue;
+ u32 aq_caps, acq_caps, dev_sts, addr_low, addr_high;
+@@ -1728,8 +1727,7 @@ int ena_com_admin_init(struct ena_com_de
+
+ atomic_set(&admin_queue->outstanding_cmds, 0);
+
+- if (init_spinlock)
+- spin_lock_init(&admin_queue->q_lock);
++ spin_lock_init(&admin_queue->q_lock);
+
+ ret = ena_com_init_comp_ctxt(admin_queue);
+ if (ret)
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -436,8 +436,6 @@ void ena_com_mmio_reg_read_request_destr
+ /* ena_com_admin_init - Init the admin and the async queues
+ * @ena_dev: ENA communication layer struct
+ * @aenq_handlers: Those handlers to be called upon event.
+- * @init_spinlock: Indicate if this method should init the admin spinlock or
+- * the spinlock was init before (for example, in a case of FLR).
+ *
+ * Initialize the admin submission and completion queues.
+ * Initialize the asynchronous events notification queues.
+@@ -445,8 +443,7 @@ void ena_com_mmio_reg_read_request_destr
+ * @return - 0 on success, negative value on failure.
+ */
+ int ena_com_admin_init(struct ena_com_dev *ena_dev,
+- struct ena_aenq_handlers *aenq_handlers,
+- bool init_spinlock);
++ struct ena_aenq_handlers *aenq_handlers);
+
+ /* ena_com_admin_destroy - Destroy the admin and the async events queues.
+ * @ena_dev: ENA communication layer struct
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2508,7 +2508,7 @@ static int ena_device_init(struct ena_co
+ }
+
+ /* ENA admin level init */
+- rc = ena_com_admin_init(ena_dev, &aenq_handlers, true);
++ rc = ena_com_admin_init(ena_dev, &aenq_handlers);
+ if (rc) {
+ dev_err(dev,
+ "Can not initialize ena admin queue with device\n");
diff --git a/debian/patches/features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch b/debian/patches/features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch
new file mode 100644
index 000000000..ce4d8d8e0
--- /dev/null
+++ b/debian/patches/features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch
@@ -0,0 +1,28 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:26 +0300
+Subject: [PATCH 12/19] net: ena: update driver version to 2.0.1
+Origin: https://git.kernel.org/linus/3a7b9d8ddd200bdafaa3ef75b8544d2403eaa03b
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -43,9 +43,9 @@
+ #include "ena_com.h"
+ #include "ena_eth_com.h"
+
+-#define DRV_MODULE_VER_MAJOR 1
+-#define DRV_MODULE_VER_MINOR 5
+-#define DRV_MODULE_VER_SUBMINOR 0
++#define DRV_MODULE_VER_MAJOR 2
++#define DRV_MODULE_VER_MINOR 0
++#define DRV_MODULE_VER_SUBMINOR 1
+
+ #define DRV_MODULE_NAME "ena"
+ #ifndef DRV_MODULE_VERSION
diff --git a/debian/patches/features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch b/debian/patches/features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch
new file mode 100644
index 000000000..2e0ad4279
--- /dev/null
+++ b/debian/patches/features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch
@@ -0,0 +1,1000 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Thu, 11 Oct 2018 11:26:27 +0300
+Subject: [PATCH 13/19] net: ena: fix indentations in ena_defs for better
+ readability
+Origin: https://git.kernel.org/linus/be26667cb3947c90322467f1d15ad86b02350e00
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/amazon/ena/ena_admin_defs.h | 334 +++++++-----------
+ .../net/ethernet/amazon/ena/ena_eth_io_defs.h | 223 ++++++------
+ .../net/ethernet/amazon/ena/ena_regs_defs.h | 206 +++++------
+ 3 files changed, 338 insertions(+), 425 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+@@ -32,119 +32,81 @@
+ #ifndef _ENA_ADMIN_H_
+ #define _ENA_ADMIN_H_
+
+-enum ena_admin_aq_opcode {
+- ENA_ADMIN_CREATE_SQ = 1,
+-
+- ENA_ADMIN_DESTROY_SQ = 2,
+-
+- ENA_ADMIN_CREATE_CQ = 3,
+-
+- ENA_ADMIN_DESTROY_CQ = 4,
+-
+- ENA_ADMIN_GET_FEATURE = 8,
+
+- ENA_ADMIN_SET_FEATURE = 9,
+-
+- ENA_ADMIN_GET_STATS = 11,
++enum ena_admin_aq_opcode {
++ ENA_ADMIN_CREATE_SQ = 1,
++ ENA_ADMIN_DESTROY_SQ = 2,
++ ENA_ADMIN_CREATE_CQ = 3,
++ ENA_ADMIN_DESTROY_CQ = 4,
++ ENA_ADMIN_GET_FEATURE = 8,
++ ENA_ADMIN_SET_FEATURE = 9,
++ ENA_ADMIN_GET_STATS = 11,
+ };
+
+ enum ena_admin_aq_completion_status {
+- ENA_ADMIN_SUCCESS = 0,
+-
+- ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE = 1,
+-
+- ENA_ADMIN_BAD_OPCODE = 2,
+-
+- ENA_ADMIN_UNSUPPORTED_OPCODE = 3,
+-
+- ENA_ADMIN_MALFORMED_REQUEST = 4,
+-
++ ENA_ADMIN_SUCCESS = 0,
++ ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE = 1,
++ ENA_ADMIN_BAD_OPCODE = 2,
++ ENA_ADMIN_UNSUPPORTED_OPCODE = 3,
++ ENA_ADMIN_MALFORMED_REQUEST = 4,
+ /* Additional status is provided in ACQ entry extended_status */
+- ENA_ADMIN_ILLEGAL_PARAMETER = 5,
+-
+- ENA_ADMIN_UNKNOWN_ERROR = 6,
+-
+- ENA_ADMIN_RESOURCE_BUSY = 7,
++ ENA_ADMIN_ILLEGAL_PARAMETER = 5,
++ ENA_ADMIN_UNKNOWN_ERROR = 6,
++ ENA_ADMIN_RESOURCE_BUSY = 7,
+ };
+
+ enum ena_admin_aq_feature_id {
+- ENA_ADMIN_DEVICE_ATTRIBUTES = 1,
+-
+- ENA_ADMIN_MAX_QUEUES_NUM = 2,
+-
+- ENA_ADMIN_HW_HINTS = 3,
+-
+- ENA_ADMIN_LLQ = 4,
+-
+- ENA_ADMIN_RSS_HASH_FUNCTION = 10,
+-
+- ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11,
+-
+- ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12,
+-
+- ENA_ADMIN_MTU = 14,
+-
+- ENA_ADMIN_RSS_HASH_INPUT = 18,
+-
+- ENA_ADMIN_INTERRUPT_MODERATION = 20,
+-
+- ENA_ADMIN_AENQ_CONFIG = 26,
+-
+- ENA_ADMIN_LINK_CONFIG = 27,
+-
+- ENA_ADMIN_HOST_ATTR_CONFIG = 28,
+-
+- ENA_ADMIN_FEATURES_OPCODE_NUM = 32,
++ ENA_ADMIN_DEVICE_ATTRIBUTES = 1,
++ ENA_ADMIN_MAX_QUEUES_NUM = 2,
++ ENA_ADMIN_HW_HINTS = 3,
++ ENA_ADMIN_LLQ = 4,
++ ENA_ADMIN_RSS_HASH_FUNCTION = 10,
++ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11,
++ ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12,
++ ENA_ADMIN_MTU = 14,
++ ENA_ADMIN_RSS_HASH_INPUT = 18,
++ ENA_ADMIN_INTERRUPT_MODERATION = 20,
++ ENA_ADMIN_AENQ_CONFIG = 26,
++ ENA_ADMIN_LINK_CONFIG = 27,
++ ENA_ADMIN_HOST_ATTR_CONFIG = 28,
++ ENA_ADMIN_FEATURES_OPCODE_NUM = 32,
+ };
+
+ enum ena_admin_placement_policy_type {
+ /* descriptors and headers are in host memory */
+- ENA_ADMIN_PLACEMENT_POLICY_HOST = 1,
+-
++ ENA_ADMIN_PLACEMENT_POLICY_HOST = 1,
+ /* descriptors and headers are in device memory (a.k.a Low Latency
+ * Queue)
+ */
+- ENA_ADMIN_PLACEMENT_POLICY_DEV = 3,
++ ENA_ADMIN_PLACEMENT_POLICY_DEV = 3,
+ };
+
+ enum ena_admin_link_types {
+- ENA_ADMIN_LINK_SPEED_1G = 0x1,
+-
+- ENA_ADMIN_LINK_SPEED_2_HALF_G = 0x2,
+-
+- ENA_ADMIN_LINK_SPEED_5G = 0x4,
+-
+- ENA_ADMIN_LINK_SPEED_10G = 0x8,
+-
+- ENA_ADMIN_LINK_SPEED_25G = 0x10,
+-
+- ENA_ADMIN_LINK_SPEED_40G = 0x20,
+-
+- ENA_ADMIN_LINK_SPEED_50G = 0x40,
+-
+- ENA_ADMIN_LINK_SPEED_100G = 0x80,
+-
+- ENA_ADMIN_LINK_SPEED_200G = 0x100,
+-
+- ENA_ADMIN_LINK_SPEED_400G = 0x200,
++ ENA_ADMIN_LINK_SPEED_1G = 0x1,
++ ENA_ADMIN_LINK_SPEED_2_HALF_G = 0x2,
++ ENA_ADMIN_LINK_SPEED_5G = 0x4,
++ ENA_ADMIN_LINK_SPEED_10G = 0x8,
++ ENA_ADMIN_LINK_SPEED_25G = 0x10,
++ ENA_ADMIN_LINK_SPEED_40G = 0x20,
++ ENA_ADMIN_LINK_SPEED_50G = 0x40,
++ ENA_ADMIN_LINK_SPEED_100G = 0x80,
++ ENA_ADMIN_LINK_SPEED_200G = 0x100,
++ ENA_ADMIN_LINK_SPEED_400G = 0x200,
+ };
+
+ enum ena_admin_completion_policy_type {
+ /* completion queue entry for each sq descriptor */
+- ENA_ADMIN_COMPLETION_POLICY_DESC = 0,
+-
++ ENA_ADMIN_COMPLETION_POLICY_DESC = 0,
+ /* completion queue entry upon request in sq descriptor */
+- ENA_ADMIN_COMPLETION_POLICY_DESC_ON_DEMAND = 1,
+-
++ ENA_ADMIN_COMPLETION_POLICY_DESC_ON_DEMAND = 1,
+ /* current queue head pointer is updated in OS memory upon sq
+ * descriptor request
+ */
+- ENA_ADMIN_COMPLETION_POLICY_HEAD_ON_DEMAND = 2,
+-
++ ENA_ADMIN_COMPLETION_POLICY_HEAD_ON_DEMAND = 2,
+ /* current queue head pointer is updated in OS memory for each sq
+ * descriptor
+ */
+- ENA_ADMIN_COMPLETION_POLICY_HEAD = 3,
++ ENA_ADMIN_COMPLETION_POLICY_HEAD = 3,
+ };
+
+ /* basic stats return ena_admin_basic_stats while extanded stats return a
+@@ -152,15 +114,13 @@ enum ena_admin_completion_policy_type {
+ * device id
+ */
+ enum ena_admin_get_stats_type {
+- ENA_ADMIN_GET_STATS_TYPE_BASIC = 0,
+-
+- ENA_ADMIN_GET_STATS_TYPE_EXTENDED = 1,
++ ENA_ADMIN_GET_STATS_TYPE_BASIC = 0,
++ ENA_ADMIN_GET_STATS_TYPE_EXTENDED = 1,
+ };
+
+ enum ena_admin_get_stats_scope {
+- ENA_ADMIN_SPECIFIC_QUEUE = 0,
+-
+- ENA_ADMIN_ETH_TRAFFIC = 1,
++ ENA_ADMIN_SPECIFIC_QUEUE = 0,
++ ENA_ADMIN_ETH_TRAFFIC = 1,
+ };
+
+ struct ena_admin_aq_common_desc {
+@@ -231,7 +191,9 @@ struct ena_admin_acq_common_desc {
+
+ u16 extended_status;
+
+- /* serves as a hint what AQ entries can be revoked */
++ /* indicates to the driver which AQ entry has been consumed by the
++ * device and could be reused
++ */
+ u16 sq_head_indx;
+ };
+
+@@ -300,9 +262,8 @@ struct ena_admin_aq_create_sq_cmd {
+ };
+
+ enum ena_admin_sq_direction {
+- ENA_ADMIN_SQ_DIRECTION_TX = 1,
+-
+- ENA_ADMIN_SQ_DIRECTION_RX = 2,
++ ENA_ADMIN_SQ_DIRECTION_TX = 1,
++ ENA_ADMIN_SQ_DIRECTION_RX = 2,
+ };
+
+ struct ena_admin_acq_create_sq_resp_desc {
+@@ -664,9 +625,8 @@ struct ena_admin_feature_offload_desc {
+ };
+
+ enum ena_admin_hash_functions {
+- ENA_ADMIN_TOEPLITZ = 1,
+-
+- ENA_ADMIN_CRC32 = 2,
++ ENA_ADMIN_TOEPLITZ = 1,
++ ENA_ADMIN_CRC32 = 2,
+ };
+
+ struct ena_admin_feature_rss_flow_hash_control {
+@@ -692,50 +652,35 @@ struct ena_admin_feature_rss_flow_hash_f
+
+ /* RSS flow hash protocols */
+ enum ena_admin_flow_hash_proto {
+- ENA_ADMIN_RSS_TCP4 = 0,
+-
+- ENA_ADMIN_RSS_UDP4 = 1,
+-
+- ENA_ADMIN_RSS_TCP6 = 2,
+-
+- ENA_ADMIN_RSS_UDP6 = 3,
+-
+- ENA_ADMIN_RSS_IP4 = 4,
+-
+- ENA_ADMIN_RSS_IP6 = 5,
+-
+- ENA_ADMIN_RSS_IP4_FRAG = 6,
+-
+- ENA_ADMIN_RSS_NOT_IP = 7,
+-
++ ENA_ADMIN_RSS_TCP4 = 0,
++ ENA_ADMIN_RSS_UDP4 = 1,
++ ENA_ADMIN_RSS_TCP6 = 2,
++ ENA_ADMIN_RSS_UDP6 = 3,
++ ENA_ADMIN_RSS_IP4 = 4,
++ ENA_ADMIN_RSS_IP6 = 5,
++ ENA_ADMIN_RSS_IP4_FRAG = 6,
++ ENA_ADMIN_RSS_NOT_IP = 7,
+ /* TCPv6 with extension header */
+- ENA_ADMIN_RSS_TCP6_EX = 8,
+-
++ ENA_ADMIN_RSS_TCP6_EX = 8,
+ /* IPv6 with extension header */
+- ENA_ADMIN_RSS_IP6_EX = 9,
+-
+- ENA_ADMIN_RSS_PROTO_NUM = 16,
++ ENA_ADMIN_RSS_IP6_EX = 9,
++ ENA_ADMIN_RSS_PROTO_NUM = 16,
+ };
+
+ /* RSS flow hash fields */
+ enum ena_admin_flow_hash_fields {
+ /* Ethernet Dest Addr */
+- ENA_ADMIN_RSS_L2_DA = BIT(0),
+-
++ ENA_ADMIN_RSS_L2_DA = BIT(0),
+ /* Ethernet Src Addr */
+- ENA_ADMIN_RSS_L2_SA = BIT(1),
+-
++ ENA_ADMIN_RSS_L2_SA = BIT(1),
+ /* ipv4/6 Dest Addr */
+- ENA_ADMIN_RSS_L3_DA = BIT(2),
+-
++ ENA_ADMIN_RSS_L3_DA = BIT(2),
+ /* ipv4/6 Src Addr */
+- ENA_ADMIN_RSS_L3_SA = BIT(3),
+-
++ ENA_ADMIN_RSS_L3_SA = BIT(3),
+ /* tcp/udp Dest Port */
+- ENA_ADMIN_RSS_L4_DP = BIT(4),
+-
++ ENA_ADMIN_RSS_L4_DP = BIT(4),
+ /* tcp/udp Src Port */
+- ENA_ADMIN_RSS_L4_SP = BIT(5),
++ ENA_ADMIN_RSS_L4_SP = BIT(5),
+ };
+
+ struct ena_admin_proto_input {
+@@ -774,19 +719,13 @@ struct ena_admin_feature_rss_flow_hash_i
+ };
+
+ enum ena_admin_os_type {
+- ENA_ADMIN_OS_LINUX = 1,
+-
+- ENA_ADMIN_OS_WIN = 2,
+-
+- ENA_ADMIN_OS_DPDK = 3,
+-
+- ENA_ADMIN_OS_FREEBSD = 4,
+-
+- ENA_ADMIN_OS_IPXE = 5,
+-
+- ENA_ADMIN_OS_ESXI = 6,
+-
+- ENA_ADMIN_OS_GROUPS_NUM = 6,
++ ENA_ADMIN_OS_LINUX = 1,
++ ENA_ADMIN_OS_WIN = 2,
++ ENA_ADMIN_OS_DPDK = 3,
++ ENA_ADMIN_OS_FREEBSD = 4,
++ ENA_ADMIN_OS_IPXE = 5,
++ ENA_ADMIN_OS_ESXI = 6,
++ ENA_ADMIN_OS_GROUPS_NUM = 6,
+ };
+
+ struct ena_admin_host_info {
+@@ -981,25 +920,18 @@ struct ena_admin_aenq_common_desc {
+
+ /* asynchronous event notification groups */
+ enum ena_admin_aenq_group {
+- ENA_ADMIN_LINK_CHANGE = 0,
+-
+- ENA_ADMIN_FATAL_ERROR = 1,
+-
+- ENA_ADMIN_WARNING = 2,
+-
+- ENA_ADMIN_NOTIFICATION = 3,
+-
+- ENA_ADMIN_KEEP_ALIVE = 4,
+-
+- ENA_ADMIN_AENQ_GROUPS_NUM = 5,
++ ENA_ADMIN_LINK_CHANGE = 0,
++ ENA_ADMIN_FATAL_ERROR = 1,
++ ENA_ADMIN_WARNING = 2,
++ ENA_ADMIN_NOTIFICATION = 3,
++ ENA_ADMIN_KEEP_ALIVE = 4,
++ ENA_ADMIN_AENQ_GROUPS_NUM = 5,
+ };
+
+ enum ena_admin_aenq_notification_syndrom {
+- ENA_ADMIN_SUSPEND = 0,
+-
+- ENA_ADMIN_RESUME = 1,
+-
+- ENA_ADMIN_UPDATE_HINTS = 2,
++ ENA_ADMIN_SUSPEND = 0,
++ ENA_ADMIN_RESUME = 1,
++ ENA_ADMIN_UPDATE_HINTS = 2,
+ };
+
+ struct ena_admin_aenq_entry {
+@@ -1034,27 +966,27 @@ struct ena_admin_ena_mmio_req_read_less_
+ };
+
+ /* aq_common_desc */
+-#define ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0)
+-#define ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK BIT(0)
+-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT 1
+-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK BIT(1)
+-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT 2
+-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK BIT(2)
++#define ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0)
++#define ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK BIT(0)
++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT 1
++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK BIT(1)
++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT 2
++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK BIT(2)
+
+ /* sq */
+-#define ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT 5
+-#define ENA_ADMIN_SQ_SQ_DIRECTION_MASK GENMASK(7, 5)
++#define ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT 5
++#define ENA_ADMIN_SQ_SQ_DIRECTION_MASK GENMASK(7, 5)
+
+ /* acq_common_desc */
+-#define ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0)
+-#define ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK BIT(0)
++#define ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0)
++#define ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK BIT(0)
+
+ /* aq_create_sq_cmd */
+-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT 5
+-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK GENMASK(7, 5)
+-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK GENMASK(3, 0)
+-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT 4
+-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK GENMASK(6, 4)
++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT 5
++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK GENMASK(7, 5)
++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK GENMASK(3, 0)
++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT 4
++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK GENMASK(6, 4)
+ #define ENA_ADMIN_AQ_CREATE_SQ_CMD_IS_PHYSICALLY_CONTIGUOUS_MASK BIT(0)
+
+ /* aq_create_cq_cmd */
+@@ -1063,12 +995,12 @@ struct ena_admin_ena_mmio_req_read_less_
+ #define ENA_ADMIN_AQ_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS_MASK GENMASK(4, 0)
+
+ /* get_set_feature_common_desc */
+-#define ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0)
++#define ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0)
+
+ /* get_feature_link_desc */
+-#define ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK BIT(0)
+-#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT 1
+-#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK BIT(1)
++#define ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK BIT(0)
++#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT 1
++#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK BIT(1)
+
+ /* feature_offload_desc */
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK BIT(0)
+@@ -1080,19 +1012,19 @@ struct ena_admin_ena_mmio_req_read_less_
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK BIT(3)
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_SHIFT 4
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK BIT(4)
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT 5
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK BIT(5)
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT 6
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK BIT(6)
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT 7
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK BIT(7)
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT 5
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK BIT(5)
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT 6
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK BIT(6)
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT 7
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK BIT(7)
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK BIT(0)
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_SHIFT 1
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK BIT(1)
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_SHIFT 2
+ #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK BIT(2)
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT 3
+-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK BIT(3)
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT 3
++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK BIT(3)
+
+ /* feature_rss_flow_hash_function */
+ #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_FUNCS_MASK GENMASK(7, 0)
+@@ -1100,32 +1032,32 @@ struct ena_admin_ena_mmio_req_read_less_
+
+ /* feature_rss_flow_hash_input */
+ #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_SHIFT 1
+-#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK BIT(1)
++#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK BIT(1)
+ #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_SHIFT 2
+-#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK BIT(2)
++#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK BIT(2)
+ #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_SHIFT 1
+ #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_MASK BIT(1)
+ #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_SHIFT 2
+ #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_MASK BIT(2)
+
+ /* host_info */
+-#define ENA_ADMIN_HOST_INFO_MAJOR_MASK GENMASK(7, 0)
+-#define ENA_ADMIN_HOST_INFO_MINOR_SHIFT 8
+-#define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8)
+-#define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16
+-#define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16)
+-#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT 24
+-#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_MASK GENMASK(31, 24)
+-#define ENA_ADMIN_HOST_INFO_FUNCTION_MASK GENMASK(2, 0)
+-#define ENA_ADMIN_HOST_INFO_DEVICE_SHIFT 3
+-#define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3)
+-#define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8
+-#define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8)
++#define ENA_ADMIN_HOST_INFO_MAJOR_MASK GENMASK(7, 0)
++#define ENA_ADMIN_HOST_INFO_MINOR_SHIFT 8
++#define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8)
++#define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16
++#define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16)
++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT 24
++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_MASK GENMASK(31, 24)
++#define ENA_ADMIN_HOST_INFO_FUNCTION_MASK GENMASK(2, 0)
++#define ENA_ADMIN_HOST_INFO_DEVICE_SHIFT 3
++#define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3)
++#define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8
++#define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8)
+
+ /* aenq_common_desc */
+-#define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0)
++#define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0)
+
+ /* aenq_link_change_desc */
+-#define ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK BIT(0)
++#define ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK BIT(0)
+
+ #endif /*_ENA_ADMIN_H_ */
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h
+@@ -33,25 +33,18 @@
+ #define _ENA_ETH_IO_H_
+
+ enum ena_eth_io_l3_proto_index {
+- ENA_ETH_IO_L3_PROTO_UNKNOWN = 0,
+-
+- ENA_ETH_IO_L3_PROTO_IPV4 = 8,
+-
+- ENA_ETH_IO_L3_PROTO_IPV6 = 11,
+-
+- ENA_ETH_IO_L3_PROTO_FCOE = 21,
+-
+- ENA_ETH_IO_L3_PROTO_ROCE = 22,
++ ENA_ETH_IO_L3_PROTO_UNKNOWN = 0,
++ ENA_ETH_IO_L3_PROTO_IPV4 = 8,
++ ENA_ETH_IO_L3_PROTO_IPV6 = 11,
++ ENA_ETH_IO_L3_PROTO_FCOE = 21,
++ ENA_ETH_IO_L3_PROTO_ROCE = 22,
+ };
+
+ enum ena_eth_io_l4_proto_index {
+- ENA_ETH_IO_L4_PROTO_UNKNOWN = 0,
+-
+- ENA_ETH_IO_L4_PROTO_TCP = 12,
+-
+- ENA_ETH_IO_L4_PROTO_UDP = 13,
+-
+- ENA_ETH_IO_L4_PROTO_ROUTEABLE_ROCE = 23,
++ ENA_ETH_IO_L4_PROTO_UNKNOWN = 0,
++ ENA_ETH_IO_L4_PROTO_TCP = 12,
++ ENA_ETH_IO_L4_PROTO_UDP = 13,
++ ENA_ETH_IO_L4_PROTO_ROUTEABLE_ROCE = 23,
+ };
+
+ struct ena_eth_io_tx_desc {
+@@ -307,116 +300,116 @@ struct ena_eth_io_numa_node_cfg_reg {
+ };
+
+ /* tx_desc */
+-#define ENA_ETH_IO_TX_DESC_LENGTH_MASK GENMASK(15, 0)
+-#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT 16
+-#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK GENMASK(21, 16)
+-#define ENA_ETH_IO_TX_DESC_META_DESC_SHIFT 23
+-#define ENA_ETH_IO_TX_DESC_META_DESC_MASK BIT(23)
+-#define ENA_ETH_IO_TX_DESC_PHASE_SHIFT 24
+-#define ENA_ETH_IO_TX_DESC_PHASE_MASK BIT(24)
+-#define ENA_ETH_IO_TX_DESC_FIRST_SHIFT 26
+-#define ENA_ETH_IO_TX_DESC_FIRST_MASK BIT(26)
+-#define ENA_ETH_IO_TX_DESC_LAST_SHIFT 27
+-#define ENA_ETH_IO_TX_DESC_LAST_MASK BIT(27)
+-#define ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT 28
+-#define ENA_ETH_IO_TX_DESC_COMP_REQ_MASK BIT(28)
+-#define ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK GENMASK(3, 0)
+-#define ENA_ETH_IO_TX_DESC_DF_SHIFT 4
+-#define ENA_ETH_IO_TX_DESC_DF_MASK BIT(4)
+-#define ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT 7
+-#define ENA_ETH_IO_TX_DESC_TSO_EN_MASK BIT(7)
+-#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT 8
+-#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK GENMASK(12, 8)
+-#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT 13
+-#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK BIT(13)
+-#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT 14
+-#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK BIT(14)
+-#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT 15
+-#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK BIT(15)
+-#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT 17
+-#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK BIT(17)
+-#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT 22
+-#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK GENMASK(31, 22)
+-#define ENA_ETH_IO_TX_DESC_ADDR_HI_MASK GENMASK(15, 0)
+-#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT 24
+-#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK GENMASK(31, 24)
++#define ENA_ETH_IO_TX_DESC_LENGTH_MASK GENMASK(15, 0)
++#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT 16
++#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK GENMASK(21, 16)
++#define ENA_ETH_IO_TX_DESC_META_DESC_SHIFT 23
++#define ENA_ETH_IO_TX_DESC_META_DESC_MASK BIT(23)
++#define ENA_ETH_IO_TX_DESC_PHASE_SHIFT 24
++#define ENA_ETH_IO_TX_DESC_PHASE_MASK BIT(24)
++#define ENA_ETH_IO_TX_DESC_FIRST_SHIFT 26
++#define ENA_ETH_IO_TX_DESC_FIRST_MASK BIT(26)
++#define ENA_ETH_IO_TX_DESC_LAST_SHIFT 27
++#define ENA_ETH_IO_TX_DESC_LAST_MASK BIT(27)
++#define ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT 28
++#define ENA_ETH_IO_TX_DESC_COMP_REQ_MASK BIT(28)
++#define ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK GENMASK(3, 0)
++#define ENA_ETH_IO_TX_DESC_DF_SHIFT 4
++#define ENA_ETH_IO_TX_DESC_DF_MASK BIT(4)
++#define ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT 7
++#define ENA_ETH_IO_TX_DESC_TSO_EN_MASK BIT(7)
++#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT 8
++#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK GENMASK(12, 8)
++#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT 13
++#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK BIT(13)
++#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT 14
++#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK BIT(14)
++#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT 15
++#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK BIT(15)
++#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT 17
++#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK BIT(17)
++#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT 22
++#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK GENMASK(31, 22)
++#define ENA_ETH_IO_TX_DESC_ADDR_HI_MASK GENMASK(15, 0)
++#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT 24
++#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK GENMASK(31, 24)
+
+ /* tx_meta_desc */
+-#define ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK GENMASK(9, 0)
+-#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT 14
+-#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK BIT(14)
+-#define ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT 16
+-#define ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK GENMASK(19, 16)
+-#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT 20
+-#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK BIT(20)
+-#define ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT 21
+-#define ENA_ETH_IO_TX_META_DESC_META_STORE_MASK BIT(21)
+-#define ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT 23
+-#define ENA_ETH_IO_TX_META_DESC_META_DESC_MASK BIT(23)
+-#define ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT 24
+-#define ENA_ETH_IO_TX_META_DESC_PHASE_MASK BIT(24)
+-#define ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT 26
+-#define ENA_ETH_IO_TX_META_DESC_FIRST_MASK BIT(26)
+-#define ENA_ETH_IO_TX_META_DESC_LAST_SHIFT 27
+-#define ENA_ETH_IO_TX_META_DESC_LAST_MASK BIT(27)
+-#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT 28
+-#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK BIT(28)
+-#define ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK GENMASK(5, 0)
+-#define ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK GENMASK(7, 0)
+-#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT 8
+-#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK GENMASK(15, 8)
+-#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT 16
+-#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK GENMASK(21, 16)
+-#define ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT 22
+-#define ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK GENMASK(31, 22)
++#define ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK GENMASK(9, 0)
++#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT 14
++#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK BIT(14)
++#define ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT 16
++#define ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK GENMASK(19, 16)
++#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT 20
++#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK BIT(20)
++#define ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT 21
++#define ENA_ETH_IO_TX_META_DESC_META_STORE_MASK BIT(21)
++#define ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT 23
++#define ENA_ETH_IO_TX_META_DESC_META_DESC_MASK BIT(23)
++#define ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT 24
++#define ENA_ETH_IO_TX_META_DESC_PHASE_MASK BIT(24)
++#define ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT 26
++#define ENA_ETH_IO_TX_META_DESC_FIRST_MASK BIT(26)
++#define ENA_ETH_IO_TX_META_DESC_LAST_SHIFT 27
++#define ENA_ETH_IO_TX_META_DESC_LAST_MASK BIT(27)
++#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT 28
++#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK BIT(28)
++#define ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK GENMASK(5, 0)
++#define ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK GENMASK(7, 0)
++#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT 8
++#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK GENMASK(15, 8)
++#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT 16
++#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK GENMASK(21, 16)
++#define ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT 22
++#define ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK GENMASK(31, 22)
+
+ /* tx_cdesc */
+-#define ENA_ETH_IO_TX_CDESC_PHASE_MASK BIT(0)
++#define ENA_ETH_IO_TX_CDESC_PHASE_MASK BIT(0)
+
+ /* rx_desc */
+-#define ENA_ETH_IO_RX_DESC_PHASE_MASK BIT(0)
+-#define ENA_ETH_IO_RX_DESC_FIRST_SHIFT 2
+-#define ENA_ETH_IO_RX_DESC_FIRST_MASK BIT(2)
+-#define ENA_ETH_IO_RX_DESC_LAST_SHIFT 3
+-#define ENA_ETH_IO_RX_DESC_LAST_MASK BIT(3)
+-#define ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT 4
+-#define ENA_ETH_IO_RX_DESC_COMP_REQ_MASK BIT(4)
++#define ENA_ETH_IO_RX_DESC_PHASE_MASK BIT(0)
++#define ENA_ETH_IO_RX_DESC_FIRST_SHIFT 2
++#define ENA_ETH_IO_RX_DESC_FIRST_MASK BIT(2)
++#define ENA_ETH_IO_RX_DESC_LAST_SHIFT 3
++#define ENA_ETH_IO_RX_DESC_LAST_MASK BIT(3)
++#define ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT 4
++#define ENA_ETH_IO_RX_DESC_COMP_REQ_MASK BIT(4)
+
+ /* rx_cdesc_base */
+-#define ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK GENMASK(4, 0)
+-#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT 5
+-#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK GENMASK(6, 5)
+-#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT 8
+-#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK GENMASK(12, 8)
+-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT 13
+-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK BIT(13)
+-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT 14
+-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14)
+-#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15
+-#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15)
+-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT 16
+-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK BIT(16)
+-#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24
+-#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24)
+-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25
+-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK BIT(25)
+-#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT 26
+-#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK BIT(26)
+-#define ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT 27
+-#define ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK BIT(27)
+-#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT 30
+-#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK BIT(30)
++#define ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK GENMASK(4, 0)
++#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT 5
++#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK GENMASK(6, 5)
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT 8
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK GENMASK(12, 8)
++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT 13
++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK BIT(13)
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT 14
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14)
++#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15
++#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15)
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT 16
++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK BIT(16)
++#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24
++#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24)
++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25
++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK BIT(25)
++#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT 26
++#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK BIT(26)
++#define ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT 27
++#define ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK BIT(27)
++#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT 30
++#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK BIT(30)
+
+ /* intr_reg */
+-#define ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK GENMASK(14, 0)
+-#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT 15
+-#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK GENMASK(29, 15)
+-#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT 30
+-#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK BIT(30)
++#define ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK GENMASK(14, 0)
++#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT 15
++#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK GENMASK(29, 15)
++#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT 30
++#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK BIT(30)
+
+ /* numa_node_cfg_reg */
+-#define ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK GENMASK(7, 0)
+-#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT 31
+-#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK BIT(31)
++#define ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK GENMASK(7, 0)
++#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT 31
++#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK BIT(31)
+
+ #endif /*_ENA_ETH_IO_H_ */
+Index: linux/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_regs_defs.h
+@@ -33,137 +33,125 @@
+ #define _ENA_REGS_H_
+
+ enum ena_regs_reset_reason_types {
+- ENA_REGS_RESET_NORMAL = 0,
+-
+- ENA_REGS_RESET_KEEP_ALIVE_TO = 1,
+-
+- ENA_REGS_RESET_ADMIN_TO = 2,
+-
+- ENA_REGS_RESET_MISS_TX_CMPL = 3,
+-
+- ENA_REGS_RESET_INV_RX_REQ_ID = 4,
+-
+- ENA_REGS_RESET_INV_TX_REQ_ID = 5,
+-
+- ENA_REGS_RESET_TOO_MANY_RX_DESCS = 6,
+-
+- ENA_REGS_RESET_INIT_ERR = 7,
+-
+- ENA_REGS_RESET_DRIVER_INVALID_STATE = 8,
+-
+- ENA_REGS_RESET_OS_TRIGGER = 9,
+-
+- ENA_REGS_RESET_OS_NETDEV_WD = 10,
+-
+- ENA_REGS_RESET_SHUTDOWN = 11,
+-
+- ENA_REGS_RESET_USER_TRIGGER = 12,
+-
+- ENA_REGS_RESET_GENERIC = 13,
+-
+- ENA_REGS_RESET_MISS_INTERRUPT = 14,
++ ENA_REGS_RESET_NORMAL = 0,
++ ENA_REGS_RESET_KEEP_ALIVE_TO = 1,
++ ENA_REGS_RESET_ADMIN_TO = 2,
++ ENA_REGS_RESET_MISS_TX_CMPL = 3,
++ ENA_REGS_RESET_INV_RX_REQ_ID = 4,
++ ENA_REGS_RESET_INV_TX_REQ_ID = 5,
++ ENA_REGS_RESET_TOO_MANY_RX_DESCS = 6,
++ ENA_REGS_RESET_INIT_ERR = 7,
++ ENA_REGS_RESET_DRIVER_INVALID_STATE = 8,
++ ENA_REGS_RESET_OS_TRIGGER = 9,
++ ENA_REGS_RESET_OS_NETDEV_WD = 10,
++ ENA_REGS_RESET_SHUTDOWN = 11,
++ ENA_REGS_RESET_USER_TRIGGER = 12,
++ ENA_REGS_RESET_GENERIC = 13,
++ ENA_REGS_RESET_MISS_INTERRUPT = 14,
+ };
+
+ /* ena_registers offsets */
+-#define ENA_REGS_VERSION_OFF 0x0
+-#define ENA_REGS_CONTROLLER_VERSION_OFF 0x4
+-#define ENA_REGS_CAPS_OFF 0x8
+-#define ENA_REGS_CAPS_EXT_OFF 0xc
+-#define ENA_REGS_AQ_BASE_LO_OFF 0x10
+-#define ENA_REGS_AQ_BASE_HI_OFF 0x14
+-#define ENA_REGS_AQ_CAPS_OFF 0x18
+-#define ENA_REGS_ACQ_BASE_LO_OFF 0x20
+-#define ENA_REGS_ACQ_BASE_HI_OFF 0x24
+-#define ENA_REGS_ACQ_CAPS_OFF 0x28
+-#define ENA_REGS_AQ_DB_OFF 0x2c
+-#define ENA_REGS_ACQ_TAIL_OFF 0x30
+-#define ENA_REGS_AENQ_CAPS_OFF 0x34
+-#define ENA_REGS_AENQ_BASE_LO_OFF 0x38
+-#define ENA_REGS_AENQ_BASE_HI_OFF 0x3c
+-#define ENA_REGS_AENQ_HEAD_DB_OFF 0x40
+-#define ENA_REGS_AENQ_TAIL_OFF 0x44
+-#define ENA_REGS_INTR_MASK_OFF 0x4c
+-#define ENA_REGS_DEV_CTL_OFF 0x54
+-#define ENA_REGS_DEV_STS_OFF 0x58
+-#define ENA_REGS_MMIO_REG_READ_OFF 0x5c
+-#define ENA_REGS_MMIO_RESP_LO_OFF 0x60
+-#define ENA_REGS_MMIO_RESP_HI_OFF 0x64
+-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_OFF 0x68
++
++/* 0 base */
++#define ENA_REGS_VERSION_OFF 0x0
++#define ENA_REGS_CONTROLLER_VERSION_OFF 0x4
++#define ENA_REGS_CAPS_OFF 0x8
++#define ENA_REGS_CAPS_EXT_OFF 0xc
++#define ENA_REGS_AQ_BASE_LO_OFF 0x10
++#define ENA_REGS_AQ_BASE_HI_OFF 0x14
++#define ENA_REGS_AQ_CAPS_OFF 0x18
++#define ENA_REGS_ACQ_BASE_LO_OFF 0x20
++#define ENA_REGS_ACQ_BASE_HI_OFF 0x24
++#define ENA_REGS_ACQ_CAPS_OFF 0x28
++#define ENA_REGS_AQ_DB_OFF 0x2c
++#define ENA_REGS_ACQ_TAIL_OFF 0x30
++#define ENA_REGS_AENQ_CAPS_OFF 0x34
++#define ENA_REGS_AENQ_BASE_LO_OFF 0x38
++#define ENA_REGS_AENQ_BASE_HI_OFF 0x3c
++#define ENA_REGS_AENQ_HEAD_DB_OFF 0x40
++#define ENA_REGS_AENQ_TAIL_OFF 0x44
++#define ENA_REGS_INTR_MASK_OFF 0x4c
++#define ENA_REGS_DEV_CTL_OFF 0x54
++#define ENA_REGS_DEV_STS_OFF 0x58
++#define ENA_REGS_MMIO_REG_READ_OFF 0x5c
++#define ENA_REGS_MMIO_RESP_LO_OFF 0x60
++#define ENA_REGS_MMIO_RESP_HI_OFF 0x64
++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_OFF 0x68
+
+ /* version register */
+-#define ENA_REGS_VERSION_MINOR_VERSION_MASK 0xff
+-#define ENA_REGS_VERSION_MAJOR_VERSION_SHIFT 8
+-#define ENA_REGS_VERSION_MAJOR_VERSION_MASK 0xff00
++#define ENA_REGS_VERSION_MINOR_VERSION_MASK 0xff
++#define ENA_REGS_VERSION_MAJOR_VERSION_SHIFT 8
++#define ENA_REGS_VERSION_MAJOR_VERSION_MASK 0xff00
+
+ /* controller_version register */
+-#define ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK 0xff
+-#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT 8
+-#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK 0xff00
+-#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT 16
+-#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK 0xff0000
+-#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_SHIFT 24
+-#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_MASK 0xff000000
++#define ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK 0xff
++#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT 8
++#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK 0xff00
++#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT 16
++#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK 0xff0000
++#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_SHIFT 24
++#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_MASK 0xff000000
+
+ /* caps register */
+-#define ENA_REGS_CAPS_CONTIGUOUS_QUEUE_REQUIRED_MASK 0x1
+-#define ENA_REGS_CAPS_RESET_TIMEOUT_SHIFT 1
+-#define ENA_REGS_CAPS_RESET_TIMEOUT_MASK 0x3e
+-#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT 8
+-#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK 0xff00
+-#define ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT 16
+-#define ENA_REGS_CAPS_ADMIN_CMD_TO_MASK 0xf0000
++#define ENA_REGS_CAPS_CONTIGUOUS_QUEUE_REQUIRED_MASK 0x1
++#define ENA_REGS_CAPS_RESET_TIMEOUT_SHIFT 1
++#define ENA_REGS_CAPS_RESET_TIMEOUT_MASK 0x3e
++#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT 8
++#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK 0xff00
++#define ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT 16
++#define ENA_REGS_CAPS_ADMIN_CMD_TO_MASK 0xf0000
+
+ /* aq_caps register */
+-#define ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK 0xffff
+-#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_SHIFT 16
+-#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_MASK 0xffff0000
++#define ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK 0xffff
++#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_SHIFT 16
++#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_MASK 0xffff0000
+
+ /* acq_caps register */
+-#define ENA_REGS_ACQ_CAPS_ACQ_DEPTH_MASK 0xffff
+-#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_SHIFT 16
+-#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_MASK 0xffff0000
++#define ENA_REGS_ACQ_CAPS_ACQ_DEPTH_MASK 0xffff
++#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_SHIFT 16
++#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_MASK 0xffff0000
+
+ /* aenq_caps register */
+-#define ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK 0xffff
+-#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT 16
+-#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK 0xffff0000
++#define ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK 0xffff
++#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT 16
++#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK 0xffff0000
+
+ /* dev_ctl register */
+-#define ENA_REGS_DEV_CTL_DEV_RESET_MASK 0x1
+-#define ENA_REGS_DEV_CTL_AQ_RESTART_SHIFT 1
+-#define ENA_REGS_DEV_CTL_AQ_RESTART_MASK 0x2
+-#define ENA_REGS_DEV_CTL_QUIESCENT_SHIFT 2
+-#define ENA_REGS_DEV_CTL_QUIESCENT_MASK 0x4
+-#define ENA_REGS_DEV_CTL_IO_RESUME_SHIFT 3
+-#define ENA_REGS_DEV_CTL_IO_RESUME_MASK 0x8
+-#define ENA_REGS_DEV_CTL_RESET_REASON_SHIFT 28
+-#define ENA_REGS_DEV_CTL_RESET_REASON_MASK 0xf0000000
++#define ENA_REGS_DEV_CTL_DEV_RESET_MASK 0x1
++#define ENA_REGS_DEV_CTL_AQ_RESTART_SHIFT 1
++#define ENA_REGS_DEV_CTL_AQ_RESTART_MASK 0x2
++#define ENA_REGS_DEV_CTL_QUIESCENT_SHIFT 2
++#define ENA_REGS_DEV_CTL_QUIESCENT_MASK 0x4
++#define ENA_REGS_DEV_CTL_IO_RESUME_SHIFT 3
++#define ENA_REGS_DEV_CTL_IO_RESUME_MASK 0x8
++#define ENA_REGS_DEV_CTL_RESET_REASON_SHIFT 28
++#define ENA_REGS_DEV_CTL_RESET_REASON_MASK 0xf0000000
+
+ /* dev_sts register */
+-#define ENA_REGS_DEV_STS_READY_MASK 0x1
+-#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_SHIFT 1
+-#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_MASK 0x2
+-#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_SHIFT 2
+-#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_MASK 0x4
+-#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_SHIFT 3
+-#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK 0x8
+-#define ENA_REGS_DEV_STS_RESET_FINISHED_SHIFT 4
+-#define ENA_REGS_DEV_STS_RESET_FINISHED_MASK 0x10
+-#define ENA_REGS_DEV_STS_FATAL_ERROR_SHIFT 5
+-#define ENA_REGS_DEV_STS_FATAL_ERROR_MASK 0x20
+-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_SHIFT 6
+-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_MASK 0x40
+-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_SHIFT 7
+-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_MASK 0x80
++#define ENA_REGS_DEV_STS_READY_MASK 0x1
++#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_SHIFT 1
++#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_MASK 0x2
++#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_SHIFT 2
++#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_MASK 0x4
++#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_SHIFT 3
++#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK 0x8
++#define ENA_REGS_DEV_STS_RESET_FINISHED_SHIFT 4
++#define ENA_REGS_DEV_STS_RESET_FINISHED_MASK 0x10
++#define ENA_REGS_DEV_STS_FATAL_ERROR_SHIFT 5
++#define ENA_REGS_DEV_STS_FATAL_ERROR_MASK 0x20
++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_SHIFT 6
++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_MASK 0x40
++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_SHIFT 7
++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_MASK 0x80
+
+ /* mmio_reg_read register */
+-#define ENA_REGS_MMIO_REG_READ_REQ_ID_MASK 0xffff
+-#define ENA_REGS_MMIO_REG_READ_REG_OFF_SHIFT 16
+-#define ENA_REGS_MMIO_REG_READ_REG_OFF_MASK 0xffff0000
++#define ENA_REGS_MMIO_REG_READ_REQ_ID_MASK 0xffff
++#define ENA_REGS_MMIO_REG_READ_REG_OFF_SHIFT 16
++#define ENA_REGS_MMIO_REG_READ_REG_OFF_MASK 0xffff0000
+
+ /* rss_ind_entry_update register */
+-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_INDEX_MASK 0xffff
+-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_SHIFT 16
+-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_MASK 0xffff0000
++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_INDEX_MASK 0xffff
++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_SHIFT 16
++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_MASK 0xffff0000
+
+ #endif /*_ENA_REGS_H_ */
diff --git a/debian/patches/features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch b/debian/patches/features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch
new file mode 100644
index 000000000..6161a87ba
--- /dev/null
+++ b/debian/patches/features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch
@@ -0,0 +1,50 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Wed, 17 Oct 2018 15:33:23 +0300
+Subject: [PATCH 15/19] net: ena: enable Low Latency Queues
+Origin: https://git.kernel.org/linus/9fd255928d7ffb56d8466fab3331d0b2f40aa8c7
+
+Use the new API to enable usage of LLQ.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -3022,20 +3022,10 @@ static int ena_calc_io_queue_num(struct
+ int io_sq_num, io_queue_num;
+
+ /* In case of LLQ use the llq number in the get feature cmd */
+- if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) {
+- io_sq_num = get_feat_ctx->max_queues.max_legacy_llq_num;
+-
+- if (io_sq_num == 0) {
+- dev_err(&pdev->dev,
+- "Trying to use LLQ but llq_num is 0. Fall back into regular queues\n");
+-
+- ena_dev->tx_mem_queue_type =
+- ENA_ADMIN_PLACEMENT_POLICY_HOST;
+- io_sq_num = get_feat_ctx->max_queues.max_sq_num;
+- }
+- } else {
++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
++ io_sq_num = get_feat_ctx->llq.max_llq_num;
++ else
+ io_sq_num = get_feat_ctx->max_queues.max_sq_num;
+- }
+
+ io_queue_num = min_t(int, num_online_cpus(), ENA_MAX_NUM_IO_QUEUES);
+ io_queue_num = min_t(int, io_queue_num, io_sq_num);
+@@ -3238,7 +3228,7 @@ static int ena_calc_queue_size(struct pc
+
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+ queue_size = min_t(u32, queue_size,
+- get_feat_ctx->max_queues.max_legacy_llq_depth);
++ get_feat_ctx->llq.max_llq_depth);
+
+ queue_size = rounddown_pow_of_two(queue_size);
+
diff --git a/debian/patches/features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch b/debian/patches/features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch
new file mode 100644
index 000000000..b37c7a169
--- /dev/null
+++ b/debian/patches/features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch
@@ -0,0 +1,31 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Sun, 21 Oct 2018 18:07:14 +0300
+Subject: [PATCH 16/19] net: ena: fix compilation error in xtensa architecture
+Origin: https://git.kernel.org/linus/00f17a8219f02139119d8b4547e032bf4888fa0d
+
+linux/prefetch.h is never explicitly included in ena_com, although
+functions from it, such as prefetchw(), are used throughout ena_com.
+This is an inclusion bug, and we fix it here by explicitly including
+linux/prefetch.h. The bug was exposed when the driver was compiled
+for the xtensa architecture.
+
+Fixes: 689b2bdaaa14 ("net: ena: add functions for handling Low Latency Queues in ena_com")
+Fixes: 8c590f977638 ("ena: Fix Kconfig dependency on X86")
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -38,6 +38,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/gfp.h>
+ #include <linux/io.h>
++#include <linux/prefetch.h>
+ #include <linux/sched.h>
+ #include <linux/sizes.h>
+ #include <linux/spinlock.h>
diff --git a/debian/patches/features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch b/debian/patches/features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch
new file mode 100644
index 000000000..59f2b13b7
--- /dev/null
+++ b/debian/patches/features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch
@@ -0,0 +1,97 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 19 Nov 2018 12:05:21 +0200
+Subject: [PATCH 18/19] net: ena: fix crash during ena_remove()
+Origin: https://git.kernel.org/linus/58a54b9c62e206b8d5f6e59020bcb178fc271d8e
+
+In ena_remove() we have the following stack call:
+ena_remove()
+ unregister_netdev()
+ ena_destroy_device()
+ netif_carrier_off()
+
+Calling netif_carrier_off() causes linkwatch to try to handle the
+link change event on the already unregistered netdev, which leads
+to a read from an unreadable memory address.
+
+This patch switches the order of the two functions, so that
+netif_carrier_off() is called on a regiestered netdev.
+
+To accomplish this fix we also had to:
+1. Remove the set bit ENA_FLAG_TRIGGER_RESET
+2. Add a sanitiy check in ena_close()
+both to prevent double device reset (when calling unregister_netdev()
+ena_close is called, but the device was already deleted in
+ena_destroy_device()).
+3. Set the admin_queue running state to false to avoid using it after
+device was reset (for example when calling ena_destroy_all_io_queues()
+right after ena_com_dev_reset() in ena_down)
+
+Fixes: 944b28aa2982 ("net: ena: fix missing lock during device destruction")
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 21 ++++++++++----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1853,6 +1853,8 @@ static void ena_down(struct ena_adapter
+ rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
+ if (rc)
+ dev_err(&adapter->pdev->dev, "Device reset failed\n");
++ /* stop submitting admin commands on a device that was reset */
++ ena_com_set_admin_running_state(adapter->ena_dev, false);
+ }
+
+ ena_destroy_all_io_queues(adapter);
+@@ -1919,6 +1921,9 @@ static int ena_close(struct net_device *
+
+ netif_dbg(adapter, ifdown, netdev, "%s\n", __func__);
+
++ if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
++ return 0;
++
+ if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
+ ena_down(adapter);
+
+@@ -2618,9 +2623,7 @@ static void ena_destroy_device(struct en
+ ena_down(adapter);
+
+ /* Stop the device from sending AENQ events (in case reset flag is set
+- * and device is up, ena_close already reset the device
+- * In case the reset flag is set and the device is up, ena_down()
+- * already perform the reset, so it can be skipped.
++ * and device is up, ena_down() already reset the device.
+ */
+ if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up))
+ ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason);
+@@ -3455,6 +3458,8 @@ err_rss:
+ ena_com_rss_destroy(ena_dev);
+ err_free_msix:
+ ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR);
++ /* stop submitting admin commands on a device that was reset */
++ ena_com_set_admin_running_state(ena_dev, false);
+ ena_free_mgmnt_irq(adapter);
+ ena_disable_msix(adapter);
+ err_worker_destroy:
+@@ -3504,18 +3509,12 @@ static void ena_remove(struct pci_dev *p
+ del_timer_sync(&adapter->timer_service);
+ cancel_work_sync(&adapter->reset_task);
+
+- unregister_netdev(netdev);
+-
+- /* If the device is running then we want to make sure the device will be
+- * reset to make sure no more events will be issued by the device.
+- */
+- if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags))
+- set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
+-
+ rtnl_lock();
+ ena_destroy_device(adapter, true);
+ rtnl_unlock();
+
++ unregister_netdev(netdev);
++
+ free_netdev(netdev);
+
+ ena_com_rss_destroy(ena_dev);
diff --git a/debian/patches/features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch b/debian/patches/features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch
new file mode 100644
index 000000000..68194bdc9
--- /dev/null
+++ b/debian/patches/features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch
@@ -0,0 +1,26 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 19 Nov 2018 12:05:22 +0200
+Subject: [PATCH 19/19] net: ena: update driver version from 2.0.1 to 2.0.2
+Origin: https://git.kernel.org/linus/4c23738a3f9f203a9b41c89e030eaa8ee241f90f
+
+Update driver version due to critical bug fixes.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -45,7 +45,7 @@
+
+ #define DRV_MODULE_VER_MAJOR 2
+ #define DRV_MODULE_VER_MINOR 0
+-#define DRV_MODULE_VER_SUBMINOR 1
++#define DRV_MODULE_VER_SUBMINOR 2
+
+ #define DRV_MODULE_NAME "ena"
+ #ifndef DRV_MODULE_VERSION
diff --git a/debian/patches/features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch b/debian/patches/features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch
new file mode 100644
index 000000000..d2e7da1ab
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch
@@ -0,0 +1,39 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Sun, 23 Jun 2019 10:11:10 +0300
+Subject: [PATCH] net: ena: Fix bug where ring allocation backoff stopped too
+ late
+Origin: https://git.kernel.org/linus/3e5bfb189e1a65df132fd0e3fa00fbb6feec1431
+Bug-Debian: https://bugs.debian.org/941291
+
+The current code of create_queues_with_size_backoff() allows the ring size
+to become as small as ENA_MIN_RING_SIZE/2. This is a bug since we don't
+want the queue ring to be smaller than ENA_MIN_RING_SIZE
+
+In this commit we change the loop's termination condition to look at the
+queue size of the next iteration instead of that of the current one,
+so that the minimal queue size again becomes ENA_MIN_RING_SIZE.
+
+Fixes: eece4d2ab9d2 ("net: ena: add ethtool function for changing io queue sizes")
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1836,8 +1836,8 @@ err_setup_tx:
+ if (cur_rx_ring_size >= cur_tx_ring_size)
+ new_rx_ring_size = cur_rx_ring_size / 2;
+
+- if (cur_tx_ring_size < ENA_MIN_RING_SIZE ||
+- cur_rx_ring_size < ENA_MIN_RING_SIZE) {
++ if (new_tx_ring_size < ENA_MIN_RING_SIZE ||
++ new_rx_ring_size < ENA_MIN_RING_SIZE) {
+ netif_err(adapter, ifup, adapter->netdev,
+ "Queue creation failed with the smallest possible queue size of %d for both queues. Not retrying with smaller queues\n",
+ ENA_MIN_RING_SIZE);
diff --git a/debian/patches/features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch b/debian/patches/features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch
new file mode 100644
index 000000000..bf790f061
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch
@@ -0,0 +1,345 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Tue, 11 Jun 2019 14:58:05 +0300
+Subject: [PATCH] net: ena: add MAX_QUEUES_EXT get feature admin command
+Origin: https://git.kernel.org/linus/ba8ef506fb91005fc4808370b7587ab7bf4bd918
+Bug-Debian: https://bugs.debian.org/941291
+
+Add a new admin command to support different queue size for Tx/Rx
+queues (the change also support different SQ/CQ sizes)
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/amazon/ena/ena_admin_defs.h | 56 +++++++++++++-
+ drivers/net/ethernet/amazon/ena/ena_com.c | 76 ++++++++++++-------
+ drivers/net/ethernet/amazon/ena/ena_com.h | 3 +
+ 3 files changed, 105 insertions(+), 30 deletions(-)
+
+--- a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
++++ b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+@@ -60,6 +60,7 @@ enum ena_admin_aq_feature_id {
+ ENA_ADMIN_MAX_QUEUES_NUM = 2,
+ ENA_ADMIN_HW_HINTS = 3,
+ ENA_ADMIN_LLQ = 4,
++ ENA_ADMIN_MAX_QUEUES_EXT = 7,
+ ENA_ADMIN_RSS_HASH_FUNCTION = 10,
+ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11,
+ ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12,
+@@ -421,7 +422,13 @@ struct ena_admin_get_set_feature_common_
+ /* as appears in ena_admin_aq_feature_id */
+ u8 feature_id;
+
+- u16 reserved16;
++ /* The driver specifies the max feature version it supports and the
++ * device responds with the currently supported feature version. The
++ * field is zero based
++ */
++ u8 feature_version;
++
++ u8 reserved8;
+ };
+
+ struct ena_admin_device_attr_feature_desc {
+@@ -531,6 +538,34 @@ struct ena_admin_feature_llq_desc {
+ u32 max_tx_burst_size;
+ };
+
++struct ena_admin_queue_ext_feature_fields {
++ u32 max_tx_sq_num;
++
++ u32 max_tx_cq_num;
++
++ u32 max_rx_sq_num;
++
++ u32 max_rx_cq_num;
++
++ u32 max_tx_sq_depth;
++
++ u32 max_tx_cq_depth;
++
++ u32 max_rx_sq_depth;
++
++ u32 max_rx_cq_depth;
++
++ u32 max_tx_header_size;
++
++ /* Maximum Descriptors number, including meta descriptor, allowed for
++ * a single Tx packet
++ */
++ u16 max_per_packet_tx_descs;
++
++ /* Maximum Descriptors number allowed for a single Rx packet */
++ u16 max_per_packet_rx_descs;
++};
++
+ struct ena_admin_queue_feature_desc {
+ u32 max_sq_num;
+
+@@ -837,6 +872,19 @@ struct ena_admin_get_feat_cmd {
+ u32 raw[11];
+ };
+
++struct ena_admin_queue_ext_feature_desc {
++ /* version */
++ u8 version;
++
++ u8 reserved1[3];
++
++ union {
++ struct ena_admin_queue_ext_feature_fields max_queue_ext;
++
++ u32 raw[10];
++ };
++};
++
+ struct ena_admin_get_feat_resp {
+ struct ena_admin_acq_common_desc acq_common_desc;
+
+@@ -849,6 +897,8 @@ struct ena_admin_get_feat_resp {
+
+ struct ena_admin_queue_feature_desc max_queue;
+
++ struct ena_admin_queue_ext_feature_desc max_queue_ext;
++
+ struct ena_admin_feature_aenq_desc aenq;
+
+ struct ena_admin_get_feature_link_desc link;
+@@ -913,7 +963,9 @@ struct ena_admin_aenq_common_desc {
+
+ u16 syndrom;
+
+- /* 0 : phase */
++ /* 0 : phase
++ * 7:1 : reserved - MBZ
++ */
+ u8 flags;
+
+ u8 reserved1[3];
+--- a/drivers/net/ethernet/amazon/ena/ena_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -983,7 +983,8 @@ static int ena_com_get_feature_ex(struct
+ struct ena_admin_get_feat_resp *get_resp,
+ enum ena_admin_aq_feature_id feature_id,
+ dma_addr_t control_buf_dma_addr,
+- u32 control_buff_size)
++ u32 control_buff_size,
++ u8 feature_ver)
+ {
+ struct ena_com_admin_queue *admin_queue;
+ struct ena_admin_get_feat_cmd get_cmd;
+@@ -1014,7 +1015,7 @@ static int ena_com_get_feature_ex(struct
+ }
+
+ get_cmd.control_buffer.length = control_buff_size;
+-
++ get_cmd.feat_common.feature_version = feature_ver;
+ get_cmd.feat_common.feature_id = feature_id;
+
+ ret = ena_com_execute_admin_command(admin_queue,
+@@ -1034,13 +1035,15 @@ static int ena_com_get_feature_ex(struct
+
+ static int ena_com_get_feature(struct ena_com_dev *ena_dev,
+ struct ena_admin_get_feat_resp *get_resp,
+- enum ena_admin_aq_feature_id feature_id)
++ enum ena_admin_aq_feature_id feature_id,
++ u8 feature_ver)
+ {
+ return ena_com_get_feature_ex(ena_dev,
+ get_resp,
+ feature_id,
+ 0,
+- 0);
++ 0,
++ feature_ver);
+ }
+
+ static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev)
+@@ -1118,7 +1121,7 @@ static int ena_com_indirect_table_alloca
+ int ret;
+
+ ret = ena_com_get_feature(ena_dev, &get_resp,
+- ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG);
++ ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG, 0);
+ if (unlikely(ret))
+ return ret;
+
+@@ -1538,7 +1541,7 @@ int ena_com_set_aenq_config(struct ena_c
+ struct ena_admin_get_feat_resp get_resp;
+ int ret;
+
+- ret = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_AENQ_CONFIG);
++ ret = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_AENQ_CONFIG, 0);
+ if (ret) {
+ pr_info("Can't get aenq configuration\n");
+ return ret;
+@@ -1913,7 +1916,7 @@ void ena_com_destroy_io_queue(struct ena
+ int ena_com_get_link_params(struct ena_com_dev *ena_dev,
+ struct ena_admin_get_feat_resp *resp)
+ {
+- return ena_com_get_feature(ena_dev, resp, ENA_ADMIN_LINK_CONFIG);
++ return ena_com_get_feature(ena_dev, resp, ENA_ADMIN_LINK_CONFIG, 0);
+ }
+
+ int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev,
+@@ -1923,7 +1926,7 @@ int ena_com_get_dev_attr_feat(struct ena
+ int rc;
+
+ rc = ena_com_get_feature(ena_dev, &get_resp,
+- ENA_ADMIN_DEVICE_ATTRIBUTES);
++ ENA_ADMIN_DEVICE_ATTRIBUTES, 0);
+ if (rc)
+ return rc;
+
+@@ -1931,17 +1934,34 @@ int ena_com_get_dev_attr_feat(struct ena
+ sizeof(get_resp.u.dev_attr));
+ ena_dev->supported_features = get_resp.u.dev_attr.supported_features;
+
+- rc = ena_com_get_feature(ena_dev, &get_resp,
+- ENA_ADMIN_MAX_QUEUES_NUM);
+- if (rc)
+- return rc;
++ if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) {
++ rc = ena_com_get_feature(ena_dev, &get_resp,
++ ENA_ADMIN_MAX_QUEUES_EXT,
++ ENA_FEATURE_MAX_QUEUE_EXT_VER);
++ if (rc)
++ return rc;
+
+- memcpy(&get_feat_ctx->max_queues, &get_resp.u.max_queue,
+- sizeof(get_resp.u.max_queue));
+- ena_dev->tx_max_header_size = get_resp.u.max_queue.max_header_size;
++ if (get_resp.u.max_queue_ext.version != ENA_FEATURE_MAX_QUEUE_EXT_VER)
++ return -EINVAL;
++
++ memcpy(&get_feat_ctx->max_queue_ext, &get_resp.u.max_queue_ext,
++ sizeof(get_resp.u.max_queue_ext));
++ ena_dev->tx_max_header_size =
++ get_resp.u.max_queue_ext.max_queue_ext.max_tx_header_size;
++ } else {
++ rc = ena_com_get_feature(ena_dev, &get_resp,
++ ENA_ADMIN_MAX_QUEUES_NUM, 0);
++ memcpy(&get_feat_ctx->max_queues, &get_resp.u.max_queue,
++ sizeof(get_resp.u.max_queue));
++ ena_dev->tx_max_header_size =
++ get_resp.u.max_queue.max_header_size;
++
++ if (rc)
++ return rc;
++ }
+
+ rc = ena_com_get_feature(ena_dev, &get_resp,
+- ENA_ADMIN_AENQ_CONFIG);
++ ENA_ADMIN_AENQ_CONFIG, 0);
+ if (rc)
+ return rc;
+
+@@ -1949,7 +1969,7 @@ int ena_com_get_dev_attr_feat(struct ena
+ sizeof(get_resp.u.aenq));
+
+ rc = ena_com_get_feature(ena_dev, &get_resp,
+- ENA_ADMIN_STATELESS_OFFLOAD_CONFIG);
++ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG, 0);
+ if (rc)
+ return rc;
+
+@@ -1959,7 +1979,7 @@ int ena_com_get_dev_attr_feat(struct ena
+ /* Driver hints isn't mandatory admin command. So in case the
+ * command isn't supported set driver hints to 0
+ */
+- rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS);
++ rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS, 0);
+
+ if (!rc)
+ memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints,
+@@ -1970,7 +1990,7 @@ int ena_com_get_dev_attr_feat(struct ena
+ else
+ return rc;
+
+- rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ);
++ rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ, 0);
+ if (!rc)
+ memcpy(&get_feat_ctx->llq, &get_resp.u.llq,
+ sizeof(get_resp.u.llq));
+@@ -2208,7 +2228,7 @@ int ena_com_get_offload_settings(struct
+ struct ena_admin_get_feat_resp resp;
+
+ ret = ena_com_get_feature(ena_dev, &resp,
+- ENA_ADMIN_STATELESS_OFFLOAD_CONFIG);
++ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG, 0);
+ if (unlikely(ret)) {
+ pr_err("Failed to get offload capabilities %d\n", ret);
+ return ret;
+@@ -2237,7 +2257,7 @@ int ena_com_set_hash_function(struct ena
+
+ /* Validate hash function is supported */
+ ret = ena_com_get_feature(ena_dev, &get_resp,
+- ENA_ADMIN_RSS_HASH_FUNCTION);
++ ENA_ADMIN_RSS_HASH_FUNCTION, 0);
+ if (unlikely(ret))
+ return ret;
+
+@@ -2297,7 +2317,7 @@ int ena_com_fill_hash_function(struct en
+ rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+ ENA_ADMIN_RSS_HASH_FUNCTION,
+ rss->hash_key_dma_addr,
+- sizeof(*rss->hash_key));
++ sizeof(*rss->hash_key), 0);
+ if (unlikely(rc))
+ return rc;
+
+@@ -2350,7 +2370,7 @@ int ena_com_get_hash_function(struct ena
+ rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+ ENA_ADMIN_RSS_HASH_FUNCTION,
+ rss->hash_key_dma_addr,
+- sizeof(*rss->hash_key));
++ sizeof(*rss->hash_key), 0);
+ if (unlikely(rc))
+ return rc;
+
+@@ -2379,7 +2399,7 @@ int ena_com_get_hash_ctrl(struct ena_com
+ rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+ ENA_ADMIN_RSS_HASH_INPUT,
+ rss->hash_ctrl_dma_addr,
+- sizeof(*rss->hash_ctrl));
++ sizeof(*rss->hash_ctrl), 0);
+ if (unlikely(rc))
+ return rc;
+
+@@ -2615,7 +2635,7 @@ int ena_com_indirect_table_get(struct en
+ rc = ena_com_get_feature_ex(ena_dev, &get_resp,
+ ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG,
+ rss->rss_ind_tbl_dma_addr,
+- tbl_size);
++ tbl_size, 0);
+ if (unlikely(rc))
+ return rc;
+
+@@ -2831,7 +2851,7 @@ int ena_com_init_interrupt_moderation(st
+ int rc;
+
+ rc = ena_com_get_feature(ena_dev, &get_resp,
+- ENA_ADMIN_INTERRUPT_MODERATION);
++ ENA_ADMIN_INTERRUPT_MODERATION, 0);
+
+ if (rc) {
+ if (rc == -EOPNOTSUPP) {
+--- a/drivers/net/ethernet/amazon/ena/ena_com.h
++++ b/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -102,6 +102,8 @@
+
+ #define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF
+
++#define ENA_FEATURE_MAX_QUEUE_EXT_VER 1
++
+ enum ena_intr_moder_level {
+ ENA_INTR_MODER_LOWEST = 0,
+ ENA_INTR_MODER_LOW,
+@@ -383,6 +385,7 @@ struct ena_com_dev {
+
+ struct ena_com_dev_get_features_ctx {
+ struct ena_admin_queue_feature_desc max_queues;
++ struct ena_admin_queue_ext_feature_desc max_queue_ext;
+ struct ena_admin_device_attr_feature_desc dev_attr;
+ struct ena_admin_feature_aenq_desc aenq;
+ struct ena_admin_feature_offload_desc offload;
diff --git a/debian/patches/features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch b/debian/patches/features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch
new file mode 100644
index 000000000..227f39b3b
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch
@@ -0,0 +1,106 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Tue, 11 Jun 2019 14:58:09 +0300
+Subject: [PATCH] net: ena: add ethtool function for changing io queue sizes
+Origin: https://git.kernel.org/linus/eece4d2ab9d214e3b12f5ac1ed189a05793b28a5
+Bug-Debian: https://bugs.debian.org/941291
+
+Implement the set_ringparam() function of the ethtool interface
+to enable the changing of io queue sizes.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 22 +++++++++++++++++++
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 14 ++++++++++++
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 5 ++++-
+ 3 files changed, 40 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -454,6 +454,27 @@ static void ena_get_ringparam(struct net
+ ring->rx_pending = adapter->rx_ring[0].ring_size;
+ }
+
++static int ena_set_ringparam(struct net_device *netdev,
++ struct ethtool_ringparam *ring)
++{
++ struct ena_adapter *adapter = netdev_priv(netdev);
++ u32 new_tx_size, new_rx_size;
++
++ new_tx_size = ring->tx_pending < ENA_MIN_RING_SIZE ?
++ ENA_MIN_RING_SIZE : ring->tx_pending;
++ new_tx_size = rounddown_pow_of_two(new_tx_size);
++
++ new_rx_size = ring->rx_pending < ENA_MIN_RING_SIZE ?
++ ENA_MIN_RING_SIZE : ring->rx_pending;
++ new_rx_size = rounddown_pow_of_two(new_rx_size);
++
++ if (new_tx_size == adapter->requested_tx_ring_size &&
++ new_rx_size == adapter->requested_rx_ring_size)
++ return 0;
++
++ return ena_update_queue_sizes(adapter, new_tx_size, new_rx_size);
++}
++
+ static u32 ena_flow_hash_to_flow_type(u16 hash_fields)
+ {
+ u32 data = 0;
+@@ -805,6 +826,7 @@ static const struct ethtool_ops ena_etht
+ .get_coalesce = ena_get_coalesce,
+ .set_coalesce = ena_set_coalesce,
+ .get_ringparam = ena_get_ringparam,
++ .set_ringparam = ena_set_ringparam,
+ .get_sset_count = ena_get_sset_count,
+ .get_strings = ena_get_strings,
+ .get_ethtool_stats = ena_get_ethtool_stats,
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2028,6 +2028,20 @@ static int ena_close(struct net_device *
+ return 0;
+ }
+
++int ena_update_queue_sizes(struct ena_adapter *adapter,
++ u32 new_tx_size,
++ u32 new_rx_size)
++{
++ bool dev_up;
++
++ dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
++ ena_close(adapter->netdev);
++ adapter->requested_tx_ring_size = new_tx_size;
++ adapter->requested_rx_ring_size = new_rx_size;
++ ena_init_io_rings(adapter);
++ return dev_up ? ena_up(adapter) : 0;
++}
++
+ static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb)
+ {
+ u32 mss = skb_shinfo(skb)->gso_size;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -81,7 +81,6 @@
+ #define ENA_DEFAULT_RING_SIZE (1024)
+ #define ENA_MIN_RING_SIZE (256)
+
+-
+ #define ENA_TX_WAKEUP_THRESH (MAX_SKB_FRAGS + 2)
+ #define ENA_DEFAULT_RX_COPYBREAK (256 - NET_IP_ALIGN)
+
+@@ -386,6 +385,10 @@ void ena_dump_stats_to_dmesg(struct ena_
+
+ void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf);
+
++int ena_update_queue_sizes(struct ena_adapter *adapter,
++ u32 new_tx_size,
++ u32 new_rx_size);
++
+ int ena_get_sset_count(struct net_device *netdev, int sset);
+
+ #endif /* !(ENA_H) */
diff --git a/debian/patches/features/all/ena/net-ena-add-good-checksum-counter.patch b/debian/patches/features/all/ena/net-ena-add-good-checksum-counter.patch
new file mode 100644
index 000000000..cde5cdad4
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-add-good-checksum-counter.patch
@@ -0,0 +1,72 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:28 +0300
+Subject: [PATCH] net: ena: add good checksum counter
+Origin: https://git.kernel.org/linus/d2eecc6ee8c92053797513e34931334dd0e85e18
+Bug-Debian: https://bugs.debian.org/941291
+
+Add a new statistics to ETHTOOL to specify if the device calculated
+and validated the Rx csum.
+
+Signed-off-by: Evgeny Shmeilin <evgeny@annapurnaLabs.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 3 ++-
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 +++
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 3 ++-
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -88,13 +88,14 @@ static const struct ena_stats ena_stats_
+ static const struct ena_stats ena_stats_rx_strings[] = {
+ ENA_STAT_RX_ENTRY(cnt),
+ ENA_STAT_RX_ENTRY(bytes),
++ ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
++ ENA_STAT_RX_ENTRY(csum_good),
+ ENA_STAT_RX_ENTRY(refil_partial),
+ ENA_STAT_RX_ENTRY(bad_csum),
+ ENA_STAT_RX_ENTRY(page_alloc_fail),
+ ENA_STAT_RX_ENTRY(skb_alloc_fail),
+ ENA_STAT_RX_ENTRY(dma_mapping_err),
+ ENA_STAT_RX_ENTRY(bad_desc_num),
+- ENA_STAT_RX_ENTRY(rx_copybreak_pkt),
+ ENA_STAT_RX_ENTRY(bad_req_id),
+ ENA_STAT_RX_ENTRY(empty_rx_ring),
+ ENA_STAT_RX_ENTRY(csum_unchecked),
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1001,6 +1001,9 @@ static inline void ena_rx_checksum(struc
+
+ if (likely(ena_rx_ctx->l4_csum_checked)) {
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
++ u64_stats_update_begin(&rx_ring->syncp);
++ rx_ring->rx_stats.csum_good++;
++ u64_stats_update_end(&rx_ring->syncp);
+ } else {
+ u64_stats_update_begin(&rx_ring->syncp);
+ rx_ring->rx_stats.csum_unchecked++;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -221,13 +221,14 @@ struct ena_stats_tx {
+ struct ena_stats_rx {
+ u64 cnt;
+ u64 bytes;
++ u64 rx_copybreak_pkt;
++ u64 csum_good;
+ u64 refil_partial;
+ u64 bad_csum;
+ u64 page_alloc_fail;
+ u64 skb_alloc_fail;
+ u64 dma_mapping_err;
+ u64 bad_desc_num;
+- u64 rx_copybreak_pkt;
+ u64 bad_req_id;
+ u64 empty_rx_ring;
+ u64 csum_unchecked;
diff --git a/debian/patches/features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch b/debian/patches/features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch
new file mode 100644
index 000000000..4034439eb
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch
@@ -0,0 +1,232 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:19 +0300
+Subject: [PATCH] net: ena: add handling of llq max tx burst size
+Origin: https://git.kernel.org/linus/05d62ca218f8425c70389d0416c15bd0d455b416
+Bug-Debian: https://bugs.debian.org/941291
+
+There is a maximum TX burst size that the ENA device can handle.
+It is exposed by the device to the driver and the driver
+needs to comply with it to avoid bugs.
+
+In this commit we:
+1. Add ena_com_is_doorbell_needed(), which calculates the number of
+ llq entries that will be used to hold a packet, and will return
+ true if they exceed the number of allowed entries in a burst.
+ If the function returns true, a doorbell needs to be invoked
+ to send this packet in the next burst.
+
+2. Follow the available entries in the current burst:
+ - Every doorbell a new burst begins
+ - With each write of an llq entry, the available entries in the
+ current burst are decreased by 1.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ .../net/ethernet/amazon/ena/ena_admin_defs.h | 5 ++
+ drivers/net/ethernet/amazon/ena/ena_com.c | 7 +++
+ drivers/net/ethernet/amazon/ena/ena_com.h | 2 +
+ drivers/net/ethernet/amazon/ena/ena_eth_com.c | 28 ++++------
+ drivers/net/ethernet/amazon/ena/ena_eth_com.h | 53 +++++++++++++++++++
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 7 +++
+ 6 files changed, 85 insertions(+), 17 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+@@ -524,6 +524,11 @@ struct ena_admin_feature_llq_desc {
+
+ /* the stride control the driver selected to use */
+ u16 descriptors_stride_ctrl_enabled;
++
++ /* Maximum size in bytes taken by llq entries in a single tx burst.
++ * Set to 0 when there is no such limit.
++ */
++ u32 max_tx_burst_size;
+ };
+
+ struct ena_admin_queue_feature_desc {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -396,6 +396,10 @@ static int ena_com_init_io_sq(struct ena
+ 0x0, io_sq->llq_info.desc_list_entry_size);
+ io_sq->llq_buf_ctrl.descs_left_in_line =
+ io_sq->llq_info.descs_num_before_header;
++
++ if (io_sq->llq_info.max_entries_in_tx_burst > 0)
++ io_sq->entries_in_tx_burst_left =
++ io_sq->llq_info.max_entries_in_tx_burst;
+ }
+
+ io_sq->tail = 0;
+@@ -727,6 +731,9 @@ static int ena_com_config_llq_info(struc
+ supported_feat, llq_info->descs_num_before_header);
+ }
+
++ llq_info->max_entries_in_tx_burst =
++ (u16)(llq_features->max_tx_burst_size / llq_default_cfg->llq_ring_entry_size_value);
++
+ rc = ena_com_set_llq(ena_dev);
+ if (rc)
+ pr_err("Cannot set LLQ configuration: %d\n", rc);
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -159,6 +159,7 @@ struct ena_com_llq_info {
+ u16 desc_list_entry_size;
+ u16 descs_num_before_header;
+ u16 descs_per_entry;
++ u16 max_entries_in_tx_burst;
+ };
+
+ struct ena_com_io_cq {
+@@ -238,6 +239,7 @@ struct ena_com_io_sq {
+ u8 phase;
+ u8 desc_entry_size;
+ u8 dma_addr_bits;
++ u16 entries_in_tx_burst_left;
+ } ____cacheline_aligned;
+
+ struct ena_com_admin_cq {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+@@ -82,6 +82,17 @@ static inline int ena_com_write_bounce_b
+ dst_tail_mask = io_sq->tail & (io_sq->q_depth - 1);
+ dst_offset = dst_tail_mask * llq_info->desc_list_entry_size;
+
++ if (is_llq_max_tx_burst_exists(io_sq)) {
++ if (unlikely(!io_sq->entries_in_tx_burst_left)) {
++ pr_err("Error: trying to send more packets than tx burst allows\n");
++ return -ENOSPC;
++ }
++
++ io_sq->entries_in_tx_burst_left--;
++ pr_debug("decreasing entries_in_tx_burst_left of queue %d to %d\n",
++ io_sq->qid, io_sq->entries_in_tx_burst_left);
++ }
++
+ /* Make sure everything was written into the bounce buffer before
+ * writing the bounce buffer to the device
+ */
+@@ -274,23 +285,6 @@ static inline u16 ena_com_cdesc_rx_pkt_g
+ return count;
+ }
+
+-static inline bool ena_com_meta_desc_changed(struct ena_com_io_sq *io_sq,
+- struct ena_com_tx_ctx *ena_tx_ctx)
+-{
+- int rc;
+-
+- if (ena_tx_ctx->meta_valid) {
+- rc = memcmp(&io_sq->cached_tx_meta,
+- &ena_tx_ctx->ena_meta,
+- sizeof(struct ena_com_tx_meta));
+-
+- if (unlikely(rc != 0))
+- return true;
+- }
+-
+- return false;
+-}
+-
+ static inline int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
+ struct ena_com_tx_ctx *ena_tx_ctx)
+ {
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+@@ -125,8 +125,55 @@ static inline bool ena_com_sq_have_enoug
+ return ena_com_free_desc(io_sq) > temp;
+ }
+
++static inline bool ena_com_meta_desc_changed(struct ena_com_io_sq *io_sq,
++ struct ena_com_tx_ctx *ena_tx_ctx)
++{
++ if (!ena_tx_ctx->meta_valid)
++ return false;
++
++ return !!memcmp(&io_sq->cached_tx_meta,
++ &ena_tx_ctx->ena_meta,
++ sizeof(struct ena_com_tx_meta));
++}
++
++static inline bool is_llq_max_tx_burst_exists(struct ena_com_io_sq *io_sq)
++{
++ return (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) &&
++ io_sq->llq_info.max_entries_in_tx_burst > 0;
++}
++
++static inline bool ena_com_is_doorbell_needed(struct ena_com_io_sq *io_sq,
++ struct ena_com_tx_ctx *ena_tx_ctx)
++{
++ struct ena_com_llq_info *llq_info;
++ int descs_after_first_entry;
++ int num_entries_needed = 1;
++ u16 num_descs;
++
++ if (!is_llq_max_tx_burst_exists(io_sq))
++ return false;
++
++ llq_info = &io_sq->llq_info;
++ num_descs = ena_tx_ctx->num_bufs;
++
++ if (unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx)))
++ ++num_descs;
++
++ if (num_descs > llq_info->descs_num_before_header) {
++ descs_after_first_entry = num_descs - llq_info->descs_num_before_header;
++ num_entries_needed += DIV_ROUND_UP(descs_after_first_entry,
++ llq_info->descs_per_entry);
++ }
++
++ pr_debug("queue: %d num_descs: %d num_entries_needed: %d\n", io_sq->qid,
++ num_descs, num_entries_needed);
++
++ return num_entries_needed > io_sq->entries_in_tx_burst_left;
++}
++
+ static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq)
+ {
++ u16 max_entries_in_tx_burst = io_sq->llq_info.max_entries_in_tx_burst;
+ u16 tail = io_sq->tail;
+
+ pr_debug("write submission queue doorbell for queue: %d tail: %d\n",
+@@ -134,6 +181,12 @@ static inline int ena_com_write_sq_doorb
+
+ writel(tail, io_sq->db_addr);
+
++ if (is_llq_max_tx_burst_exists(io_sq)) {
++ pr_debug("reset available entries in tx burst for queue %d to %d\n",
++ io_sq->qid, max_entries_in_tx_burst);
++ io_sq->entries_in_tx_burst_left = max_entries_in_tx_burst;
++ }
++
+ return 0;
+ }
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2172,6 +2172,13 @@ static netdev_tx_t ena_start_xmit(struct
+ /* set flags and meta data */
+ ena_tx_csum(&ena_tx_ctx, skb);
+
++ if (unlikely(ena_com_is_doorbell_needed(tx_ring->ena_com_io_sq, &ena_tx_ctx))) {
++ netif_dbg(adapter, tx_queued, dev,
++ "llq tx max burst size of queue %d achieved, writing doorbell to send burst\n",
++ qid);
++ ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq);
++ }
++
+ /* prepare the packet's descriptors to dma engine */
+ rc = ena_com_prepare_tx(tx_ring->ena_com_io_sq, &ena_tx_ctx,
+ &nb_hw_desc);
diff --git a/debian/patches/features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch b/debian/patches/features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch
new file mode 100644
index 000000000..086da850a
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch
@@ -0,0 +1,118 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:26 +0300
+Subject: [PATCH] net: ena: add intr_moder_rx_interval to struct ena_com_dev
+ and use it
+Origin: https://git.kernel.org/linus/15619e722b16aaa40f942b93631aa92581a7b393
+Bug-Debian: https://bugs.debian.org/941291
+
+Add intr_moder_rx_interval to struct ena_com_dev and use it as the
+location where the interrupt moderation rx interval is saved, instead
+of the interrupt moderation table.
+
+This is done as a first step before removing the old interrupt moderation
+code.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 20 ++++----------------
+ drivers/net/ethernet/amazon/ena/ena_com.h | 8 +++++++-
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 ++-
+ 3 files changed, 13 insertions(+), 18 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -1297,9 +1297,6 @@ static int ena_com_init_interrupt_modera
+ static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev,
+ u16 intr_delay_resolution)
+ {
+- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+- unsigned int i;
+-
+ if (!intr_delay_resolution) {
+ pr_err("Illegal intr_delay_resolution provided. Going to use default 1 usec resolution\n");
+ intr_delay_resolution = 1;
+@@ -1307,8 +1304,7 @@ static void ena_com_update_intr_delay_re
+ ena_dev->intr_delay_resolution = intr_delay_resolution;
+
+ /* update Rx */
+- for (i = 0; i < ENA_INTR_MAX_NUM_OF_LEVELS; i++)
+- intr_moder_tbl[i].intr_moder_interval /= intr_delay_resolution;
++ ena_dev->intr_moder_rx_interval /= intr_delay_resolution;
+
+ /* update Tx */
+ ena_dev->intr_moder_tx_interval /= intr_delay_resolution;
+@@ -2798,11 +2794,8 @@ int ena_com_update_nonadaptive_moderatio
+ return -EFAULT;
+ }
+
+- /* We use LOWEST entry of moderation table for storing
+- * nonadaptive interrupt coalescing values
+- */
+- ena_dev->intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval =
+- rx_coalesce_usecs / ena_dev->intr_delay_resolution;
++ ena_dev->intr_moder_rx_interval = rx_coalesce_usecs /
++ ena_dev->intr_delay_resolution;
+
+ return 0;
+ }
+@@ -2907,12 +2900,7 @@ unsigned int ena_com_get_nonadaptive_mod
+
+ unsigned int ena_com_get_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev)
+ {
+- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+-
+- if (intr_moder_tbl)
+- return intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval;
+-
+- return 0;
++ return ena_dev->intr_moder_rx_interval;
+ }
+
+ void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev,
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -93,7 +93,7 @@
+ #define ENA_INTR_HIGHEST_BYTES (192 * 1024)
+
+ #define ENA_INTR_INITIAL_TX_INTERVAL_USECS 196
+-#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 4
++#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0
+ #define ENA_INTR_DELAY_OLD_VALUE_WEIGHT 6
+ #define ENA_INTR_DELAY_NEW_VALUE_WEIGHT 4
+ #define ENA_INTR_MODER_LEVEL_STRIDE 2
+@@ -376,7 +376,13 @@ struct ena_com_dev {
+ struct ena_host_attribute host_attr;
+ bool adaptive_coalescing;
+ u16 intr_delay_resolution;
++
++ /* interrupt moderation intervals are in usec divided by
++ * intr_delay_resolution, which is supplied by the device.
++ */
+ u32 intr_moder_tx_interval;
++ u32 intr_moder_rx_interval;
++
+ struct ena_intr_moder_entry *intr_moder_tbl;
+
+ struct ena_com_llq_info llq_info;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -3487,10 +3487,11 @@ static int ena_probe(struct pci_dev *pde
+ calc_queue_ctx.get_feat_ctx = &get_feat_ctx;
+ calc_queue_ctx.pdev = pdev;
+
+- /* initial Tx interrupt delay, Assumes 1 usec granularity.
++ /* Initial Tx and RX interrupt delay. Assumes 1 usec granularity.
+ * Updated during device initialization with the real granularity
+ */
+ ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS;
++ ena_dev->intr_moder_rx_interval = ENA_INTR_INITIAL_RX_INTERVAL_USECS;
+ io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx);
+ rc = ena_calc_queue_size(&calc_queue_ctx);
+ if (rc || io_queue_num <= 0) {
diff --git a/debian/patches/features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch b/debian/patches/features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch
new file mode 100644
index 000000000..3b1c6c4cb
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch
@@ -0,0 +1,91 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:23 +0300
+Subject: [PATCH] net: ena: add newline at the end of pr_err prints
+Origin: https://git.kernel.org/linus/9cb9c0de266f1ea52f01589f2f4019f163c01cd1
+Bug-Debian: https://bugs.debian.org/941291
+
+Some pr_err prints lacked '\n' in the end. Added where missing.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -115,7 +115,7 @@ static int ena_com_admin_init_sq(struct
+ GFP_KERNEL);
+
+ if (!sq->entries) {
+- pr_err("memory allocation failed");
++ pr_err("memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+@@ -137,7 +137,7 @@ static int ena_com_admin_init_cq(struct
+ GFP_KERNEL);
+
+ if (!cq->entries) {
+- pr_err("memory allocation failed");
++ pr_err("memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+@@ -160,7 +160,7 @@ static int ena_com_admin_init_aenq(struc
+ GFP_KERNEL);
+
+ if (!aenq->entries) {
+- pr_err("memory allocation failed");
++ pr_err("memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+@@ -285,7 +285,7 @@ static inline int ena_com_init_comp_ctxt
+
+ queue->comp_ctx = devm_kzalloc(queue->q_dmadev, size, GFP_KERNEL);
+ if (unlikely(!queue->comp_ctx)) {
+- pr_err("memory allocation failed");
++ pr_err("memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+@@ -356,7 +356,7 @@ static int ena_com_init_io_sq(struct ena
+ }
+
+ if (!io_sq->desc_addr.virt_addr) {
+- pr_err("memory allocation failed");
++ pr_err("memory allocation failed\n");
+ return -ENOMEM;
+ }
+ }
+@@ -382,7 +382,7 @@ static int ena_com_init_io_sq(struct ena
+ devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
+
+ if (!io_sq->bounce_buf_ctrl.base_buffer) {
+- pr_err("bounce buffer memory allocation failed");
++ pr_err("bounce buffer memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+@@ -440,7 +440,7 @@ static int ena_com_init_io_cq(struct ena
+ }
+
+ if (!io_cq->cdesc_addr.virt_addr) {
+- pr_err("memory allocation failed");
++ pr_err("memory allocation failed\n");
+ return -ENOMEM;
+ }
+
+@@ -829,7 +829,7 @@ static u32 ena_com_reg_bar_read32(struct
+ }
+
+ if (read_resp->reg_off != offset) {
+- pr_err("Read failure: wrong offset provided");
++ pr_err("Read failure: wrong offset provided\n");
+ ret = ENA_MMIO_READ_TIMEOUT;
+ } else {
+ ret = read_resp->reg_val;
diff --git a/debian/patches/features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch b/debian/patches/features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch
new file mode 100644
index 000000000..ac5bc89e7
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch
@@ -0,0 +1,54 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:26 +0300
+Subject: [PATCH] net: ena: add support for changing max_header_size in LLQ
+ mode
+Origin: https://git.kernel.org/linus/cdf449eccc5946d5dd4145b38347874a7423c50d
+Bug-Debian: https://bugs.debian.org/941291
+
+Up until now the driver always used a single setting for the sizes
+of the different parts of the llq entry - 128 for entry size, 2 for
+descriptors before header and 96 for maximum header size.
+
+The current code makes sure that the parts of the llq entry are
+compatible with each other and with the initial llq entry size given
+by the device.
+
+This commit changes this code to support any llq entry size
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -2936,8 +2936,8 @@ int ena_com_config_dev_mode(struct ena_c
+ struct ena_admin_feature_llq_desc *llq_features,
+ struct ena_llq_configurations *llq_default_cfg)
+ {
++ struct ena_com_llq_info *llq_info = &ena_dev->llq_info;
+ int rc;
+- int size;
+
+ if (!llq_features->max_llq_num) {
+ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+@@ -2948,12 +2948,10 @@ int ena_com_config_dev_mode(struct ena_c
+ if (rc)
+ return rc;
+
+- /* Validate the descriptor is not too big */
+- size = ena_dev->tx_max_header_size;
+- size += ena_dev->llq_info.descs_num_before_header *
+- sizeof(struct ena_eth_io_tx_desc);
++ ena_dev->tx_max_header_size = llq_info->desc_list_entry_size -
++ (llq_info->descs_num_before_header * sizeof(struct ena_eth_io_tx_desc));
+
+- if (unlikely(ena_dev->llq_info.desc_list_entry_size < size)) {
++ if (unlikely(ena_dev->tx_max_header_size == 0)) {
+ pr_err("the size of the LLQ entry is smaller than needed\n");
+ return -EINVAL;
+ }
diff --git a/debian/patches/features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch b/debian/patches/features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch
new file mode 100644
index 000000000..dab6166e1
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch
@@ -0,0 +1,103 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:25 +0300
+Subject: [PATCH] net: ena: allow automatic fallback to polling mode
+Origin: https://git.kernel.org/linus/a4e262cde3cda4491ce666e7c5270954c4d926b9
+Bug-Debian: https://bugs.debian.org/941291
+
+Enable fallback to polling mode for Admin queue
+when identified a command response arrival
+without an accompanying MSI-X interrupt
+
+Signed-off-by: Igor Chauskin <igorch@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 34 +++++++++++++++++------
+ drivers/net/ethernet/amazon/ena/ena_com.h | 14 ++++++++++
+ 2 files changed, 39 insertions(+), 9 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -762,16 +762,26 @@ static int ena_com_wait_and_process_admi
+ admin_queue->stats.no_completion++;
+ spin_unlock_irqrestore(&admin_queue->q_lock, flags);
+
+- if (comp_ctx->status == ENA_CMD_COMPLETED)
+- pr_err("The ena device have completion but the driver didn't receive any MSI-X interrupt (cmd %d)\n",
+- comp_ctx->cmd_opcode);
+- else
+- pr_err("The ena device doesn't send any completion for the admin cmd %d status %d\n",
++ if (comp_ctx->status == ENA_CMD_COMPLETED) {
++ pr_err("The ena device sent a completion but the driver didn't receive a MSI-X interrupt (cmd %d), autopolling mode is %s\n",
++ comp_ctx->cmd_opcode,
++ admin_queue->auto_polling ? "ON" : "OFF");
++ /* Check if fallback to polling is enabled */
++ if (admin_queue->auto_polling)
++ admin_queue->polling = true;
++ } else {
++ pr_err("The ena device doesn't send a completion for the admin cmd %d status %d\n",
+ comp_ctx->cmd_opcode, comp_ctx->status);
+-
+- admin_queue->running_state = false;
+- ret = -ETIME;
+- goto err;
++ }
++ /* Check if shifted to polling mode.
++ * This will happen if there is a completion without an interrupt
++ * and autopolling mode is enabled. Continuing normal execution in such case
++ */
++ if (!admin_queue->polling) {
++ admin_queue->running_state = false;
++ ret = -ETIME;
++ goto err;
++ }
+ }
+
+ ret = ena_com_comp_status_to_errno(comp_ctx->comp_status);
+@@ -1650,6 +1660,12 @@ void ena_com_set_admin_polling_mode(stru
+ ena_dev->admin_queue.polling = polling;
+ }
+
++void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev,
++ bool polling)
++{
++ ena_dev->admin_queue.auto_polling = polling;
++}
++
+ int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev)
+ {
+ struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -283,6 +283,9 @@ struct ena_com_admin_queue {
+ /* Indicate if the admin queue should poll for completion */
+ bool polling;
+
++ /* Define if fallback to polling mode should occur */
++ bool auto_polling;
++
+ u16 curr_cmd_id;
+
+ /* Indicate that the ena was initialized and can
+@@ -538,6 +541,17 @@ void ena_com_set_admin_polling_mode(stru
+ */
+ bool ena_com_get_ena_admin_polling_mode(struct ena_com_dev *ena_dev);
+
++/* ena_com_set_admin_auto_polling_mode - Enable autoswitch to polling mode
++ * @ena_dev: ENA communication layer struct
++ * @polling: Enable/Disable polling mode
++ *
++ * Set the autopolling mode.
++ * If autopolling is on:
++ * In case of missing interrupt when data is available switch to polling.
++ */
++void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev,
++ bool polling);
++
+ /* ena_com_admin_q_comp_intr_handler - admin queue interrupt handler
+ * @ena_dev: ENA communication layer struct
+ *
diff --git a/debian/patches/features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch b/debian/patches/features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch
new file mode 100644
index 000000000..6f902b864
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch
@@ -0,0 +1,323 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Tue, 11 Jun 2019 14:58:08 +0300
+Subject: [PATCH] net: ena: allow queue allocation backoff when low on memory
+Origin: https://git.kernel.org/linus/13ca32a69e29f3a0fe72094dd930f312b3f3ee44
+Bug-Debian: https://bugs.debian.org/941291
+
+If there is not enough memory to allocate io queues the driver will
+try to allocate smaller queues.
+
+The backoff algorithm is as follows:
+
+1. Try to allocate TX and RX and if successful.
+1.1. return success
+
+2. Divide by 2 the size of the larger of RX and TX queues (or both if their size is the same).
+
+3. If TX or RX is smaller than 256
+3.1. return failure.
+4. else
+4.1. go back to 1.
+
+Also change the tx_queue_size, rx_queue_size field names in struct
+adapter to requested_tx_queue_size and requested_rx_queue_size, and
+use RX and TX queue 0 for actual queue sizes.
+Explanation:
+The original fields were useless as they were simply used to assign
+values once from them to each of the queues in the adapter in ena_probe().
+They could simply be deleted. However now that we have a backoff
+feature, we have use for them. In case of backoff there is a difference
+between the requested queue sizes and the actual sizes. Therefore there
+is a need to save the requested queue size for future retries of queue
+allocation (for example if allocation failed and then ifdown + ifup was
+called we want to start the allocation from the original requested size of
+the queues).
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 +-
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 159 +++++++++++++-----
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 +-
+ 3 files changed, 127 insertions(+), 42 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -450,8 +450,8 @@ static void ena_get_ringparam(struct net
+
+ ring->tx_max_pending = adapter->max_tx_ring_size;
+ ring->rx_max_pending = adapter->max_rx_ring_size;
+- ring->tx_pending = adapter->tx_ring_size;
+- ring->rx_pending = adapter->rx_ring_size;
++ ring->tx_pending = adapter->tx_ring[0].ring_size;
++ ring->rx_pending = adapter->rx_ring[0].ring_size;
+ }
+
+ static u32 ena_flow_hash_to_flow_type(u16 hash_fields)
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -182,7 +182,7 @@ static void ena_init_io_rings(struct ena
+ ena_init_io_rings_common(adapter, rxr, i);
+
+ /* TX specific ring state */
+- txr->ring_size = adapter->tx_ring_size;
++ txr->ring_size = adapter->requested_tx_ring_size;
+ txr->tx_max_header_size = ena_dev->tx_max_header_size;
+ txr->tx_mem_queue_type = ena_dev->tx_mem_queue_type;
+ txr->sgl_size = adapter->max_tx_sgl_size;
+@@ -190,7 +190,7 @@ static void ena_init_io_rings(struct ena
+ ena_com_get_nonadaptive_moderation_interval_tx(ena_dev);
+
+ /* RX specific ring state */
+- rxr->ring_size = adapter->rx_ring_size;
++ rxr->ring_size = adapter->requested_rx_ring_size;
+ rxr->rx_copybreak = adapter->rx_copybreak;
+ rxr->sgl_size = adapter->max_rx_sgl_size;
+ rxr->smoothed_interval =
+@@ -594,7 +594,6 @@ static void ena_free_rx_bufs(struct ena_
+
+ /* ena_refill_all_rx_bufs - allocate all queues Rx buffers
+ * @adapter: board private structure
+- *
+ */
+ static void ena_refill_all_rx_bufs(struct ena_adapter *adapter)
+ {
+@@ -1635,7 +1634,7 @@ static int ena_create_io_tx_queue(struct
+ ctx.qid = ena_qid;
+ ctx.mem_queue_type = ena_dev->tx_mem_queue_type;
+ ctx.msix_vector = msix_vector;
+- ctx.queue_size = adapter->tx_ring_size;
++ ctx.queue_size = tx_ring->ring_size;
+ ctx.numa_node = cpu_to_node(tx_ring->cpu);
+
+ rc = ena_com_create_io_queue(ena_dev, &ctx);
+@@ -1702,7 +1701,7 @@ static int ena_create_io_rx_queue(struct
+ ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX;
+ ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST;
+ ctx.msix_vector = msix_vector;
+- ctx.queue_size = adapter->rx_ring_size;
++ ctx.queue_size = rx_ring->ring_size;
+ ctx.numa_node = cpu_to_node(rx_ring->cpu);
+
+ rc = ena_com_create_io_queue(ena_dev, &ctx);
+@@ -1749,6 +1748,112 @@ create_err:
+ return rc;
+ }
+
++static void set_io_rings_size(struct ena_adapter *adapter,
++ int new_tx_size, int new_rx_size)
++{
++ int i;
++
++ for (i = 0; i < adapter->num_queues; i++) {
++ adapter->tx_ring[i].ring_size = new_tx_size;
++ adapter->rx_ring[i].ring_size = new_rx_size;
++ }
++}
++
++/* This function allows queue allocation to backoff when the system is
++ * low on memory. If there is not enough memory to allocate io queues
++ * the driver will try to allocate smaller queues.
++ *
++ * The backoff algorithm is as follows:
++ * 1. Try to allocate TX and RX and if successful.
++ * 1.1. return success
++ *
++ * 2. Divide by 2 the size of the larger of RX and TX queues (or both if their size is the same).
++ *
++ * 3. If TX or RX is smaller than 256
++ * 3.1. return failure.
++ * 4. else
++ * 4.1. go back to 1.
++ */
++static int create_queues_with_size_backoff(struct ena_adapter *adapter)
++{
++ int rc, cur_rx_ring_size, cur_tx_ring_size;
++ int new_rx_ring_size, new_tx_ring_size;
++
++ /* current queue sizes might be set to smaller than the requested
++ * ones due to past queue allocation failures.
++ */
++ set_io_rings_size(adapter, adapter->requested_tx_ring_size,
++ adapter->requested_rx_ring_size);
++
++ while (1) {
++ rc = ena_setup_all_tx_resources(adapter);
++ if (rc)
++ goto err_setup_tx;
++
++ rc = ena_create_all_io_tx_queues(adapter);
++ if (rc)
++ goto err_create_tx_queues;
++
++ rc = ena_setup_all_rx_resources(adapter);
++ if (rc)
++ goto err_setup_rx;
++
++ rc = ena_create_all_io_rx_queues(adapter);
++ if (rc)
++ goto err_create_rx_queues;
++
++ return 0;
++
++err_create_rx_queues:
++ ena_free_all_io_rx_resources(adapter);
++err_setup_rx:
++ ena_destroy_all_tx_queues(adapter);
++err_create_tx_queues:
++ ena_free_all_io_tx_resources(adapter);
++err_setup_tx:
++ if (rc != -ENOMEM) {
++ netif_err(adapter, ifup, adapter->netdev,
++ "Queue creation failed with error code %d\n",
++ rc);
++ return rc;
++ }
++
++ cur_tx_ring_size = adapter->tx_ring[0].ring_size;
++ cur_rx_ring_size = adapter->rx_ring[0].ring_size;
++
++ netif_err(adapter, ifup, adapter->netdev,
++ "Not enough memory to create queues with sizes TX=%d, RX=%d\n",
++ cur_tx_ring_size, cur_rx_ring_size);
++
++ new_tx_ring_size = cur_tx_ring_size;
++ new_rx_ring_size = cur_rx_ring_size;
++
++ /* Decrease the size of the larger queue, or
++ * decrease both if they are the same size.
++ */
++ if (cur_rx_ring_size <= cur_tx_ring_size)
++ new_tx_ring_size = cur_tx_ring_size / 2;
++ if (cur_rx_ring_size >= cur_tx_ring_size)
++ new_rx_ring_size = cur_rx_ring_size / 2;
++
++ if (cur_tx_ring_size < ENA_MIN_RING_SIZE ||
++ cur_rx_ring_size < ENA_MIN_RING_SIZE) {
++ netif_err(adapter, ifup, adapter->netdev,
++ "Queue creation failed with the smallest possible queue size of %d for both queues. Not retrying with smaller queues\n",
++ ENA_MIN_RING_SIZE);
++ return rc;
++ }
++
++ netif_err(adapter, ifup, adapter->netdev,
++ "Retrying queue creation with sizes TX=%d, RX=%d\n",
++ new_tx_ring_size,
++ new_rx_ring_size);
++
++ set_io_rings_size(adapter, new_tx_ring_size,
++ new_rx_ring_size);
++ }
++}
++
+ static int ena_up(struct ena_adapter *adapter)
+ {
+ int rc, i;
+@@ -1768,25 +1873,9 @@ static int ena_up(struct ena_adapter *ad
+ if (rc)
+ goto err_req_irq;
+
+- /* allocate transmit descriptors */
+- rc = ena_setup_all_tx_resources(adapter);
++ rc = create_queues_with_size_backoff(adapter);
+ if (rc)
+- goto err_setup_tx;
+-
+- /* allocate receive descriptors */
+- rc = ena_setup_all_rx_resources(adapter);
+- if (rc)
+- goto err_setup_rx;
+-
+- /* Create TX queues */
+- rc = ena_create_all_io_tx_queues(adapter);
+- if (rc)
+- goto err_create_tx_queues;
+-
+- /* Create RX queues */
+- rc = ena_create_all_io_rx_queues(adapter);
+- if (rc)
+- goto err_create_rx_queues;
++ goto err_create_queues_with_backoff;
+
+ rc = ena_up_complete(adapter);
+ if (rc)
+@@ -1815,14 +1904,11 @@ static int ena_up(struct ena_adapter *ad
+ return rc;
+
+ err_up:
+- ena_destroy_all_rx_queues(adapter);
+-err_create_rx_queues:
+ ena_destroy_all_tx_queues(adapter);
+-err_create_tx_queues:
+- ena_free_all_io_rx_resources(adapter);
+-err_setup_rx:
+ ena_free_all_io_tx_resources(adapter);
+-err_setup_tx:
++ ena_destroy_all_rx_queues(adapter);
++ ena_free_all_io_rx_resources(adapter);
++err_create_queues_with_backoff:
+ ena_free_io_irq(adapter);
+ err_req_irq:
+ ena_del_napi(adapter);
+@@ -3286,17 +3372,14 @@ static int ena_calc_queue_size(struct en
+ max_tx_queue_size = rounddown_pow_of_two(max_tx_queue_size);
+ max_rx_queue_size = rounddown_pow_of_two(max_rx_queue_size);
+
+- tx_queue_size = min_t(u32, tx_queue_size, max_tx_queue_size);
+- rx_queue_size = min_t(u32, rx_queue_size, max_rx_queue_size);
++ tx_queue_size = clamp_val(tx_queue_size, ENA_MIN_RING_SIZE,
++ max_tx_queue_size);
++ rx_queue_size = clamp_val(rx_queue_size, ENA_MIN_RING_SIZE,
++ max_rx_queue_size);
+
+ tx_queue_size = rounddown_pow_of_two(tx_queue_size);
+ rx_queue_size = rounddown_pow_of_two(rx_queue_size);
+
+- if (unlikely(!rx_queue_size || !tx_queue_size)) {
+- dev_err(&ctx->pdev->dev, "Invalid queue size\n");
+- return -EFAULT;
+- }
+-
+ ctx->max_tx_queue_size = max_tx_queue_size;
+ ctx->max_rx_queue_size = max_rx_queue_size;
+ ctx->tx_queue_size = tx_queue_size;
+@@ -3426,8 +3509,8 @@ static int ena_probe(struct pci_dev *pde
+ adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
+ adapter->reset_reason = ENA_REGS_RESET_NORMAL;
+
+- adapter->tx_ring_size = calc_queue_ctx.tx_queue_size;
+- adapter->rx_ring_size = calc_queue_ctx.rx_queue_size;
++ adapter->requested_tx_ring_size = calc_queue_ctx.tx_queue_size;
++ adapter->requested_rx_ring_size = calc_queue_ctx.rx_queue_size;
+ adapter->max_tx_ring_size = calc_queue_ctx.max_tx_queue_size;
+ adapter->max_rx_ring_size = calc_queue_ctx.max_rx_queue_size;
+ adapter->max_tx_sgl_size = calc_queue_ctx.max_tx_sgl_size;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -79,6 +79,8 @@
+ #define ENA_BAR_MASK (BIT(ENA_REG_BAR) | BIT(ENA_MEM_BAR))
+
+ #define ENA_DEFAULT_RING_SIZE (1024)
++#define ENA_MIN_RING_SIZE (256)
++
+
+ #define ENA_TX_WAKEUP_THRESH (MAX_SKB_FRAGS + 2)
+ #define ENA_DEFAULT_RX_COPYBREAK (256 - NET_IP_ALIGN)
+@@ -330,8 +332,8 @@ struct ena_adapter {
+ u32 tx_usecs, rx_usecs; /* interrupt moderation */
+ u32 tx_frames, rx_frames; /* interrupt moderation */
+
+- u32 tx_ring_size;
+- u32 rx_ring_size;
++ u32 requested_tx_ring_size;
++ u32 requested_rx_ring_size;
+
+ u32 max_tx_ring_size;
+ u32 max_rx_ring_size;
diff --git a/debian/patches/features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch b/debian/patches/features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch
new file mode 100644
index 000000000..af89762f1
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch
@@ -0,0 +1,49 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:22 +0300
+Subject: [PATCH] net: ena: arrange ena_probe() function variables in reverse
+ christmas tree
+Origin: https://git.kernel.org/linus/83b9240428a66da3c8e24e719b985d533cf58067
+Bug-Debian: https://bugs.debian.org/941291
+
+Reverse christmas tree arrangement is when strings are written from longer
+to shorter with each line. Most of our functions are abiding this
+arrangement but this function does not.
+
+In this commit we arrange the variables of ena_probe() in reverse christmas
+tree.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -3274,17 +3274,17 @@ static int ena_calc_queue_size(struct pc
+ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ struct ena_com_dev_get_features_ctx get_feat_ctx;
+- static int version_printed;
+- struct net_device *netdev;
+- struct ena_adapter *adapter;
+ struct ena_llq_configurations llq_config;
+ struct ena_com_dev *ena_dev = NULL;
+- char *queue_type_str;
+- static int adapters_found;
++ struct ena_adapter *adapter;
++ static int version_printed;
+ int io_queue_num, bars, rc;
+- int queue_size;
++ struct net_device *netdev;
++ static int adapters_found;
++ char *queue_type_str;
+ u16 tx_sgl_size = 0;
+ u16 rx_sgl_size = 0;
++ int queue_size;
+ bool wd_state;
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
diff --git a/debian/patches/features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch b/debian/patches/features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch
new file mode 100644
index 000000000..e1b214e80
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch
@@ -0,0 +1,52 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Sun, 15 Sep 2019 17:29:44 +0300
+Subject: [PATCH] net: ena: don't wake up tx queue when down
+Origin: https://git.kernel.org/linus/a53651ec93a8d7ab5b26c5390e0c389048b4b4b6
+Bug-Debian: https://bugs.debian.org/941291
+
+There is a race condition that can occur when calling ena_down().
+The ena_clean_tx_irq() - which is a part of the napi handler -
+function might wake up the tx queue when the queue is supposed
+to be down (during recovery or changing the size of the queues
+for example) This causes the ena_start_xmit() function to trigger
+and possibly try to access the destroyed queues.
+
+The race is illustrated below:
+
+Flow A: Flow B(napi handler)
+ena_down()
+ netif_carrier_off()
+ netif_tx_disable()
+ ena_clean_tx_irq()
+ netif_tx_wake_queue()
+ ena_napi_disable_all()
+ ena_destroy_all_io_queues()
+
+After these flows the tx queue is active and ena_start_xmit() accesses
+the destroyed queue which leads to a kernel panic.
+
+fixes: 1738cd3ed342 (net: ena: Add a driver for Amazon Elastic Network Adapters (ENA))
+
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index 664e3ed97ea9..d118ed4c57ce 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -823,7 +823,8 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget)
+ above_thresh =
+ ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq,
+ ENA_TX_WAKEUP_THRESH);
+- if (netif_tx_queue_stopped(txq) && above_thresh) {
++ if (netif_tx_queue_stopped(txq) && above_thresh &&
++ test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags)) {
+ netif_tx_wake_queue(txq);
+ u64_stats_update_begin(&tx_ring->syncp);
+ tx_ring->tx_stats.queue_wakeup++;
+--
+2.17.1
+
diff --git a/debian/patches/features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch b/debian/patches/features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch
new file mode 100644
index 000000000..43be08179
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch
@@ -0,0 +1,270 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Tue, 11 Jun 2019 14:58:06 +0300
+Subject: [PATCH] net: ena: enable negotiating larger Rx ring size
+Origin: https://git.kernel.org/linus/31aa9857f1733403f2eb12d51c1cec20a22483d9
+Bug-Debian: https://bugs.debian.org/941291
+
+Use MAX_QUEUES_EXT get feature capability to query the device.
+
+Signed-off-by: Netanel Belgazal <netanel@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 144 ++++++++++++-------
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 15 ++
+ 2 files changed, 110 insertions(+), 49 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2455,13 +2455,6 @@ static int ena_device_validate_params(st
+ return -EINVAL;
+ }
+
+- if ((get_feat_ctx->max_queues.max_cq_num < adapter->num_queues) ||
+- (get_feat_ctx->max_queues.max_sq_num < adapter->num_queues)) {
+- netif_err(adapter, drv, netdev,
+- "Error, device doesn't support enough queues\n");
+- return -EINVAL;
+- }
+-
+ if (get_feat_ctx->dev_attr.max_mtu < netdev->mtu) {
+ netif_err(adapter, drv, netdev,
+ "Error, device max mtu is smaller than netdev MTU\n");
+@@ -3035,18 +3028,32 @@ static int ena_calc_io_queue_num(struct
+ struct ena_com_dev *ena_dev,
+ struct ena_com_dev_get_features_ctx *get_feat_ctx)
+ {
+- int io_sq_num, io_queue_num;
++ int io_tx_sq_num, io_tx_cq_num, io_rx_num, io_queue_num;
++
++ if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) {
++ struct ena_admin_queue_ext_feature_fields *max_queue_ext =
++ &get_feat_ctx->max_queue_ext.max_queue_ext;
++ io_rx_num = min_t(int, max_queue_ext->max_rx_sq_num,
++ max_queue_ext->max_rx_cq_num);
+
+- /* In case of LLQ use the llq number in the get feature cmd */
++ io_tx_sq_num = max_queue_ext->max_tx_sq_num;
++ io_tx_cq_num = max_queue_ext->max_tx_cq_num;
++ } else {
++ struct ena_admin_queue_feature_desc *max_queues =
++ &get_feat_ctx->max_queues;
++ io_tx_sq_num = max_queues->max_sq_num;
++ io_tx_cq_num = max_queues->max_cq_num;
++ io_rx_num = min_t(int, io_tx_sq_num, io_tx_cq_num);
++ }
++
++ /* In case of LLQ use the llq fields for the tx SQ/CQ */
+ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+- io_sq_num = get_feat_ctx->llq.max_llq_num;
+- else
+- io_sq_num = get_feat_ctx->max_queues.max_sq_num;
++ io_tx_sq_num = get_feat_ctx->llq.max_llq_num;
+
+ io_queue_num = min_t(int, num_online_cpus(), ENA_MAX_NUM_IO_QUEUES);
+- io_queue_num = min_t(int, io_queue_num, io_sq_num);
+- io_queue_num = min_t(int, io_queue_num,
+- get_feat_ctx->max_queues.max_cq_num);
++ io_queue_num = min_t(int, io_queue_num, io_rx_num);
++ io_queue_num = min_t(int, io_queue_num, io_tx_sq_num);
++ io_queue_num = min_t(int, io_queue_num, io_tx_cq_num);
+ /* 1 IRQ for for mgmnt and 1 IRQs for each IO direction */
+ io_queue_num = min_t(int, io_queue_num, pci_msix_vec_count(pdev) - 1);
+ if (unlikely(!io_queue_num)) {
+@@ -3229,36 +3236,73 @@ static inline void set_default_llq_confi
+ llq_config->llq_ring_entry_size_value = 128;
+ }
+
+-static int ena_calc_queue_size(struct pci_dev *pdev,
+- struct ena_com_dev *ena_dev,
+- u16 *max_tx_sgl_size,
+- u16 *max_rx_sgl_size,
+- struct ena_com_dev_get_features_ctx *get_feat_ctx)
+-{
+- u32 queue_size = ENA_DEFAULT_RING_SIZE;
+-
+- queue_size = min_t(u32, queue_size,
+- get_feat_ctx->max_queues.max_cq_depth);
+- queue_size = min_t(u32, queue_size,
+- get_feat_ctx->max_queues.max_sq_depth);
++static int ena_calc_queue_size(struct ena_calc_queue_size_ctx *ctx)
++{
++ struct ena_admin_feature_llq_desc *llq = &ctx->get_feat_ctx->llq;
++ struct ena_com_dev *ena_dev = ctx->ena_dev;
++ u32 tx_queue_size = ENA_DEFAULT_RING_SIZE;
++ u32 rx_queue_size = ENA_DEFAULT_RING_SIZE;
++ u32 max_tx_queue_size;
++ u32 max_rx_queue_size;
++
++ if (ctx->ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) {
++ struct ena_admin_queue_ext_feature_fields *max_queue_ext =
++ &ctx->get_feat_ctx->max_queue_ext.max_queue_ext;
++ max_rx_queue_size = min_t(u32, max_queue_ext->max_rx_cq_depth,
++ max_queue_ext->max_rx_sq_depth);
++ max_tx_queue_size = max_queue_ext->max_tx_cq_depth;
++
++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
++ max_tx_queue_size = min_t(u32, max_tx_queue_size,
++ llq->max_llq_depth);
++ else
++ max_tx_queue_size = min_t(u32, max_tx_queue_size,
++ max_queue_ext->max_tx_sq_depth);
++
++ ctx->max_tx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
++ max_queue_ext->max_per_packet_tx_descs);
++ ctx->max_rx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
++ max_queue_ext->max_per_packet_rx_descs);
++ } else {
++ struct ena_admin_queue_feature_desc *max_queues =
++ &ctx->get_feat_ctx->max_queues;
++ max_rx_queue_size = min_t(u32, max_queues->max_cq_depth,
++ max_queues->max_sq_depth);
++ max_tx_queue_size = max_queues->max_cq_depth;
++
++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
++ max_tx_queue_size = min_t(u32, max_tx_queue_size,
++ llq->max_llq_depth);
++ else
++ max_tx_queue_size = min_t(u32, max_tx_queue_size,
++ max_queues->max_sq_depth);
+
+- if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+- queue_size = min_t(u32, queue_size,
+- get_feat_ctx->llq.max_llq_depth);
++ ctx->max_tx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
++ max_queues->max_packet_tx_descs);
++ ctx->max_rx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
++ max_queues->max_packet_rx_descs);
++ }
+
+- queue_size = rounddown_pow_of_two(queue_size);
++ max_tx_queue_size = rounddown_pow_of_two(max_tx_queue_size);
++ max_rx_queue_size = rounddown_pow_of_two(max_rx_queue_size);
+
+- if (unlikely(!queue_size)) {
+- dev_err(&pdev->dev, "Invalid queue size\n");
++ tx_queue_size = min_t(u32, tx_queue_size, max_tx_queue_size);
++ rx_queue_size = min_t(u32, rx_queue_size, max_rx_queue_size);
++
++ tx_queue_size = rounddown_pow_of_two(tx_queue_size);
++ rx_queue_size = rounddown_pow_of_two(rx_queue_size);
++
++ if (unlikely(!rx_queue_size || !tx_queue_size)) {
++ dev_err(&ctx->pdev->dev, "Invalid queue size\n");
+ return -EFAULT;
+ }
+
+- *max_tx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
+- get_feat_ctx->max_queues.max_packet_tx_descs);
+- *max_rx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS,
+- get_feat_ctx->max_queues.max_packet_rx_descs);
++ ctx->max_tx_queue_size = max_tx_queue_size;
++ ctx->max_rx_queue_size = max_rx_queue_size;
++ ctx->tx_queue_size = tx_queue_size;
++ ctx->rx_queue_size = rx_queue_size;
+
+- return queue_size;
++ return 0;
+ }
+
+ /* ena_probe - Device Initialization Routine
+@@ -3274,6 +3318,7 @@ static int ena_calc_queue_size(struct pc
+ static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+ {
+ struct ena_com_dev_get_features_ctx get_feat_ctx;
++ struct ena_calc_queue_size_ctx calc_queue_ctx = { 0 };
+ struct ena_llq_configurations llq_config;
+ struct ena_com_dev *ena_dev = NULL;
+ struct ena_adapter *adapter;
+@@ -3281,9 +3326,6 @@ static int ena_probe(struct pci_dev *pde
+ struct net_device *netdev;
+ static int adapters_found;
+ char *queue_type_str;
+- u16 tx_sgl_size = 0;
+- u16 rx_sgl_size = 0;
+- int queue_size;
+ bool wd_state;
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+@@ -3340,20 +3382,25 @@ static int ena_probe(struct pci_dev *pde
+ goto err_device_destroy;
+ }
+
++ calc_queue_ctx.ena_dev = ena_dev;
++ calc_queue_ctx.get_feat_ctx = &get_feat_ctx;
++ calc_queue_ctx.pdev = pdev;
++
+ /* initial Tx interrupt delay, Assumes 1 usec granularity.
+ * Updated during device initialization with the real granularity
+ */
+ ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS;
+ io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx);
+- queue_size = ena_calc_queue_size(pdev, ena_dev, &tx_sgl_size,
+- &rx_sgl_size, &get_feat_ctx);
+- if ((queue_size <= 0) || (io_queue_num <= 0)) {
++ rc = ena_calc_queue_size(&calc_queue_ctx);
++ if (rc || io_queue_num <= 0) {
+ rc = -EFAULT;
+ goto err_device_destroy;
+ }
+
+- dev_info(&pdev->dev, "creating %d io queues. queue size: %d. LLQ is %s\n",
+- io_queue_num, queue_size,
++ dev_info(&pdev->dev, "creating %d io queues. rx queue size: %d tx queue size. %d LLQ is %s\n",
++ io_queue_num,
++ calc_queue_ctx.rx_queue_size,
++ calc_queue_ctx.tx_queue_size,
+ (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ?
+ "ENABLED" : "DISABLED");
+
+@@ -3379,11 +3426,10 @@ static int ena_probe(struct pci_dev *pde
+ adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
+ adapter->reset_reason = ENA_REGS_RESET_NORMAL;
+
+- adapter->tx_ring_size = queue_size;
+- adapter->rx_ring_size = queue_size;
+-
+- adapter->max_tx_sgl_size = tx_sgl_size;
+- adapter->max_rx_sgl_size = rx_sgl_size;
++ adapter->tx_ring_size = calc_queue_ctx.tx_queue_size;
++ adapter->rx_ring_size = calc_queue_ctx.rx_queue_size;
++ adapter->max_tx_sgl_size = calc_queue_ctx.max_tx_sgl_size;
++ adapter->max_rx_sgl_size = calc_queue_ctx.max_rx_sgl_size;
+
+ adapter->num_queues = io_queue_num;
+ adapter->last_monitored_tx_qid = 0;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -154,6 +154,18 @@ struct ena_napi {
+ u32 qid;
+ };
+
++struct ena_calc_queue_size_ctx {
++ struct ena_com_dev_get_features_ctx *get_feat_ctx;
++ struct ena_com_dev *ena_dev;
++ struct pci_dev *pdev;
++ u16 tx_queue_size;
++ u16 rx_queue_size;
++ u16 max_tx_queue_size;
++ u16 max_rx_queue_size;
++ u16 max_tx_sgl_size;
++ u16 max_rx_sgl_size;
++};
++
+ struct ena_tx_buffer {
+ struct sk_buff *skb;
+ /* num of ena desc for this specific skb
+@@ -321,6 +333,9 @@ struct ena_adapter {
+ u32 tx_ring_size;
+ u32 rx_ring_size;
+
++ u32 max_tx_ring_size;
++ u32 max_rx_ring_size;
++
+ u32 msg_enable;
+
+ u16 max_tx_sgl_size;
diff --git a/debian/patches/features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch b/debian/patches/features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch
new file mode 100644
index 000000000..3eb7e408c
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch
@@ -0,0 +1,63 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:29 +0300
+Subject: [PATCH] net: ena: enable the interrupt_moderation in
+ driver_supported_features
+Origin: https://git.kernel.org/linus/bd21b0cc3a63d1c658b230db084b0f392b78cab2
+Bug-Debian: https://bugs.debian.org/941291
+
+Add driver_supported_features to host_host info which is a new API used to
+communicate to the device which features are supported by the driver.
+
+Add the interrupt_moderation bit to host_info->driver_supported_features
+and enable it to signal the device that this driver supports interrupt
+moderation properly.
+
+Reserved bits are for features implemented in the future
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_admin_defs.h | 8 ++++++++
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 +++
+ 2 files changed, 11 insertions(+)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h
+@@ -808,6 +808,12 @@ struct ena_admin_host_info {
+ u16 num_cpus;
+
+ u16 reserved;
++
++ /* 1 :0 : reserved
++ * 2 : interrupt_moderation
++ * 31:3 : reserved
++ */
++ u32 driver_supported_features;
+ };
+
+ struct ena_admin_rss_ind_table_entry {
+@@ -1110,6 +1116,8 @@ struct ena_admin_ena_mmio_req_read_less_
+ #define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3)
+ #define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8
+ #define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8)
++#define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_SHIFT 2
++#define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK BIT(2)
+
+ /* aenq_common_desc */
+ #define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0)
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -2440,6 +2440,9 @@ static void ena_config_host_info(struct
+ ("K"[0] << ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT);
+ host_info->num_cpus = num_online_cpus();
+
++ host_info->driver_supported_features =
++ ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK;
++
+ rc = ena_com_set_host_attributes(ena_dev);
+ if (rc) {
+ if (rc == -EOPNOTSUPP)
diff --git a/debian/patches/features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch b/debian/patches/features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch
new file mode 100644
index 000000000..e194ecde9
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch
@@ -0,0 +1,89 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:36 +0300
+Subject: [PATCH] net: ena: fix incorrect update of intr_delay_resolution
+Origin: https://git.kernel.org/linus/79226cea4a5ebbd84a4eee1762526f664c7beb62
+Bug-Debian: https://bugs.debian.org/941291
+
+ena_dev->intr_moder_rx/tx_interval save the intervals received from the
+user after dividing them by ena_dev->intr_delay_resolution. Therefore
+when intr_delay_resolution changes, the code needs to first mutiply
+intr_moder_rx/tx_interval by the previous intr_delay_resolution to get
+the value originally given by the user, and only then divide it by the
+new intr_delay_resolution.
+
+Current code does not first multiply intr_moder_rx/tx_interval by the old
+intr_delay_resolution. This commit fixes it.
+
+Also initialize ena_dev->intr_delay_resolution to be 1.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 21 ++++++++++++++++----
+ drivers/net/ethernet/amazon/ena/ena_com.h | 1 +
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 1 +
+ 3 files changed, 19 insertions(+), 4 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -1281,17 +1281,30 @@ static int ena_com_ind_tbl_convert_from_
+ static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev,
+ u16 intr_delay_resolution)
+ {
++ /* Initial value of intr_delay_resolution might be 0 */
++ u16 prev_intr_delay_resolution =
++ ena_dev->intr_delay_resolution ?
++ ena_dev->intr_delay_resolution :
++ ENA_DEFAULT_INTR_DELAY_RESOLUTION;
++
+ if (!intr_delay_resolution) {
+ pr_err("Illegal intr_delay_resolution provided. Going to use default 1 usec resolution\n");
+- intr_delay_resolution = 1;
++ intr_delay_resolution = ENA_DEFAULT_INTR_DELAY_RESOLUTION;
+ }
+- ena_dev->intr_delay_resolution = intr_delay_resolution;
+
+ /* update Rx */
+- ena_dev->intr_moder_rx_interval /= intr_delay_resolution;
++ ena_dev->intr_moder_rx_interval =
++ ena_dev->intr_moder_rx_interval *
++ prev_intr_delay_resolution /
++ intr_delay_resolution;
+
+ /* update Tx */
+- ena_dev->intr_moder_tx_interval /= intr_delay_resolution;
++ ena_dev->intr_moder_tx_interval =
++ ena_dev->intr_moder_tx_interval *
++ prev_intr_delay_resolution /
++ intr_delay_resolution;
++
++ ena_dev->intr_delay_resolution = intr_delay_resolution;
+ }
+
+ /*****************************************************************************/
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -74,6 +74,7 @@
+
+ #define ENA_INTR_INITIAL_TX_INTERVAL_USECS 196
+ #define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0
++#define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1
+
+ #define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -3502,6 +3502,7 @@ static int ena_probe(struct pci_dev *pde
+ */
+ ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS;
+ ena_dev->intr_moder_rx_interval = ENA_INTR_INITIAL_RX_INTERVAL_USECS;
++ ena_dev->intr_delay_resolution = ENA_DEFAULT_INTR_DELAY_RESOLUTION;
+ io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx);
+ rc = ena_calc_queue_size(&calc_queue_ctx);
+ if (rc || io_queue_num <= 0) {
diff --git a/debian/patches/features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch b/debian/patches/features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch
new file mode 100644
index 000000000..353f87dbf
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch
@@ -0,0 +1,45 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:35 +0300
+Subject: [PATCH] net: ena: fix retrieval of nonadaptive interrupt moderation
+ intervals
+Origin: https://git.kernel.org/linus/0eda847953d8dfb4b713ea62420f66157e230e13
+Bug-Debian: https://bugs.debian.org/941291
+
+Nonadaptive interrupt moderation intervals are assigned the value set
+by the user in ethtool -C divided by ena_dev->intr_delay_resolution.
+
+Therefore when the user tries to get the nonadaptive interrupt moderation
+intervals with ethtool -c the code needs to multiply the saved value
+by ena_dev->intr_delay_resolution.
+
+The current code erroneously divides instead of multiplying in ethtool -c.
+This patch fixes this.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -310,14 +310,15 @@ static int ena_get_coalesce(struct net_d
+ /* the devie doesn't support interrupt moderation */
+ return -EOPNOTSUPP;
+ }
++
+ coalesce->tx_coalesce_usecs =
+- ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) /
++ ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) *
+ ena_dev->intr_delay_resolution;
+
+ if (!ena_com_get_adaptive_moderation_enabled(ena_dev))
+ coalesce->rx_coalesce_usecs =
+ ena_com_get_nonadaptive_moderation_interval_rx(ena_dev)
+- / ena_dev->intr_delay_resolution;
++ * ena_dev->intr_delay_resolution;
+
+ coalesce->use_adaptive_rx_coalesce =
+ ena_com_get_adaptive_moderation_enabled(ena_dev);
diff --git a/debian/patches/features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch b/debian/patches/features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch
new file mode 100644
index 000000000..f757bf178
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch
@@ -0,0 +1,34 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Wed, 1 May 2019 16:47:07 +0300
+Subject: [PATCH] net: ena: fix return value of ena_com_config_llq_info()
+Origin: https://git.kernel.org/linus/9a27de0c6ba10fe1af74d16d3524425e52c1ba3e
+Bug-Debian: https://bugs.debian.org/941291
+
+ena_com_config_llq_info() returns 0 even if ena_com_set_llq() fails.
+Return the failure code of ena_com_set_llq() in case it fails.
+
+fixes: 689b2bdaaa14 ("net: ena: add functions for handling Low Latency Queues in ena_com")
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c
+index f9bc0b831a1a..4fe437fe771b 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_com.c
++++ b/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -731,7 +731,7 @@ static int ena_com_config_llq_info(struct ena_com_dev *ena_dev,
+ if (rc)
+ pr_err("Cannot set LLQ configuration: %d\n", rc);
+
+- return 0;
++ return rc;
+ }
+
+ static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx,
+--
+2.17.1
+
diff --git a/debian/patches/features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch b/debian/patches/features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch
new file mode 100644
index 000000000..bc30849de
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch
@@ -0,0 +1,91 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Wed, 1 May 2019 16:47:04 +0300
+Subject: [PATCH] net: ena: fix: set freed objects to NULL to avoid failing
+ future allocations
+Origin: https://git.kernel.org/linus/8ee8ee7fe87bf64738ab4e31be036a7165608b27
+Bug-Debian: https://bugs.debian.org/941291
+
+In some cases when a queue related allocation fails, successful past
+allocations are freed but the pointer that pointed to them is not
+set to NULL. This is a problem for 2 reasons:
+1. This is generally a bad practice since this pointer might be
+accidentally accessed in the future.
+2. Future allocations using the same pointer check if the pointer
+is NULL and fail if it is not.
+
+Fixed this by setting such pointers to NULL in the allocation of
+queue related objects.
+
+Also refactored the code of ena_setup_tx_resources() to goto-style
+error handling to avoid code duplication of resource freeing.
+
+Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 25 ++++++++++++--------
+ 1 file changed, 15 insertions(+), 10 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -224,28 +224,23 @@ static int ena_setup_tx_resources(struct
+ if (!tx_ring->tx_buffer_info) {
+ tx_ring->tx_buffer_info = vzalloc(size);
+ if (!tx_ring->tx_buffer_info)
+- return -ENOMEM;
++ goto err_tx_buffer_info;
+ }
+
+ size = sizeof(u16) * tx_ring->ring_size;
+ tx_ring->free_tx_ids = vzalloc_node(size, node);
+ if (!tx_ring->free_tx_ids) {
+ tx_ring->free_tx_ids = vzalloc(size);
+- if (!tx_ring->free_tx_ids) {
+- vfree(tx_ring->tx_buffer_info);
+- return -ENOMEM;
+- }
++ if (!tx_ring->free_tx_ids)
++ goto err_free_tx_ids;
+ }
+
+ size = tx_ring->tx_max_header_size;
+ tx_ring->push_buf_intermediate_buf = vzalloc_node(size, node);
+ if (!tx_ring->push_buf_intermediate_buf) {
+ tx_ring->push_buf_intermediate_buf = vzalloc(size);
+- if (!tx_ring->push_buf_intermediate_buf) {
+- vfree(tx_ring->tx_buffer_info);
+- vfree(tx_ring->free_tx_ids);
+- return -ENOMEM;
+- }
++ if (!tx_ring->push_buf_intermediate_buf)
++ goto err_push_buf_intermediate_buf;
+ }
+
+ /* Req id ring for TX out of order completions */
+@@ -259,6 +254,15 @@ static int ena_setup_tx_resources(struct
+ tx_ring->next_to_clean = 0;
+ tx_ring->cpu = ena_irq->cpu;
+ return 0;
++
++err_push_buf_intermediate_buf:
++ vfree(tx_ring->free_tx_ids);
++ tx_ring->free_tx_ids = NULL;
++err_free_tx_ids:
++ vfree(tx_ring->tx_buffer_info);
++ tx_ring->tx_buffer_info = NULL;
++err_tx_buffer_info:
++ return -ENOMEM;
+ }
+
+ /* ena_free_tx_resources - Free I/O Tx Resources per Queue
+@@ -378,6 +382,7 @@ static int ena_setup_rx_resources(struct
+ rx_ring->free_rx_ids = vzalloc(size);
+ if (!rx_ring->free_rx_ids) {
+ vfree(rx_ring->rx_buffer_info);
++ rx_ring->rx_buffer_info = NULL;
+ return -ENOMEM;
+ }
+ }
diff --git a/debian/patches/features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch b/debian/patches/features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch
new file mode 100644
index 000000000..72137a523
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch
@@ -0,0 +1,39 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:34 +0300
+Subject: [PATCH] net: ena: fix update of interrupt moderation register
+Origin: https://git.kernel.org/linus/7b8a28787e2ba671eaeb073e3b62fb4786338a09
+Bug-Debian: https://bugs.debian.org/941291
+
+Current implementation always updates the interrupt register with
+the smoothed_interval of the rx_ring. However this should be
+done only in case of adaptive interrupt moderation. If non-adaptive
+interrupt moderation is used, the non-adaptive interrupt moderation
+interval should be used. This commit fixes that.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1188,12 +1188,15 @@ static void ena_unmask_interrupt(struct
+ struct ena_ring *rx_ring)
+ {
+ struct ena_eth_io_intr_reg intr_reg;
++ u32 rx_interval = ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev) ?
++ rx_ring->smoothed_interval :
++ ena_com_get_nonadaptive_moderation_interval_rx(rx_ring->ena_dev);
+
+ /* Update intr register: rx intr delay,
+ * tx intr delay and interrupt unmask
+ */
+ ena_com_update_intr_reg(&intr_reg,
+- rx_ring->smoothed_interval,
++ rx_interval,
+ tx_ring->smoothed_interval,
+ true);
+
diff --git a/debian/patches/features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch b/debian/patches/features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch
new file mode 100644
index 000000000..ec5dc707c
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch
@@ -0,0 +1,41 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Wed, 1 May 2019 16:47:08 +0300
+Subject: [PATCH] net: ena: improve latency by disabling adaptive interrupt
+ moderation by default
+Origin: https://git.kernel.org/linus/78cb421d185cfb4fcea94e7c3ff6e6ea77bb8c11
+Bug-Debian: https://bugs.debian.org/941291
+
+Adaptive interrupt moderation was erroneously enabled by default
+in the driver.
+
+In case the device supports adaptive interrupt moderation it will
+be automatically used, which may potentially increase latency.
+
+The adaptive moderation can be enabled from ethtool command in
+case the feature is supported by the device.
+
+Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
+Signed-off-by: Guy Tzalik <gtzalik@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -2801,7 +2801,11 @@ int ena_com_init_interrupt_moderation(st
+ /* if moderation is supported by device we set adaptive moderation */
+ delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution;
+ ena_com_update_intr_delay_resolution(ena_dev, delay_resolution);
+- ena_com_enable_adaptive_moderation(ena_dev);
++
++ /* Disable adaptive moderation by default - can be enabled from
++ * ethtool
++ */
++ ena_com_disable_adaptive_moderation(ena_dev);
+
+ return 0;
+ err:
diff --git a/debian/patches/features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch b/debian/patches/features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch
new file mode 100644
index 000000000..3367bc9f9
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch
@@ -0,0 +1,53 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Tue, 11 Jun 2019 14:58:07 +0300
+Subject: [PATCH] net: ena: make ethtool show correct current and max queue
+ sizes
+Origin: https://git.kernel.org/linus/9f9ae3f98b8d8b8aa709831057759dbb52ba5083
+Bug-Debian: https://bugs.debian.org/941291
+
+Currently ethtool -g shows the same size for current and max queue
+sizes.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 10 ++++------
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 ++
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -447,13 +447,11 @@ static void ena_get_ringparam(struct net
+ struct ethtool_ringparam *ring)
+ {
+ struct ena_adapter *adapter = netdev_priv(netdev);
+- struct ena_ring *tx_ring = &adapter->tx_ring[0];
+- struct ena_ring *rx_ring = &adapter->rx_ring[0];
+
+- ring->rx_max_pending = rx_ring->ring_size;
+- ring->tx_max_pending = tx_ring->ring_size;
+- ring->rx_pending = rx_ring->ring_size;
+- ring->tx_pending = tx_ring->ring_size;
++ ring->tx_max_pending = adapter->max_tx_ring_size;
++ ring->rx_max_pending = adapter->max_rx_ring_size;
++ ring->tx_pending = adapter->tx_ring_size;
++ ring->rx_pending = adapter->rx_ring_size;
+ }
+
+ static u32 ena_flow_hash_to_flow_type(u16 hash_fields)
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -3428,6 +3428,8 @@ static int ena_probe(struct pci_dev *pde
+
+ adapter->tx_ring_size = calc_queue_ctx.tx_queue_size;
+ adapter->rx_ring_size = calc_queue_ctx.rx_queue_size;
++ adapter->max_tx_ring_size = calc_queue_ctx.max_tx_queue_size;
++ adapter->max_rx_ring_size = calc_queue_ctx.max_rx_queue_size;
+ adapter->max_tx_sgl_size = calc_queue_ctx.max_tx_sgl_size;
+ adapter->max_rx_sgl_size = calc_queue_ctx.max_rx_sgl_size;
+
diff --git a/debian/patches/features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch b/debian/patches/features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch
new file mode 100644
index 000000000..c790eae13
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch
@@ -0,0 +1,50 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:27 +0300
+Subject: [PATCH] net: ena: optimise calculations for CQ doorbell
+Origin: https://git.kernel.org/linus/d91860989dd4bce582ed6c3647a0d41d6fd895b3
+Bug-Debian: https://bugs.debian.org/941291
+
+This patch initially checks if CQ doorbell
+is needed before proceeding with the calculations.
+
+Signed-off-by: Igor Chauskin <igorch@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_eth_com.h | 20 ++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.h b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+index 0a3d9180e40e..77986c0ea52c 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.h
++++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.h
+@@ -195,15 +195,17 @@ static inline int ena_com_update_dev_comp_head(struct ena_com_io_cq *io_cq)
+ u16 unreported_comp, head;
+ bool need_update;
+
+- head = io_cq->head;
+- unreported_comp = head - io_cq->last_head_update;
+- need_update = unreported_comp > (io_cq->q_depth / ENA_COMP_HEAD_THRESH);
+-
+- if (io_cq->cq_head_db_reg && need_update) {
+- pr_debug("Write completion queue doorbell for queue %d: head: %d\n",
+- io_cq->qid, head);
+- writel(head, io_cq->cq_head_db_reg);
+- io_cq->last_head_update = head;
++ if (unlikely(io_cq->cq_head_db_reg)) {
++ head = io_cq->head;
++ unreported_comp = head - io_cq->last_head_update;
++ need_update = unreported_comp > (io_cq->q_depth / ENA_COMP_HEAD_THRESH);
++
++ if (unlikely(need_update)) {
++ pr_debug("Write completion queue doorbell for queue %d: head: %d\n",
++ io_cq->qid, head);
++ writel(head, io_cq->cq_head_db_reg);
++ io_cq->last_head_update = head;
++ }
+ }
+
+ return 0;
+--
+2.17.1
+
diff --git a/debian/patches/features/all/ena/net-ena-reimplement-set-get_coalesce.patch b/debian/patches/features/all/ena/net-ena-reimplement-set-get_coalesce.patch
new file mode 100644
index 000000000..c88ebef3a
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-reimplement-set-get_coalesce.patch
@@ -0,0 +1,158 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:28 +0300
+Subject: [PATCH] net: ena: reimplement set/get_coalesce()
+Origin: https://git.kernel.org/linus/b3db86dc4b82ffc63e33c78dafc09d5c78ac4fe4
+Bug-Debian: https://bugs.debian.org/941291
+
+1. Remove old adaptive interrupt moderation code from set/get_coalesce()
+2. Add ena_update_rx_rings_intr_moderation() function for updating
+ nonadaptive interrupt moderation intervals similarly to
+ ena_update_tx_rings_intr_moderation().
+3. Remove checks of multiple unsupported received interrupt coalescing
+ parameters. This makes code cleaner and cancels the need to update
+ it every time a new coalescing parameter is invented.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_ethtool.c | 84 ++++++-------------
+ 1 file changed, 26 insertions(+), 58 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c
+@@ -305,7 +305,6 @@ static int ena_get_coalesce(struct net_d
+ {
+ struct ena_adapter *adapter = netdev_priv(net_dev);
+ struct ena_com_dev *ena_dev = adapter->ena_dev;
+- struct ena_intr_moder_entry intr_moder_entry;
+
+ if (!ena_com_interrupt_moderation_supported(ena_dev)) {
+ /* the devie doesn't support interrupt moderation */
+@@ -314,23 +313,12 @@ static int ena_get_coalesce(struct net_d
+ coalesce->tx_coalesce_usecs =
+ ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) /
+ ena_dev->intr_delay_resolution;
+- if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) {
++
++ if (!ena_com_get_adaptive_moderation_enabled(ena_dev))
+ coalesce->rx_coalesce_usecs =
+ ena_com_get_nonadaptive_moderation_interval_rx(ena_dev)
+ / ena_dev->intr_delay_resolution;
+- } else {
+- ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_LOWEST, &intr_moder_entry);
+- coalesce->rx_coalesce_usecs_low = intr_moder_entry.intr_moder_interval;
+- coalesce->rx_max_coalesced_frames_low = intr_moder_entry.pkts_per_interval;
+-
+- ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_MID, &intr_moder_entry);
+- coalesce->rx_coalesce_usecs = intr_moder_entry.intr_moder_interval;
+- coalesce->rx_max_coalesced_frames = intr_moder_entry.pkts_per_interval;
+-
+- ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_HIGHEST, &intr_moder_entry);
+- coalesce->rx_coalesce_usecs_high = intr_moder_entry.intr_moder_interval;
+- coalesce->rx_max_coalesced_frames_high = intr_moder_entry.pkts_per_interval;
+- }
++
+ coalesce->use_adaptive_rx_coalesce =
+ ena_com_get_adaptive_moderation_enabled(ena_dev);
+
+@@ -348,12 +336,22 @@ static void ena_update_tx_rings_intr_mod
+ adapter->tx_ring[i].smoothed_interval = val;
+ }
+
++static void ena_update_rx_rings_intr_moderation(struct ena_adapter *adapter)
++{
++ unsigned int val;
++ int i;
++
++ val = ena_com_get_nonadaptive_moderation_interval_rx(adapter->ena_dev);
++
++ for (i = 0; i < adapter->num_queues; i++)
++ adapter->rx_ring[i].smoothed_interval = val;
++}
++
+ static int ena_set_coalesce(struct net_device *net_dev,
+ struct ethtool_coalesce *coalesce)
+ {
+ struct ena_adapter *adapter = netdev_priv(net_dev);
+ struct ena_com_dev *ena_dev = adapter->ena_dev;
+- struct ena_intr_moder_entry intr_moder_entry;
+ int rc;
+
+ if (!ena_com_interrupt_moderation_supported(ena_dev)) {
+@@ -361,22 +359,6 @@ static int ena_set_coalesce(struct net_d
+ return -EOPNOTSUPP;
+ }
+
+- if (coalesce->rx_coalesce_usecs_irq ||
+- coalesce->rx_max_coalesced_frames_irq ||
+- coalesce->tx_coalesce_usecs_irq ||
+- coalesce->tx_max_coalesced_frames ||
+- coalesce->tx_max_coalesced_frames_irq ||
+- coalesce->stats_block_coalesce_usecs ||
+- coalesce->use_adaptive_tx_coalesce ||
+- coalesce->pkt_rate_low ||
+- coalesce->tx_coalesce_usecs_low ||
+- coalesce->tx_max_coalesced_frames_low ||
+- coalesce->pkt_rate_high ||
+- coalesce->tx_coalesce_usecs_high ||
+- coalesce->tx_max_coalesced_frames_high ||
+- coalesce->rate_sample_interval)
+- return -EINVAL;
+-
+ rc = ena_com_update_nonadaptive_moderation_interval_tx(ena_dev,
+ coalesce->tx_coalesce_usecs);
+ if (rc)
+@@ -384,37 +366,23 @@ static int ena_set_coalesce(struct net_d
+
+ ena_update_tx_rings_intr_moderation(adapter);
+
+- if (ena_com_get_adaptive_moderation_enabled(ena_dev)) {
+- if (!coalesce->use_adaptive_rx_coalesce) {
+- ena_com_disable_adaptive_moderation(ena_dev);
+- rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev,
+- coalesce->rx_coalesce_usecs);
+- return rc;
+- }
+- } else { /* was in non-adaptive mode */
+- if (coalesce->use_adaptive_rx_coalesce) {
++ if (coalesce->use_adaptive_rx_coalesce) {
++ if (!ena_com_get_adaptive_moderation_enabled(ena_dev))
+ ena_com_enable_adaptive_moderation(ena_dev);
+- } else {
+- rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev,
+- coalesce->rx_coalesce_usecs);
+- return rc;
+- }
++ return 0;
+ }
+
+- intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs_low;
+- intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames_low;
+- intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED;
+- ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_LOWEST, &intr_moder_entry);
+-
+- intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs;
+- intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames;
+- intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED;
+- ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_MID, &intr_moder_entry);
+-
+- intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs_high;
+- intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames_high;
+- intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED;
+- ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_HIGHEST, &intr_moder_entry);
++ rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev,
++ coalesce->rx_coalesce_usecs);
++ if (rc)
++ return rc;
++
++ ena_update_rx_rings_intr_moderation(adapter);
++
++ if (!coalesce->use_adaptive_rx_coalesce) {
++ if (ena_com_get_adaptive_moderation_enabled(ena_dev))
++ ena_com_disable_adaptive_moderation(ena_dev);
++ }
+
+ return 0;
+ }
diff --git a/debian/patches/features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch b/debian/patches/features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch
new file mode 100644
index 000000000..2f3c2839d
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch
@@ -0,0 +1,361 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:33 +0300
+Subject: [PATCH] net: ena: remove all old adaptive rx interrupt moderation
+ code from ena_com
+Origin: https://git.kernel.org/linus/3ced8cbdf7ddb3160ffa714a91040dd18f39a12c
+Bug-Debian: https://bugs.debian.org/941291
+
+Remove previous implementation of adaptive rx interrupt moderation
+from ena_com files.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 110 -----------------
+ drivers/net/ethernet/amazon/ena/ena_com.h | 142 ----------------------
+ 2 files changed, 252 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -1278,22 +1278,6 @@ static int ena_com_ind_tbl_convert_from_
+ return 0;
+ }
+
+-static int ena_com_init_interrupt_moderation_table(struct ena_com_dev *ena_dev)
+-{
+- size_t size;
+-
+- size = sizeof(struct ena_intr_moder_entry) * ENA_INTR_MAX_NUM_OF_LEVELS;
+-
+- ena_dev->intr_moder_tbl =
+- devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL);
+- if (!ena_dev->intr_moder_tbl)
+- return -ENOMEM;
+-
+- ena_com_config_default_interrupt_moderation_table(ena_dev);
+-
+- return 0;
+-}
+-
+ static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev,
+ u16 intr_delay_resolution)
+ {
+@@ -2802,13 +2786,6 @@ int ena_com_update_nonadaptive_moderatio
+ &ena_dev->intr_moder_rx_interval);
+ }
+
+-void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev)
+-{
+- if (ena_dev->intr_moder_tbl)
+- devm_kfree(ena_dev->dmadev, ena_dev->intr_moder_tbl);
+- ena_dev->intr_moder_tbl = NULL;
+-}
+-
+ int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev)
+ {
+ struct ena_admin_get_feat_resp get_resp;
+@@ -2833,10 +2810,6 @@ int ena_com_init_interrupt_moderation(st
+ return rc;
+ }
+
+- rc = ena_com_init_interrupt_moderation_table(ena_dev);
+- if (rc)
+- goto err;
+-
+ /* if moderation is supported by device we set adaptive moderation */
+ delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution;
+ ena_com_update_intr_delay_resolution(ena_dev, delay_resolution);
+@@ -2845,52 +2818,6 @@ int ena_com_init_interrupt_moderation(st
+ ena_com_disable_adaptive_moderation(ena_dev);
+
+ return 0;
+-err:
+- ena_com_destroy_interrupt_moderation(ena_dev);
+- return rc;
+-}
+-
+-void ena_com_config_default_interrupt_moderation_table(struct ena_com_dev *ena_dev)
+-{
+- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+-
+- if (!intr_moder_tbl)
+- return;
+-
+- intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval =
+- ENA_INTR_LOWEST_USECS;
+- intr_moder_tbl[ENA_INTR_MODER_LOWEST].pkts_per_interval =
+- ENA_INTR_LOWEST_PKTS;
+- intr_moder_tbl[ENA_INTR_MODER_LOWEST].bytes_per_interval =
+- ENA_INTR_LOWEST_BYTES;
+-
+- intr_moder_tbl[ENA_INTR_MODER_LOW].intr_moder_interval =
+- ENA_INTR_LOW_USECS;
+- intr_moder_tbl[ENA_INTR_MODER_LOW].pkts_per_interval =
+- ENA_INTR_LOW_PKTS;
+- intr_moder_tbl[ENA_INTR_MODER_LOW].bytes_per_interval =
+- ENA_INTR_LOW_BYTES;
+-
+- intr_moder_tbl[ENA_INTR_MODER_MID].intr_moder_interval =
+- ENA_INTR_MID_USECS;
+- intr_moder_tbl[ENA_INTR_MODER_MID].pkts_per_interval =
+- ENA_INTR_MID_PKTS;
+- intr_moder_tbl[ENA_INTR_MODER_MID].bytes_per_interval =
+- ENA_INTR_MID_BYTES;
+-
+- intr_moder_tbl[ENA_INTR_MODER_HIGH].intr_moder_interval =
+- ENA_INTR_HIGH_USECS;
+- intr_moder_tbl[ENA_INTR_MODER_HIGH].pkts_per_interval =
+- ENA_INTR_HIGH_PKTS;
+- intr_moder_tbl[ENA_INTR_MODER_HIGH].bytes_per_interval =
+- ENA_INTR_HIGH_BYTES;
+-
+- intr_moder_tbl[ENA_INTR_MODER_HIGHEST].intr_moder_interval =
+- ENA_INTR_HIGHEST_USECS;
+- intr_moder_tbl[ENA_INTR_MODER_HIGHEST].pkts_per_interval =
+- ENA_INTR_HIGHEST_PKTS;
+- intr_moder_tbl[ENA_INTR_MODER_HIGHEST].bytes_per_interval =
+- ENA_INTR_HIGHEST_BYTES;
+ }
+
+ unsigned int ena_com_get_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev)
+@@ -2903,43 +2830,6 @@ unsigned int ena_com_get_nonadaptive_mod
+ return ena_dev->intr_moder_rx_interval;
+ }
+
+-void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev,
+- enum ena_intr_moder_level level,
+- struct ena_intr_moder_entry *entry)
+-{
+- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+-
+- if (level >= ENA_INTR_MAX_NUM_OF_LEVELS)
+- return;
+-
+- intr_moder_tbl[level].intr_moder_interval = entry->intr_moder_interval;
+- if (ena_dev->intr_delay_resolution)
+- intr_moder_tbl[level].intr_moder_interval /=
+- ena_dev->intr_delay_resolution;
+- intr_moder_tbl[level].pkts_per_interval = entry->pkts_per_interval;
+-
+- /* use hardcoded value until ethtool supports bytecount parameter */
+- if (entry->bytes_per_interval != ENA_INTR_BYTE_COUNT_NOT_SUPPORTED)
+- intr_moder_tbl[level].bytes_per_interval = entry->bytes_per_interval;
+-}
+-
+-void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev,
+- enum ena_intr_moder_level level,
+- struct ena_intr_moder_entry *entry)
+-{
+- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+-
+- if (level >= ENA_INTR_MAX_NUM_OF_LEVELS)
+- return;
+-
+- entry->intr_moder_interval = intr_moder_tbl[level].intr_moder_interval;
+- if (ena_dev->intr_delay_resolution)
+- entry->intr_moder_interval *= ena_dev->intr_delay_resolution;
+- entry->pkts_per_interval =
+- intr_moder_tbl[level].pkts_per_interval;
+- entry->bytes_per_interval = intr_moder_tbl[level].bytes_per_interval;
+-}
+-
+ int ena_com_config_dev_mode(struct ena_com_dev *ena_dev,
+ struct ena_admin_feature_llq_desc *llq_features,
+ struct ena_llq_configurations *llq_default_cfg)
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h
+@@ -72,46 +72,13 @@
+ /*****************************************************************************/
+ /* ENA adaptive interrupt moderation settings */
+
+-#define ENA_INTR_LOWEST_USECS (0)
+-#define ENA_INTR_LOWEST_PKTS (3)
+-#define ENA_INTR_LOWEST_BYTES (2 * 1524)
+-
+-#define ENA_INTR_LOW_USECS (32)
+-#define ENA_INTR_LOW_PKTS (12)
+-#define ENA_INTR_LOW_BYTES (16 * 1024)
+-
+-#define ENA_INTR_MID_USECS (80)
+-#define ENA_INTR_MID_PKTS (48)
+-#define ENA_INTR_MID_BYTES (64 * 1024)
+-
+-#define ENA_INTR_HIGH_USECS (128)
+-#define ENA_INTR_HIGH_PKTS (96)
+-#define ENA_INTR_HIGH_BYTES (128 * 1024)
+-
+-#define ENA_INTR_HIGHEST_USECS (192)
+-#define ENA_INTR_HIGHEST_PKTS (128)
+-#define ENA_INTR_HIGHEST_BYTES (192 * 1024)
+-
+ #define ENA_INTR_INITIAL_TX_INTERVAL_USECS 196
+ #define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0
+-#define ENA_INTR_DELAY_OLD_VALUE_WEIGHT 6
+-#define ENA_INTR_DELAY_NEW_VALUE_WEIGHT 4
+-#define ENA_INTR_MODER_LEVEL_STRIDE 2
+-#define ENA_INTR_BYTE_COUNT_NOT_SUPPORTED 0xFFFFFF
+
+ #define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF
+
+ #define ENA_FEATURE_MAX_QUEUE_EXT_VER 1
+
+-enum ena_intr_moder_level {
+- ENA_INTR_MODER_LOWEST = 0,
+- ENA_INTR_MODER_LOW,
+- ENA_INTR_MODER_MID,
+- ENA_INTR_MODER_HIGH,
+- ENA_INTR_MODER_HIGHEST,
+- ENA_INTR_MAX_NUM_OF_LEVELS,
+-};
+-
+ struct ena_llq_configurations {
+ enum ena_admin_llq_header_location llq_header_location;
+ enum ena_admin_llq_ring_entry_size llq_ring_entry_size;
+@@ -120,12 +87,6 @@ struct ena_llq_configurations {
+ u16 llq_ring_entry_size_value;
+ };
+
+-struct ena_intr_moder_entry {
+- unsigned int intr_moder_interval;
+- unsigned int pkts_per_interval;
+- unsigned int bytes_per_interval;
+-};
+-
+ enum queue_direction {
+ ENA_COM_IO_QUEUE_DIRECTION_TX,
+ ENA_COM_IO_QUEUE_DIRECTION_RX
+@@ -920,11 +881,6 @@ int ena_com_execute_admin_command(struct
+ */
+ int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev);
+
+-/* ena_com_destroy_interrupt_moderation - Destroy interrupt moderation resources
+- * @ena_dev: ENA communication layer struct
+- */
+-void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev);
+-
+ /* ena_com_interrupt_moderation_supported - Return if interrupt moderation
+ * capability is supported by the device.
+ *
+@@ -932,12 +888,6 @@ void ena_com_destroy_interrupt_moderatio
+ */
+ bool ena_com_interrupt_moderation_supported(struct ena_com_dev *ena_dev);
+
+-/* ena_com_config_default_interrupt_moderation_table - Restore the interrupt
+- * moderation table back to the default parameters.
+- * @ena_dev: ENA communication layer struct
+- */
+-void ena_com_config_default_interrupt_moderation_table(struct ena_com_dev *ena_dev);
+-
+ /* ena_com_update_nonadaptive_moderation_interval_tx - Update the
+ * non-adaptive interval in Tx direction.
+ * @ena_dev: ENA communication layer struct
+@@ -974,29 +924,6 @@ unsigned int ena_com_get_nonadaptive_mod
+ */
+ unsigned int ena_com_get_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev);
+
+-/* ena_com_init_intr_moderation_entry - Update a single entry in the interrupt
+- * moderation table.
+- * @ena_dev: ENA communication layer struct
+- * @level: Interrupt moderation table level
+- * @entry: Entry value
+- *
+- * Update a single entry in the interrupt moderation table.
+- */
+-void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev,
+- enum ena_intr_moder_level level,
+- struct ena_intr_moder_entry *entry);
+-
+-/* ena_com_get_intr_moderation_entry - Init ena_intr_moder_entry.
+- * @ena_dev: ENA communication layer struct
+- * @level: Interrupt moderation table level
+- * @entry: Entry to fill.
+- *
+- * Initialize the entry according to the adaptive interrupt moderation table.
+- */
+-void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev,
+- enum ena_intr_moder_level level,
+- struct ena_intr_moder_entry *entry);
+-
+ /* ena_com_config_dev_mode - Configure the placement policy of the device.
+ * @ena_dev: ENA communication layer struct
+ * @llq_features: LLQ feature descriptor, retrieve via
+@@ -1022,75 +949,6 @@ static inline void ena_com_disable_adapt
+ ena_dev->adaptive_coalescing = false;
+ }
+
+-/* ena_com_calculate_interrupt_delay - Calculate new interrupt delay
+- * @ena_dev: ENA communication layer struct
+- * @pkts: Number of packets since the last update
+- * @bytes: Number of bytes received since the last update.
+- * @smoothed_interval: Returned interval
+- * @moder_tbl_idx: Current table level as input update new level as return
+- * value.
+- */
+-static inline void ena_com_calculate_interrupt_delay(struct ena_com_dev *ena_dev,
+- unsigned int pkts,
+- unsigned int bytes,
+- unsigned int *smoothed_interval,
+- unsigned int *moder_tbl_idx)
+-{
+- enum ena_intr_moder_level curr_moder_idx, new_moder_idx;
+- struct ena_intr_moder_entry *curr_moder_entry;
+- struct ena_intr_moder_entry *pred_moder_entry;
+- struct ena_intr_moder_entry *new_moder_entry;
+- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl;
+- unsigned int interval;
+-
+- /* We apply adaptive moderation on Rx path only.
+- * Tx uses static interrupt moderation.
+- */
+- if (!pkts || !bytes)
+- /* Tx interrupt, or spurious interrupt,
+- * in both cases we just use same delay values
+- */
+- return;
+-
+- curr_moder_idx = (enum ena_intr_moder_level)(*moder_tbl_idx);
+- if (unlikely(curr_moder_idx >= ENA_INTR_MAX_NUM_OF_LEVELS)) {
+- pr_err("Wrong moderation index %u\n", curr_moder_idx);
+- return;
+- }
+-
+- curr_moder_entry = &intr_moder_tbl[curr_moder_idx];
+- new_moder_idx = curr_moder_idx;
+-
+- if (curr_moder_idx == ENA_INTR_MODER_LOWEST) {
+- if ((pkts > curr_moder_entry->pkts_per_interval) ||
+- (bytes > curr_moder_entry->bytes_per_interval))
+- new_moder_idx =
+- (enum ena_intr_moder_level)(curr_moder_idx + ENA_INTR_MODER_LEVEL_STRIDE);
+- } else {
+- pred_moder_entry = &intr_moder_tbl[curr_moder_idx - ENA_INTR_MODER_LEVEL_STRIDE];
+-
+- if ((pkts <= pred_moder_entry->pkts_per_interval) ||
+- (bytes <= pred_moder_entry->bytes_per_interval))
+- new_moder_idx =
+- (enum ena_intr_moder_level)(curr_moder_idx - ENA_INTR_MODER_LEVEL_STRIDE);
+- else if ((pkts > curr_moder_entry->pkts_per_interval) ||
+- (bytes > curr_moder_entry->bytes_per_interval)) {
+- if (curr_moder_idx != ENA_INTR_MODER_HIGHEST)
+- new_moder_idx =
+- (enum ena_intr_moder_level)(curr_moder_idx + ENA_INTR_MODER_LEVEL_STRIDE);
+- }
+- }
+- new_moder_entry = &intr_moder_tbl[new_moder_idx];
+-
+- interval = new_moder_entry->intr_moder_interval;
+- *smoothed_interval = (
+- (interval * ENA_INTR_DELAY_NEW_VALUE_WEIGHT +
+- ENA_INTR_DELAY_OLD_VALUE_WEIGHT * (*smoothed_interval)) + 5) /
+- 10;
+-
+- *moder_tbl_idx = new_moder_idx;
+-}
+-
+ /* ena_com_update_intr_reg - Prepare interrupt register
+ * @intr_reg: interrupt register to update.
+ * @rx_delay_interval: Rx interval in usecs
diff --git a/debian/patches/features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch b/debian/patches/features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch
new file mode 100644
index 000000000..3dcad5609
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch
@@ -0,0 +1,71 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:30 +0300
+Subject: [PATCH] net: ena: remove code duplication in
+ ena_com_update_nonadaptive_moderation_interval _*()
+Origin: https://git.kernel.org/linus/57e3a5f24bb5bf265988e973a911845abcbf6a00
+Bug-Debian: https://bugs.debian.org/941291
+
+Remove code duplication in:
+ena_com_update_nonadaptive_moderation_interval_tx()
+ena_com_update_nonadaptive_moderation_interval_rx()
+functions.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 30 ++++++++++++-----------
+ 1 file changed, 16 insertions(+), 14 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -2772,32 +2772,34 @@ bool ena_com_interrupt_moderation_suppor
+ ENA_ADMIN_INTERRUPT_MODERATION);
+ }
+
+-int ena_com_update_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev,
+- u32 tx_coalesce_usecs)
++static int ena_com_update_nonadaptive_moderation_interval(u32 coalesce_usecs,
++ u32 intr_delay_resolution,
++ u32 *intr_moder_interval)
+ {
+- if (!ena_dev->intr_delay_resolution) {
++ if (!intr_delay_resolution) {
+ pr_err("Illegal interrupt delay granularity value\n");
+ return -EFAULT;
+ }
+
+- ena_dev->intr_moder_tx_interval = tx_coalesce_usecs /
+- ena_dev->intr_delay_resolution;
++ *intr_moder_interval = coalesce_usecs / intr_delay_resolution;
+
+ return 0;
+ }
+
++int ena_com_update_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev,
++ u32 tx_coalesce_usecs)
++{
++ return ena_com_update_nonadaptive_moderation_interval(tx_coalesce_usecs,
++ ena_dev->intr_delay_resolution,
++ &ena_dev->intr_moder_tx_interval);
++}
++
+ int ena_com_update_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev,
+ u32 rx_coalesce_usecs)
+ {
+- if (!ena_dev->intr_delay_resolution) {
+- pr_err("Illegal interrupt delay granularity value\n");
+- return -EFAULT;
+- }
+-
+- ena_dev->intr_moder_rx_interval = rx_coalesce_usecs /
+- ena_dev->intr_delay_resolution;
+-
+- return 0;
++ return ena_com_update_nonadaptive_moderation_interval(rx_coalesce_usecs,
++ ena_dev->intr_delay_resolution,
++ &ena_dev->intr_moder_rx_interval);
+ }
+
+ void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev)
diff --git a/debian/patches/features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch b/debian/patches/features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch
new file mode 100644
index 000000000..1dad10a1a
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch
@@ -0,0 +1,59 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:32 +0300
+Subject: [PATCH] net: ena: remove ena_restore_ethtool_params() and relevant
+ fields
+Origin: https://git.kernel.org/linus/64d1fb9dfc6c5d8589312fa847fee14ec14ee12b
+Bug-Debian: https://bugs.debian.org/941291
+
+Deleted unused 4 fields from struct ena_adapter and their only user
+ena_restore_ethtool_params().
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 ----------
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 3 ---
+ 2 files changed, 13 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -1564,14 +1564,6 @@ static void ena_napi_enable_all(struct e
+ napi_enable(&adapter->ena_napi[i].napi);
+ }
+
+-static void ena_restore_ethtool_params(struct ena_adapter *adapter)
+-{
+- adapter->tx_usecs = 0;
+- adapter->rx_usecs = 0;
+- adapter->tx_frames = 1;
+- adapter->rx_frames = 1;
+-}
+-
+ /* Configure the Rx forwarding */
+ static int ena_rss_configure(struct ena_adapter *adapter)
+ {
+@@ -1621,8 +1613,6 @@ static int ena_up_complete(struct ena_ad
+ /* enable transmits */
+ netif_tx_start_all_queues(adapter->netdev);
+
+- ena_restore_ethtool_params(adapter);
+-
+ ena_napi_enable_all(adapter);
+
+ return 0;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -330,9 +330,6 @@ struct ena_adapter {
+
+ u32 missing_tx_completion_threshold;
+
+- u32 tx_usecs, rx_usecs; /* interrupt moderation */
+- u32 tx_frames, rx_frames; /* interrupt moderation */
+-
+ u32 requested_tx_ring_size;
+ u32 requested_rx_ring_size;
+
diff --git a/debian/patches/features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch b/debian/patches/features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch
new file mode 100644
index 000000000..8d4a2b349
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch
@@ -0,0 +1,244 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Tue, 11 Jun 2019 14:58:10 +0300
+Subject: [PATCH] net: ena: remove inline keyword from functions in *.c
+Origin: https://git.kernel.org/linus/c2b542044761965db0e4cc400ab6abf670fc25b7
+Bug-Debian: https://bugs.debian.org/941291
+
+Let the compiler decide if the function should be inline in *.c files
+
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++---
+ drivers/net/ethernet/amazon/ena/ena_eth_com.c | 26 +++++++++----------
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 16 ++++++------
+ 3 files changed, 24 insertions(+), 24 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -91,7 +91,7 @@ struct ena_com_stats_ctx {
+ struct ena_admin_acq_get_stats_resp get_resp;
+ };
+
+-static inline int ena_com_mem_addr_set(struct ena_com_dev *ena_dev,
++static int ena_com_mem_addr_set(struct ena_com_dev *ena_dev,
+ struct ena_common_mem_addr *ena_addr,
+ dma_addr_t addr)
+ {
+@@ -190,7 +190,7 @@ static int ena_com_admin_init_aenq(struc
+ return 0;
+ }
+
+-static inline void comp_ctxt_release(struct ena_com_admin_queue *queue,
++static void comp_ctxt_release(struct ena_com_admin_queue *queue,
+ struct ena_comp_ctx *comp_ctx)
+ {
+ comp_ctx->occupied = false;
+@@ -277,7 +277,7 @@ static struct ena_comp_ctx *__ena_com_su
+ return comp_ctx;
+ }
+
+-static inline int ena_com_init_comp_ctxt(struct ena_com_admin_queue *queue)
++static int ena_com_init_comp_ctxt(struct ena_com_admin_queue *queue)
+ {
+ size_t size = queue->q_depth * sizeof(struct ena_comp_ctx);
+ struct ena_comp_ctx *comp_ctx;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c
+@@ -32,7 +32,7 @@
+
+ #include "ena_eth_com.h"
+
+-static inline struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc(
++static struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc(
+ struct ena_com_io_cq *io_cq)
+ {
+ struct ena_eth_io_rx_cdesc_base *cdesc;
+@@ -59,7 +59,7 @@ static inline struct ena_eth_io_rx_cdesc
+ return cdesc;
+ }
+
+-static inline void *get_sq_desc_regular_queue(struct ena_com_io_sq *io_sq)
++static void *get_sq_desc_regular_queue(struct ena_com_io_sq *io_sq)
+ {
+ u16 tail_masked;
+ u32 offset;
+@@ -71,7 +71,7 @@ static inline void *get_sq_desc_regular_
+ return (void *)((uintptr_t)io_sq->desc_addr.virt_addr + offset);
+ }
+
+-static inline int ena_com_write_bounce_buffer_to_dev(struct ena_com_io_sq *io_sq,
++static int ena_com_write_bounce_buffer_to_dev(struct ena_com_io_sq *io_sq,
+ u8 *bounce_buffer)
+ {
+ struct ena_com_llq_info *llq_info = &io_sq->llq_info;
+@@ -111,7 +111,7 @@ static inline int ena_com_write_bounce_b
+ return 0;
+ }
+
+-static inline int ena_com_write_header_to_bounce(struct ena_com_io_sq *io_sq,
++static int ena_com_write_header_to_bounce(struct ena_com_io_sq *io_sq,
+ u8 *header_src,
+ u16 header_len)
+ {
+@@ -142,7 +142,7 @@ static inline int ena_com_write_header_t
+ return 0;
+ }
+
+-static inline void *get_sq_desc_llq(struct ena_com_io_sq *io_sq)
++static void *get_sq_desc_llq(struct ena_com_io_sq *io_sq)
+ {
+ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl;
+ u8 *bounce_buffer;
+@@ -162,7 +162,7 @@ static inline void *get_sq_desc_llq(stru
+ return sq_desc;
+ }
+
+-static inline int ena_com_close_bounce_buffer(struct ena_com_io_sq *io_sq)
++static int ena_com_close_bounce_buffer(struct ena_com_io_sq *io_sq)
+ {
+ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl;
+ struct ena_com_llq_info *llq_info = &io_sq->llq_info;
+@@ -189,7 +189,7 @@ static inline int ena_com_close_bounce_b
+ return 0;
+ }
+
+-static inline void *get_sq_desc(struct ena_com_io_sq *io_sq)
++static void *get_sq_desc(struct ena_com_io_sq *io_sq)
+ {
+ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+ return get_sq_desc_llq(io_sq);
+@@ -197,7 +197,7 @@ static inline void *get_sq_desc(struct e
+ return get_sq_desc_regular_queue(io_sq);
+ }
+
+-static inline int ena_com_sq_update_llq_tail(struct ena_com_io_sq *io_sq)
++static int ena_com_sq_update_llq_tail(struct ena_com_io_sq *io_sq)
+ {
+ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl;
+ struct ena_com_llq_info *llq_info = &io_sq->llq_info;
+@@ -225,7 +225,7 @@ static inline int ena_com_sq_update_llq_
+ return 0;
+ }
+
+-static inline int ena_com_sq_update_tail(struct ena_com_io_sq *io_sq)
++static int ena_com_sq_update_tail(struct ena_com_io_sq *io_sq)
+ {
+ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV)
+ return ena_com_sq_update_llq_tail(io_sq);
+@@ -239,7 +239,7 @@ static inline int ena_com_sq_update_tail
+ return 0;
+ }
+
+-static inline struct ena_eth_io_rx_cdesc_base *
++static struct ena_eth_io_rx_cdesc_base *
+ ena_com_rx_cdesc_idx_to_ptr(struct ena_com_io_cq *io_cq, u16 idx)
+ {
+ idx &= (io_cq->q_depth - 1);
+@@ -248,7 +248,7 @@ static inline struct ena_eth_io_rx_cdesc
+ idx * io_cq->cdesc_entry_size_in_bytes);
+ }
+
+-static inline u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
++static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq,
+ u16 *first_cdesc_idx)
+ {
+ struct ena_eth_io_rx_cdesc_base *cdesc;
+@@ -285,7 +285,7 @@ static inline u16 ena_com_cdesc_rx_pkt_g
+ return count;
+ }
+
+-static inline int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
++static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq,
+ struct ena_com_tx_ctx *ena_tx_ctx)
+ {
+ struct ena_eth_io_tx_meta_desc *meta_desc = NULL;
+@@ -334,7 +334,7 @@ static inline int ena_com_create_and_sto
+ return ena_com_sq_update_tail(io_sq);
+ }
+
+-static inline void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx,
++static void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx,
+ struct ena_eth_io_rx_cdesc_base *cdesc)
+ {
+ ena_rx_ctx->l3_proto = cdesc->status &
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -326,7 +326,7 @@ static void ena_free_all_io_tx_resources
+ ena_free_tx_resources(adapter, i);
+ }
+
+-static inline int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id)
++static int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id)
+ {
+ if (likely(req_id < rx_ring->ring_size))
+ return 0;
+@@ -460,7 +460,7 @@ static void ena_free_all_io_rx_resources
+ ena_free_rx_resources(adapter, i);
+ }
+
+-static inline int ena_alloc_rx_page(struct ena_ring *rx_ring,
++static int ena_alloc_rx_page(struct ena_ring *rx_ring,
+ struct ena_rx_buffer *rx_info, gfp_t gfp)
+ {
+ struct ena_com_buf *ena_buf;
+@@ -620,7 +620,7 @@ static void ena_free_all_rx_bufs(struct
+ ena_free_rx_bufs(adapter, i);
+ }
+
+-static inline void ena_unmap_tx_skb(struct ena_ring *tx_ring,
++static void ena_unmap_tx_skb(struct ena_ring *tx_ring,
+ struct ena_tx_buffer *tx_info)
+ {
+ struct ena_com_buf *ena_buf;
+@@ -956,7 +956,7 @@ static struct sk_buff *ena_rx_skb(struct
+ * @ena_rx_ctx: received packet context/metadata
+ * @skb: skb currently being received and modified
+ */
+-static inline void ena_rx_checksum(struct ena_ring *rx_ring,
++static void ena_rx_checksum(struct ena_ring *rx_ring,
+ struct ena_com_rx_ctx *ena_rx_ctx,
+ struct sk_buff *skb)
+ {
+@@ -1156,7 +1156,7 @@ error:
+ return 0;
+ }
+
+-inline void ena_adjust_intr_moderation(struct ena_ring *rx_ring,
++void ena_adjust_intr_moderation(struct ena_ring *rx_ring,
+ struct ena_ring *tx_ring)
+ {
+ /* We apply adaptive moderation on Rx path only.
+@@ -1175,7 +1175,7 @@ inline void ena_adjust_intr_moderation(s
+ rx_ring->per_napi_bytes = 0;
+ }
+
+-static inline void ena_unmask_interrupt(struct ena_ring *tx_ring,
++static void ena_unmask_interrupt(struct ena_ring *tx_ring,
+ struct ena_ring *rx_ring)
+ {
+ struct ena_eth_io_intr_reg intr_reg;
+@@ -1195,7 +1195,7 @@ static inline void ena_unmask_interrupt(
+ ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg);
+ }
+
+-static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring,
++static void ena_update_ring_numa_node(struct ena_ring *tx_ring,
+ struct ena_ring *rx_ring)
+ {
+ int cpu = get_cpu();
+@@ -3331,7 +3331,7 @@ static void ena_release_bars(struct ena_
+ pci_release_selected_regions(pdev, release_bars);
+ }
+
+-static inline void set_default_llq_configurations(struct ena_llq_configurations *llq_config)
++static void set_default_llq_configurations(struct ena_llq_configurations *llq_config)
+ {
+ llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER;
+ llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B;
diff --git a/debian/patches/features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch b/debian/patches/features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch
new file mode 100644
index 000000000..17cb06e09
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch
@@ -0,0 +1,83 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:31 +0300
+Subject: [PATCH] net: ena: remove old adaptive interrupt moderation code from
+ ena_netdev
+Origin: https://git.kernel.org/linus/242d81fd3dd9f301b0c20564aafec8efdb2bbe5b
+Bug-Debian: https://bugs.debian.org/941291
+
+1. Out of the fields {per_napi_bytes, per_napi_packets} in struct ena_ring,
+ only rx_ring->per_napi_packets are used to determine if napi did work
+ for dim.
+ This commit removes all other uses of these fields.
+2. Remove ena_ring->moder_tbl_idx, which is not used by dim.
+3. Remove all calls to ena_com_destroy_interrupt_moderation(), since all it
+ did was to destroy the interrupt moderation table, which is removed as
+ part of removing old interrupt moderation code.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 8 --------
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 --
+ 2 files changed, 10 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -158,7 +158,6 @@ static void ena_init_io_rings_common(str
+ ring->adapter = adapter;
+ ring->ena_dev = adapter->ena_dev;
+ ring->per_napi_packets = 0;
+- ring->per_napi_bytes = 0;
+ ring->cpu = 0;
+ ring->first_interrupt = false;
+ ring->no_interrupt_event_cnt = 0;
+@@ -835,9 +834,6 @@ static int ena_clean_tx_irq(struct ena_r
+ __netif_tx_unlock(txq);
+ }
+
+- tx_ring->per_napi_bytes += tx_bytes;
+- tx_ring->per_napi_packets += tx_pkts;
+-
+ return tx_pkts;
+ }
+
+@@ -1121,7 +1117,6 @@ static int ena_clean_rx_irq(struct ena_r
+ } while (likely(res_budget));
+
+ work_done = budget - res_budget;
+- rx_ring->per_napi_bytes += total_len;
+ rx_ring->per_napi_packets += work_done;
+ u64_stats_update_begin(&rx_ring->syncp);
+ rx_ring->rx_stats.bytes += total_len;
+@@ -3643,7 +3638,6 @@ err_free_msix:
+ ena_free_mgmnt_irq(adapter);
+ ena_disable_msix(adapter);
+ err_worker_destroy:
+- ena_com_destroy_interrupt_moderation(ena_dev);
+ del_timer(&adapter->timer_service);
+ err_netdev_destroy:
+ free_netdev(netdev);
+@@ -3704,8 +3698,6 @@ static void ena_remove(struct pci_dev *p
+
+ pci_disable_device(pdev);
+
+- ena_com_destroy_interrupt_moderation(ena_dev);
+-
+ vfree(ena_dev);
+ }
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -280,8 +280,6 @@ struct ena_ring {
+ struct ena_com_rx_buf_info ena_bufs[ENA_PKT_MAX_BUFS];
+ u32 smoothed_interval;
+ u32 per_napi_packets;
+- u32 per_napi_bytes;
+- enum ena_intr_moder_level moder_tbl_idx;
+ u16 non_empty_napi_events;
+ struct u64_stats_sync syncp;
+ union {
diff --git a/debian/patches/features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch b/debian/patches/features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch
new file mode 100644
index 000000000..c63ce87c6
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch
@@ -0,0 +1,198 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:21 +0300
+Subject: [PATCH] net: ena: replace free_tx/rx_ids union with single free_ids
+ field in ena_ring
+Origin: https://git.kernel.org/linus/f917249833c7a00ea8be39b1bcb3ec8ef3aea45f
+Bug-Debian: https://bugs.debian.org/941291
+
+struct ena_ring holds a union of free_rx_ids and free_tx_ids.
+Both of the above fields mean the exact same thing and are used
+exactly the same way.
+Furthermore, these fields are always used with a prefix of the
+type of ring. So for tx it will be tx_ring->free_tx_ids, and for
+rx it will be rx_ring->free_rx_ids, which shows how redundant the
+"_tx" and "_rx" parts are.
+Furthermore still, this may lead to confusing code like where
+tx_ring->free_rx_ids which works correctly but looks like a mess.
+
+This commit removes the aforementioned redundancy by replacing the
+free_rx/tx_ids union with a single free_ids field.
+It also changes a single goto label name from err_free_tx_ids: to
+err_tx_free_ids: for consistency with the above new notation.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 48 ++++++++++----------
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 11 ++---
+ 2 files changed, 28 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+index 33fab4f41d7c..b80b5eddca91 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -228,11 +228,11 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
+ }
+
+ size = sizeof(u16) * tx_ring->ring_size;
+- tx_ring->free_tx_ids = vzalloc_node(size, node);
+- if (!tx_ring->free_tx_ids) {
+- tx_ring->free_tx_ids = vzalloc(size);
+- if (!tx_ring->free_tx_ids)
+- goto err_free_tx_ids;
++ tx_ring->free_ids = vzalloc_node(size, node);
++ if (!tx_ring->free_ids) {
++ tx_ring->free_ids = vzalloc(size);
++ if (!tx_ring->free_ids)
++ goto err_tx_free_ids;
+ }
+
+ size = tx_ring->tx_max_header_size;
+@@ -245,7 +245,7 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
+
+ /* Req id ring for TX out of order completions */
+ for (i = 0; i < tx_ring->ring_size; i++)
+- tx_ring->free_tx_ids[i] = i;
++ tx_ring->free_ids[i] = i;
+
+ /* Reset tx statistics */
+ memset(&tx_ring->tx_stats, 0x0, sizeof(tx_ring->tx_stats));
+@@ -256,9 +256,9 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
+ return 0;
+
+ err_push_buf_intermediate_buf:
+- vfree(tx_ring->free_tx_ids);
+- tx_ring->free_tx_ids = NULL;
+-err_free_tx_ids:
++ vfree(tx_ring->free_ids);
++ tx_ring->free_ids = NULL;
++err_tx_free_ids:
+ vfree(tx_ring->tx_buffer_info);
+ tx_ring->tx_buffer_info = NULL;
+ err_tx_buffer_info:
+@@ -278,8 +278,8 @@ static void ena_free_tx_resources(struct ena_adapter *adapter, int qid)
+ vfree(tx_ring->tx_buffer_info);
+ tx_ring->tx_buffer_info = NULL;
+
+- vfree(tx_ring->free_tx_ids);
+- tx_ring->free_tx_ids = NULL;
++ vfree(tx_ring->free_ids);
++ tx_ring->free_ids = NULL;
+
+ vfree(tx_ring->push_buf_intermediate_buf);
+ tx_ring->push_buf_intermediate_buf = NULL;
+@@ -377,10 +377,10 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter,
+ }
+
+ size = sizeof(u16) * rx_ring->ring_size;
+- rx_ring->free_rx_ids = vzalloc_node(size, node);
+- if (!rx_ring->free_rx_ids) {
+- rx_ring->free_rx_ids = vzalloc(size);
+- if (!rx_ring->free_rx_ids) {
++ rx_ring->free_ids = vzalloc_node(size, node);
++ if (!rx_ring->free_ids) {
++ rx_ring->free_ids = vzalloc(size);
++ if (!rx_ring->free_ids) {
+ vfree(rx_ring->rx_buffer_info);
+ rx_ring->rx_buffer_info = NULL;
+ return -ENOMEM;
+@@ -389,7 +389,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter,
+
+ /* Req id ring for receiving RX pkts out of order */
+ for (i = 0; i < rx_ring->ring_size; i++)
+- rx_ring->free_rx_ids[i] = i;
++ rx_ring->free_ids[i] = i;
+
+ /* Reset rx statistics */
+ memset(&rx_ring->rx_stats, 0x0, sizeof(rx_ring->rx_stats));
+@@ -415,8 +415,8 @@ static void ena_free_rx_resources(struct ena_adapter *adapter,
+ vfree(rx_ring->rx_buffer_info);
+ rx_ring->rx_buffer_info = NULL;
+
+- vfree(rx_ring->free_rx_ids);
+- rx_ring->free_rx_ids = NULL;
++ vfree(rx_ring->free_ids);
++ rx_ring->free_ids = NULL;
+ }
+
+ /* ena_setup_all_rx_resources - allocate I/O Rx queues resources for all queues
+@@ -531,7 +531,7 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num)
+ for (i = 0; i < num; i++) {
+ struct ena_rx_buffer *rx_info;
+
+- req_id = rx_ring->free_rx_ids[next_to_use];
++ req_id = rx_ring->free_ids[next_to_use];
+ rc = validate_rx_req_id(rx_ring, req_id);
+ if (unlikely(rc < 0))
+ break;
+@@ -797,7 +797,7 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget)
+ tx_pkts++;
+ total_done += tx_info->tx_descs;
+
+- tx_ring->free_tx_ids[next_to_clean] = req_id;
++ tx_ring->free_ids[next_to_clean] = req_id;
+ next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean,
+ tx_ring->ring_size);
+ }
+@@ -911,7 +911,7 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
+
+ skb_put(skb, len);
+ skb->protocol = eth_type_trans(skb, rx_ring->netdev);
+- rx_ring->free_rx_ids[*next_to_clean] = req_id;
++ rx_ring->free_ids[*next_to_clean] = req_id;
+ *next_to_clean = ENA_RX_RING_IDX_ADD(*next_to_clean, descs,
+ rx_ring->ring_size);
+ return skb;
+@@ -935,7 +935,7 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
+
+ rx_info->page = NULL;
+
+- rx_ring->free_rx_ids[*next_to_clean] = req_id;
++ rx_ring->free_ids[*next_to_clean] = req_id;
+ *next_to_clean =
+ ENA_RX_RING_IDX_NEXT(*next_to_clean,
+ rx_ring->ring_size);
+@@ -1088,7 +1088,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi,
+ /* exit if we failed to retrieve a buffer */
+ if (unlikely(!skb)) {
+ for (i = 0; i < ena_rx_ctx.descs; i++) {
+- rx_ring->free_tx_ids[next_to_clean] =
++ rx_ring->free_ids[next_to_clean] =
+ rx_ring->ena_bufs[i].req_id;
+ next_to_clean =
+ ENA_RX_RING_IDX_NEXT(next_to_clean,
+@@ -2152,7 +2152,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ skb_tx_timestamp(skb);
+
+ next_to_use = tx_ring->next_to_use;
+- req_id = tx_ring->free_tx_ids[next_to_use];
++ req_id = tx_ring->free_ids[next_to_use];
+ tx_info = &tx_ring->tx_buffer_info[req_id];
+ tx_info->num_of_bufs = 0;
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+index 0681e18b0019..74c316081499 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -221,13 +221,10 @@ struct ena_stats_rx {
+ };
+
+ struct ena_ring {
+- union {
+- /* Holds the empty requests for TX/RX
+- * out of order completions
+- */
+- u16 *free_tx_ids;
+- u16 *free_rx_ids;
+- };
++ /* Holds the empty requests for TX/RX
++ * out of order completions
++ */
++ u16 *free_ids;
+
+ union {
+ struct ena_tx_buffer *tx_buffer_info;
+--
+2.17.1
+
diff --git a/debian/patches/features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch b/debian/patches/features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch
new file mode 100644
index 000000000..eb5269408
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch
@@ -0,0 +1,163 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 16 Sep 2019 14:31:27 +0300
+Subject: [PATCH] net: ena: switch to dim algorithm for rx adaptive interrupt
+ moderation
+Origin: https://git.kernel.org/linus/282faf61a053be43910fcc42d86ecf16c0d30123
+Bug-Debian: https://bugs.debian.org/941291
+
+Use the dim library for the rx adaptive interrupt moderation implementation
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_com.c | 4 +-
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 55 +++++++++++++-------
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 3 ++
+ 3 files changed, 41 insertions(+), 21 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c
+@@ -2839,9 +2839,7 @@ int ena_com_init_interrupt_moderation(st
+ delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution;
+ ena_com_update_intr_delay_resolution(ena_dev, delay_resolution);
+
+- /* Disable adaptive moderation by default - can be enabled from
+- * ethtool
+- */
++ /* Disable adaptive moderation by default - can be enabled later */
+ ena_com_disable_adaptive_moderation(ena_dev);
+
+ return 0;
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -196,6 +196,7 @@ static void ena_init_io_rings(struct ena
+ rxr->smoothed_interval =
+ ena_com_get_nonadaptive_moderation_interval_rx(ena_dev);
+ rxr->empty_rx_queue = 0;
++ adapter->ena_napi[i].dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
+ }
+ }
+
+@@ -712,6 +713,7 @@ static void ena_destroy_all_rx_queues(st
+
+ for (i = 0; i < adapter->num_queues; i++) {
+ ena_qid = ENA_IO_RXQ_IDX(i);
++ cancel_work_sync(&adapter->ena_napi[i].dim.work);
+ ena_com_destroy_io_queue(adapter->ena_dev, ena_qid);
+ }
+ }
+@@ -1156,23 +1158,35 @@ error:
+ return 0;
+ }
+
+-void ena_adjust_intr_moderation(struct ena_ring *rx_ring,
+- struct ena_ring *tx_ring)
++static void ena_dim_work(struct work_struct *w)
+ {
+- /* We apply adaptive moderation on Rx path only.
+- * Tx uses static interrupt moderation.
+- */
+- ena_com_calculate_interrupt_delay(rx_ring->ena_dev,
+- rx_ring->per_napi_packets,
+- rx_ring->per_napi_bytes,
+- &rx_ring->smoothed_interval,
+- &rx_ring->moder_tbl_idx);
+-
+- /* Reset per napi packets/bytes */
+- tx_ring->per_napi_packets = 0;
+- tx_ring->per_napi_bytes = 0;
++ struct net_dim *dim = container_of(w, struct net_dim, work);
++ struct net_dim_cq_moder cur_moder =
++ net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
++ struct ena_napi *ena_napi = container_of(dim, struct ena_napi, dim);
++
++ ena_napi->rx_ring->smoothed_interval = cur_moder.usec;
++ dim->state = NET_DIM_START_MEASURE;
++}
++
++static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi)
++{
++ struct net_dim_sample dim_sample;
++ struct ena_ring *rx_ring = ena_napi->rx_ring;
++
++ if (!rx_ring->per_napi_packets)
++ return;
++
++ rx_ring->non_empty_napi_events++;
++
++ net_dim_sample(rx_ring->non_empty_napi_events,
++ rx_ring->rx_stats.cnt,
++ rx_ring->rx_stats.bytes,
++ &dim_sample);
++
++ net_dim(&ena_napi->dim, dim_sample);
++
+ rx_ring->per_napi_packets = 0;
+- rx_ring->per_napi_bytes = 0;
+ }
+
+ static void ena_unmask_interrupt(struct ena_ring *tx_ring,
+@@ -1261,9 +1275,11 @@ static int ena_io_poll(struct napi_struc
+ * from the interrupt context (vs from sk_busy_loop)
+ */
+ if (napi_complete_done(napi, rx_work_done)) {
+- /* Tx and Rx share the same interrupt vector */
++ /* We apply adaptive moderation on Rx path only.
++ * Tx uses static interrupt moderation.
++ */
+ if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev))
+- ena_adjust_intr_moderation(rx_ring, tx_ring);
++ ena_adjust_adaptive_rx_intr_moderation(ena_napi);
+
+ ena_unmask_interrupt(tx_ring, rx_ring);
+ }
+@@ -1741,13 +1757,16 @@ static int ena_create_all_io_rx_queues(s
+ rc = ena_create_io_rx_queue(adapter, i);
+ if (rc)
+ goto create_err;
++ INIT_WORK(&adapter->ena_napi[i].dim.work, ena_dim_work);
+ }
+
+ return 0;
+
+ create_err:
+- while (i--)
++ while (i--) {
++ cancel_work_sync(&adapter->ena_napi[i].dim.work);
+ ena_com_destroy_io_queue(ena_dev, ENA_IO_RXQ_IDX(i));
++ }
+
+ return rc;
+ }
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -34,6 +34,7 @@
+ #define ENA_H
+
+ #include <linux/bitops.h>
++#include <linux/net_dim.h>
+ #include <linux/etherdevice.h>
+ #include <linux/inetdevice.h>
+ #include <linux/interrupt.h>
+@@ -153,6 +154,7 @@ struct ena_napi {
+ struct ena_ring *tx_ring;
+ struct ena_ring *rx_ring;
+ u32 qid;
++ struct net_dim dim;
+ };
+
+ struct ena_calc_queue_size_ctx {
+@@ -280,6 +282,7 @@ struct ena_ring {
+ u32 per_napi_packets;
+ u32 per_napi_bytes;
+ enum ena_intr_moder_level moder_tbl_idx;
++ u16 non_empty_napi_events;
+ struct u64_stats_sync syncp;
+ union {
+ struct ena_stats_tx tx_stats;
diff --git a/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch
new file mode 100644
index 000000000..7b3fd73ce
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch
@@ -0,0 +1,27 @@
+From: Arthur Kiyanovski <akiyano@amazon.com>
+Date: Mon, 11 Feb 2019 19:17:44 +0200
+Subject: [PATCH] net: ena: update driver version from 2.0.2 to 2.0.3
+Origin: https://git.kernel.org/linus/d9b8656da92223eb004b4f4db74fe48e7433f7b2
+Bug-Debian: https://bugs.debian.org/941291
+
+Update driver version due to bug fix.
+
+Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -45,7 +45,7 @@
+
+ #define DRV_MODULE_VER_MAJOR 2
+ #define DRV_MODULE_VER_MINOR 0
+-#define DRV_MODULE_VER_SUBMINOR 2
++#define DRV_MODULE_VER_SUBMINOR 3
+
+ #define DRV_MODULE_NAME "ena"
+ #ifndef DRV_MODULE_VERSION
diff --git a/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch
new file mode 100644
index 000000000..9a62b79ac
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch
@@ -0,0 +1,32 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Tue, 11 Jun 2019 14:58:11 +0300
+Subject: [PATCH] net: ena: update driver version from 2.0.3 to 2.1.0
+Origin: https://git.kernel.org/linus/dbbc6e6877768a03092751edf89d012d561b4553
+Bug-Debian: https://bugs.debian.org/941291
+
+Update driver version to match device specification.
+
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+index b9d590879815..f2b6e2e0504d 100644
+--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h
++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h
+@@ -44,8 +44,8 @@
+ #include "ena_eth_com.h"
+
+ #define DRV_MODULE_VER_MAJOR 2
+-#define DRV_MODULE_VER_MINOR 0
+-#define DRV_MODULE_VER_SUBMINOR 3
++#define DRV_MODULE_VER_MINOR 1
++#define DRV_MODULE_VER_SUBMINOR 0
+
+ #define DRV_MODULE_NAME "ena"
+ #ifndef DRV_MODULE_VERSION
+--
+2.17.1
+
diff --git a/debian/patches/features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch b/debian/patches/features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch
new file mode 100644
index 000000000..8b3a55e8d
--- /dev/null
+++ b/debian/patches/features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch
@@ -0,0 +1,34 @@
+From: Sameeh Jubran <sameehj@amazon.com>
+Date: Mon, 3 Jun 2019 17:43:29 +0300
+Subject: [PATCH] net: ena: use dev_info_once instead of static variable
+Origin: https://git.kernel.org/linus/1e9c3fbad83a70e0b00806df3f4dd2db0bc04cc4
+Bug-Debian: https://bugs.debian.org/941291
+
+Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+===================================================================
+--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
+@@ -3277,7 +3277,6 @@ static int ena_probe(struct pci_dev *pde
+ struct ena_llq_configurations llq_config;
+ struct ena_com_dev *ena_dev = NULL;
+ struct ena_adapter *adapter;
+- static int version_printed;
+ int io_queue_num, bars, rc;
+ struct net_device *netdev;
+ static int adapters_found;
+@@ -3289,8 +3288,7 @@ static int ena_probe(struct pci_dev *pde
+
+ dev_dbg(&pdev->dev, "%s\n", __func__);
+
+- if (version_printed++ == 0)
+- dev_info(&pdev->dev, "%s", version);
++ dev_info_once(&pdev->dev, "%s", version);
+
+ rc = pci_enable_device_mem(pdev);
+ if (rc) {
diff --git a/debian/patches/features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch b/debian/patches/features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch
new file mode 100644
index 000000000..9a8cd7c82
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch
@@ -0,0 +1,164 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:31 +0000
+Subject: [01/29] Add the ability to lock down access to the running kernel
+ image
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=6d350e2534bfaaaa3e523484b2ca44d22377e951
+
+Provide a single call to allow kernel code to determine whether the system
+should be locked down, thereby disallowing various accesses that might
+allow the running kernel image to be changed including the loading of
+modules that aren't validly signed with a key we recognise, fiddling with
+MSR registers and disallowing hibernation,
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: James Morris <james.l.morris@oracle.com>
+---
+ include/linux/kernel.h | 17 ++++++++++++++
+ include/linux/security.h | 8 +++++++
+ security/Kconfig | 8 +++++++
+ security/Makefile | 3 +++
+ security/lock_down.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 96 insertions(+)
+ create mode 100644 security/lock_down.c
+
+Index: linux/include/linux/kernel.h
+===================================================================
+--- linux.orig/include/linux/kernel.h
++++ linux/include/linux/kernel.h
+@@ -341,6 +341,23 @@ static inline void refcount_error_report
+ { }
+ #endif
+
++#ifdef CONFIG_LOCK_DOWN_KERNEL
++extern bool __kernel_is_locked_down(const char *what, bool first);
++#else
++static inline bool __kernel_is_locked_down(const char *what, bool first)
++{
++ return false;
++}
++#endif
++
++#define kernel_is_locked_down(what) \
++ ({ \
++ static bool message_given; \
++ bool locked_down = __kernel_is_locked_down(what, !message_given); \
++ message_given = true; \
++ locked_down; \
++ })
++
+ /* Internal, do not use. */
+ int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res);
+ int __must_check _kstrtol(const char *s, unsigned int base, long *res);
+Index: linux/include/linux/security.h
+===================================================================
+--- linux.orig/include/linux/security.h
++++ linux/include/linux/security.h
+@@ -1843,5 +1843,13 @@ static inline void free_secdata(void *se
+ { }
+ #endif /* CONFIG_SECURITY */
+
++#ifdef CONFIG_LOCK_DOWN_KERNEL
++extern void __init init_lockdown(void);
++#else
++static inline void __init init_lockdown(void)
++{
++}
++#endif
++
+ #endif /* ! __LINUX_SECURITY_H */
+
+Index: linux/security/Kconfig
+===================================================================
+--- linux.orig/security/Kconfig
++++ linux/security/Kconfig
+@@ -239,6 +239,14 @@ config STATIC_USERMODEHELPER_PATH
+ If you wish for all usermode helper programs to be disabled,
+ specify an empty string here (i.e. "").
+
++config LOCK_DOWN_KERNEL
++ bool "Allow the kernel to be 'locked down'"
++ help
++ Allow the kernel to be locked down under certain circumstances, for
++ instance if UEFI secure boot is enabled. Locking down the kernel
++ turns off various features that might otherwise allow access to the
++ kernel image (eg. setting MSR registers).
++
+ source security/selinux/Kconfig
+ source security/smack/Kconfig
+ source security/tomoyo/Kconfig
+Index: linux/security/Makefile
+===================================================================
+--- linux.orig/security/Makefile
++++ linux/security/Makefile
+@@ -30,3 +30,6 @@ obj-$(CONFIG_CGROUP_DEVICE) += device_c
+ # Object integrity file lists
+ subdir-$(CONFIG_INTEGRITY) += integrity
+ obj-$(CONFIG_INTEGRITY) += integrity/
++
++# Allow the kernel to be locked down
++obj-$(CONFIG_LOCK_DOWN_KERNEL) += lock_down.o
+Index: linux/security/lock_down.c
+===================================================================
+--- /dev/null
++++ linux/security/lock_down.c
+@@ -0,0 +1,60 @@
++/* Lock down the kernel
++ *
++ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++#include <linux/security.h>
++#include <linux/export.h>
++
++static __ro_after_init bool kernel_locked_down;
++
++/*
++ * Put the kernel into lock-down mode.
++ */
++static void __init lock_kernel_down(const char *where)
++{
++ if (!kernel_locked_down) {
++ kernel_locked_down = true;
++ pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n",
++ where);
++ }
++}
++
++static int __init lockdown_param(char *ignored)
++{
++ lock_kernel_down("command line");
++ return 0;
++}
++
++early_param("lockdown", lockdown_param);
++
++/*
++ * Lock the kernel down from very early in the arch setup. This must happen
++ * prior to things like ACPI being initialised.
++ */
++void __init init_lockdown(void)
++{
++#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT
++ if (efi_enabled(EFI_SECURE_BOOT))
++ lock_kernel_down("EFI secure boot");
++#endif
++}
++
++/**
++ * kernel_is_locked_down - Find out if the kernel is locked down
++ * @what: Tag to use in notice generated if lockdown is in effect
++ */
++bool __kernel_is_locked_down(const char *what, bool first)
++{
++ if (what && first && kernel_locked_down)
++ pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n",
++ what);
++ return kernel_locked_down;
++}
++EXPORT_SYMBOL(__kernel_is_locked_down);
diff --git a/debian/patches/features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch b/debian/patches/features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch
new file mode 100644
index 000000000..0ab99ba64
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch
@@ -0,0 +1,75 @@
+From: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Date: Wed, 8 Nov 2017 15:11:32 +0000
+Subject: [03/29] ima: require secure_boot rules in lockdown mode
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=29c55d71a8185208c7962843a29c9a84ae27b2b0
+
+Require the "secure_boot" rules, whether or not it is specified
+on the boot command line, for both the builtin and custom policies
+in secure boot lockdown mode.
+
+Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+[bwh: Adjust context to apply after commits 6f0911a666d1
+ "ima: fix updating the ima_appraise flag" and ef96837b0de4
+ "ima: add build time policy"]
+---
+ security/integrity/ima/ima_policy.c | 39 +++++++++++++++++++++++++++----------
+ 1 file changed, 29 insertions(+), 10 deletions(-)
+
+Index: linux/security/integrity/ima/ima_policy.c
+===================================================================
+--- linux.orig/security/integrity/ima/ima_policy.c
++++ linux/security/integrity/ima/ima_policy.c
+@@ -481,14 +481,21 @@ static int ima_appraise_flag(enum ima_ho
+ */
+ void __init ima_init_policy(void)
+ {
+- int i, measure_entries, appraise_entries, secure_boot_entries;
++ int i;
++ int measure_entries = 0;
++ int appraise_entries = 0;
++ int secure_boot_entries = 0;
++ bool kernel_locked_down = __kernel_is_locked_down(NULL, false);
+
+ /* if !ima_policy set entries = 0 so we load NO default rules */
+- measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0;
+- appraise_entries = ima_use_appraise_tcb ?
+- ARRAY_SIZE(default_appraise_rules) : 0;
+- secure_boot_entries = ima_use_secure_boot ?
+- ARRAY_SIZE(secure_boot_rules) : 0;
++ if (ima_policy)
++ measure_entries = ARRAY_SIZE(dont_measure_rules);
++
++ if (ima_use_appraise_tcb)
++ appraise_entries = ARRAY_SIZE(default_appraise_rules);
++
++ if (ima_use_secure_boot || kernel_locked_down)
++ secure_boot_entries = ARRAY_SIZE(secure_boot_rules);
+
+ for (i = 0; i < measure_entries; i++)
+ list_add_tail(&dont_measure_rules[i].list, &ima_default_rules);
+@@ -510,11 +517,24 @@ void __init ima_init_policy(void)
+ /*
+ * Insert the builtin "secure_boot" policy rules requiring file
+ * signatures, prior to any other appraise rules.
++ * In secure boot lock-down mode, also require these appraise
++ * rules for custom policies.
+ */
+ for (i = 0; i < secure_boot_entries; i++) {
++ struct ima_rule_entry *entry;
++
++ /* Include for builtin policies */
+ list_add_tail(&secure_boot_rules[i].list, &ima_default_rules);
+ temp_ima_appraise |=
+ ima_appraise_flag(secure_boot_rules[i].func);
++
++ /* Include for custom policies */
++ if (kernel_locked_down) {
++ entry = kmemdup(&secure_boot_rules[i], sizeof(*entry),
++ GFP_KERNEL);
++ if (entry)
++ list_add_tail(&entry->list, &ima_policy_rules);
++ }
+ }
+
+ /*
diff --git a/debian/patches/features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch b/debian/patches/features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch
new file mode 100644
index 000000000..0ab5e258c
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch
@@ -0,0 +1,95 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:32 +0000
+Subject: [04/29] Enforce module signatures if the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=1616ef1deccf5fdb525643a6b3efae34946a148d
+
+If the kernel is locked down, require that all modules have valid
+signatures that we can verify or that IMA can validate the file.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+[bwh: Adjust context to apply after commits 2c8fd268f418
+ "module: Do not access sig_enforce directly" and 5fdc7db6448a
+ "module: setup load info before module_sig_check()"]
+---
+ kernel/module.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+Index: linux/kernel/module.c
+===================================================================
+--- linux.orig/kernel/module.c
++++ linux/kernel/module.c
+@@ -64,6 +64,7 @@
+ #include <linux/bsearch.h>
+ #include <linux/dynamic_debug.h>
+ #include <linux/audit.h>
++#include <linux/ima.h>
+ #include <uapi/linux/module.h>
+ #include "module-internal.h"
+
+@@ -2784,7 +2785,8 @@ static inline void kmemleak_load_module(
+ #endif
+
+ #ifdef CONFIG_MODULE_SIG
+-static int module_sig_check(struct load_info *info, int flags)
++static int module_sig_check(struct load_info *info, int flags,
++ bool can_do_ima_check)
+ {
+ int err = -ENOKEY;
+ const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1;
+@@ -2808,13 +2810,16 @@ static int module_sig_check(struct load_
+ }
+
+ /* Not having a signature is only an error if we're strict. */
+- if (err == -ENOKEY && !is_module_sig_enforced())
++ if (err == -ENOKEY && !is_module_sig_enforced() &&
++ (!can_do_ima_check || !is_ima_appraise_enabled()) &&
++ !kernel_is_locked_down("Loading of unsigned modules"))
+ err = 0;
+
+ return err;
+ }
+ #else /* !CONFIG_MODULE_SIG */
+-static int module_sig_check(struct load_info *info, int flags)
++static int module_sig_check(struct load_info *info, int flags,
++ bool can_do_ima_check)
+ {
+ return 0;
+ }
+@@ -3662,7 +3667,7 @@ static int unknown_module_param_cb(char
+ /* Allocate and load the module: note that size of section 0 is always
+ zero, and we rely on this for optional sections. */
+ static int load_module(struct load_info *info, const char __user *uargs,
+- int flags)
++ int flags, bool can_do_ima_check)
+ {
+ struct module *mod;
+ long err = 0;
+@@ -3681,7 +3686,7 @@ static int load_module(struct load_info
+ goto free_copy;
+ }
+
+- err = module_sig_check(info, flags);
++ err = module_sig_check(info, flags, can_do_ima_check);
+ if (err)
+ goto free_copy;
+
+@@ -3876,7 +3881,7 @@ SYSCALL_DEFINE3(init_module, void __user
+ if (err)
+ return err;
+
+- return load_module(&info, uargs, 0);
++ return load_module(&info, uargs, 0, false);
+ }
+
+ SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags)
+@@ -3903,7 +3908,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, c
+ info.hdr = hdr;
+ info.len = size;
+
+- return load_module(&info, uargs, flags);
++ return load_module(&info, uargs, flags, true);
+ }
+
+ static inline int within(unsigned long addr, void *start, unsigned long size)
diff --git a/debian/patches/features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch b/debian/patches/features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch
new file mode 100644
index 000000000..625f8f763
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch
@@ -0,0 +1,35 @@
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Wed, 8 Nov 2017 15:11:32 +0000
+Subject: [05/29] Restrict /dev/{mem,kmem,port} when the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=8214bb0d847928bf08a7d8475f84c06541c5a352
+
+Allowing users to read and write to core kernel memory makes it possible
+for the kernel to be subverted, avoiding module loading restrictions, and
+also to steal cryptographic information.
+
+Disallow /dev/mem and /dev/kmem from being opened this when the kernel has
+been locked down to prevent this.
+
+Also disallow /dev/port from being opened to prevent raw ioport access and
+thus DMA from being used to accomplish the same thing.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+---
+ drivers/char/mem.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+Index: linux/drivers/char/mem.c
+===================================================================
+--- linux.orig/drivers/char/mem.c
++++ linux/drivers/char/mem.c
+@@ -807,6 +807,8 @@ static loff_t memory_lseek(struct file *
+
+ static int open_port(struct inode *inode, struct file *filp)
+ {
++ if (kernel_is_locked_down("/dev/mem,kmem,port"))
++ return -EPERM;
+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+ }
+
diff --git a/debian/patches/features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch b/debian/patches/features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch
new file mode 100644
index 000000000..522387d9a
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch
@@ -0,0 +1,42 @@
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Wed, 8 Nov 2017 15:11:32 +0000
+Subject: [06/29] kexec: Disable at runtime if the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=6081db9ba435b757a3a3473d0cd50ee2252ccaeb
+
+kexec permits the loading and execution of arbitrary code in ring 0, which
+is something that lock-down is meant to prevent. It makes sense to disable
+kexec in this situation.
+
+This does not affect kexec_file_load() which can check for a signature on the
+image to be booted.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Dave Young <dyoung@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+cc: kexec@lists.infradead.org
+[bwh: Adjust context to apply after commit a210fd32a46b
+ "kexec: add call to LSM hook in original kexec_load syscall"]
+---
+ kernel/kexec.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+Index: linux/kernel/kexec.c
+===================================================================
+--- linux.orig/kernel/kexec.c
++++ linux/kernel/kexec.c
+@@ -208,6 +208,13 @@ static inline int kexec_load_check(unsig
+ return result;
+
+ /*
++ * kexec can be used to circumvent module loading restrictions, so
++ * prevent loading in that case
++ */
++ if (kernel_is_locked_down("kexec of unsigned images"))
++ return -EPERM;
++
++ /*
+ * Verify we have a legal set of flags
+ * This leaves us room for future extensions.
+ */
diff --git a/debian/patches/features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch b/debian/patches/features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch
new file mode 100644
index 000000000..2024c04a6
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch
@@ -0,0 +1,36 @@
+From: Dave Young <dyoung@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:32 +0000
+Subject: [07/29] Copy secure_boot flag in boot params across kexec reboot
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a6b7f780bdaa731f3e2970d65dcd52fe9ba2409d
+
+Kexec reboot in case secure boot being enabled does not keep the secure
+boot mode in new kernel, so later one can load unsigned kernel via legacy
+kexec_load. In this state, the system is missing the protections provided
+by secure boot.
+
+Adding a patch to fix this by retain the secure_boot flag in original
+kernel.
+
+secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the
+stub. Fixing this issue by copying secure_boot flag across kexec reboot.
+
+Signed-off-by: Dave Young <dyoung@redhat.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: kexec@lists.infradead.org
+---
+ arch/x86/kernel/kexec-bzimage64.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: linux/arch/x86/kernel/kexec-bzimage64.c
+===================================================================
+--- linux.orig/arch/x86/kernel/kexec-bzimage64.c
++++ linux/arch/x86/kernel/kexec-bzimage64.c
+@@ -182,6 +182,7 @@ setup_efi_state(struct boot_params *para
+ if (efi_enabled(EFI_OLD_MEMMAP))
+ return 0;
+
++ params->secure_boot = boot_params.secure_boot;
+ ei->efi_loader_signature = current_ei->efi_loader_signature;
+ ei->efi_systab = current_ei->efi_systab;
+ ei->efi_systab_hi = current_ei->efi_systab_hi;
diff --git a/debian/patches/features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch b/debian/patches/features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch
new file mode 100644
index 000000000..056936427
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch
@@ -0,0 +1,40 @@
+From: Chun-Yi Lee <joeyli.kernel@gmail.com>
+Date: Wed, 8 Nov 2017 15:11:33 +0000
+Subject: [08/29] kexec_file: Restrict at runtime if the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=eed4aca0409692d7d24bc64f5c98d346cd0506c4
+
+When KEXEC_VERIFY_SIG is not enabled, kernel should not load images through
+kexec_file systemcall if the kernel is locked down unless IMA can be used
+to validate the image.
+
+This code was showed in Matthew's patch but not in git:
+https://lkml.org/lkml/2015/3/13/778
+
+Cc: Matthew Garrett <mjg59@srcf.ucam.org>
+Signed-off-by: Chun-Yi Lee <jlee@suse.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+cc: kexec@lists.infradead.org
+---
+ kernel/kexec_file.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+Index: linux/kernel/kexec_file.c
+===================================================================
+--- linux.orig/kernel/kexec_file.c
++++ linux/kernel/kexec_file.c
+@@ -328,6 +328,14 @@ SYSCALL_DEFINE5(kexec_file_load, int, ke
+ if (!capable(CAP_SYS_BOOT) || kexec_load_disabled)
+ return -EPERM;
+
++ /* Don't permit images to be loaded into trusted kernels if we're not
++ * going to verify the signature on them
++ */
++ if (!IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) &&
++ !is_ima_appraise_enabled() &&
++ kernel_is_locked_down("kexec of unsigned images"))
++ return -EPERM;
++
+ /* Make sure we have a legal set of flags */
+ if (flags != (flags & KEXEC_FILE_FLAGS))
+ return -EINVAL;
diff --git a/debian/patches/features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch b/debian/patches/features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch
new file mode 100644
index 000000000..56060f80a
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch
@@ -0,0 +1,31 @@
+From: Josh Boyer <jwboyer@fedoraproject.org>
+Date: Wed, 8 Nov 2017 15:11:33 +0000
+Subject: [09/29] hibernate: Disable when the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=480ddca2a40c2efd1c01cfa20d8f6c1377ddafe3
+
+There is currently no way to verify the resume image when returning
+from hibernate. This might compromise the signed modules trust model,
+so until we can work with signed hibernate images we disable it when the
+kernel is locked down.
+
+Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: linux-pm@vger.kernel.org
+---
+ kernel/power/hibernate.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/kernel/power/hibernate.c
+===================================================================
+--- linux.orig/kernel/power/hibernate.c
++++ linux/kernel/power/hibernate.c
+@@ -70,7 +70,7 @@ static const struct platform_hibernation
+
+ bool hibernation_available(void)
+ {
+- return (nohibernate == 0);
++ return nohibernate == 0 && !kernel_is_locked_down("Hibernation");
+ }
+
+ /**
diff --git a/debian/patches/features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch b/debian/patches/features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch
new file mode 100644
index 000000000..79b5f3461
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch
@@ -0,0 +1,32 @@
+From: Matthew Garrett <mjg59@srcf.ucam.org>
+Date: Wed, 8 Nov 2017 15:11:33 +0000
+Subject: [10/29] uswsusp: Disable when the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=706def46d58e9c69e91db506305485731f615e44
+
+uswsusp allows a user process to dump and then restore kernel state, which
+makes it possible to modify the running kernel. Disable this if the kernel
+is locked down.
+
+Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+cc: linux-pm@vger.kernel.org
+---
+ kernel/power/user.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/kernel/power/user.c
+===================================================================
+--- linux.orig/kernel/power/user.c
++++ linux/kernel/power/user.c
+@@ -52,6 +52,9 @@ static int snapshot_open(struct inode *i
+ if (!hibernation_available())
+ return -EPERM;
+
++ if (kernel_is_locked_down("/dev/snapshot"))
++ return -EPERM;
++
+ lock_system_sleep();
+
+ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
diff --git a/debian/patches/features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch b/debian/patches/features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch
new file mode 100644
index 000000000..1f9186ab3
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch
@@ -0,0 +1,104 @@
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Wed, 8 Nov 2017 15:11:33 +0000
+Subject: [11/29] PCI: Lock down BAR access when the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=d107d11fd7ac982a34b1233722cb3e72f9fe5a20
+
+Any hardware that can potentially generate DMA has to be locked down in
+order to avoid it being possible for an attacker to modify kernel code,
+allowing them to circumvent disabled module loading or module signing.
+Default to paranoid - in future we can potentially relax this for
+sufficiently IOMMU-isolated devices.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: linux-pci@vger.kernel.org
+---
+ drivers/pci/pci-sysfs.c | 9 +++++++++
+ drivers/pci/proc.c | 9 ++++++++-
+ drivers/pci/syscall.c | 3 ++-
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/pci/pci-sysfs.c
+===================================================================
+--- linux.orig/drivers/pci/pci-sysfs.c
++++ linux/drivers/pci/pci-sysfs.c
+@@ -905,6 +905,9 @@ static ssize_t pci_write_config(struct f
+ loff_t init_off = off;
+ u8 *data = (u8 *) buf;
+
++ if (kernel_is_locked_down("Direct PCI access"))
++ return -EPERM;
++
+ if (off > dev->cfg_size)
+ return 0;
+ if (off + count > dev->cfg_size) {
+@@ -1167,6 +1170,9 @@ static int pci_mmap_resource(struct kobj
+ enum pci_mmap_state mmap_type;
+ struct resource *res = &pdev->resource[bar];
+
++ if (kernel_is_locked_down("Direct PCI access"))
++ return -EPERM;
++
+ if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
+ return -EINVAL;
+
+@@ -1242,6 +1248,9 @@ static ssize_t pci_write_resource_io(str
+ struct bin_attribute *attr, char *buf,
+ loff_t off, size_t count)
+ {
++ if (kernel_is_locked_down("Direct PCI access"))
++ return -EPERM;
++
+ return pci_resource_io(filp, kobj, attr, buf, off, count, true);
+ }
+
+Index: linux/drivers/pci/proc.c
+===================================================================
+--- linux.orig/drivers/pci/proc.c
++++ linux/drivers/pci/proc.c
+@@ -117,6 +117,9 @@ static ssize_t proc_bus_pci_write(struct
+ int size = dev->cfg_size;
+ int cnt;
+
++ if (kernel_is_locked_down("Direct PCI access"))
++ return -EPERM;
++
+ if (pos >= size)
+ return 0;
+ if (nbytes >= size)
+@@ -196,6 +199,9 @@ static long proc_bus_pci_ioctl(struct fi
+ #endif /* HAVE_PCI_MMAP */
+ int ret = 0;
+
++ if (kernel_is_locked_down("Direct PCI access"))
++ return -EPERM;
++
+ switch (cmd) {
+ case PCIIOC_CONTROLLER:
+ ret = pci_domain_nr(dev->bus);
+@@ -237,7 +243,8 @@ static int proc_bus_pci_mmap(struct file
+ struct pci_filp_private *fpriv = file->private_data;
+ int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM;
+
+- if (!capable(CAP_SYS_RAWIO))
++ if (!capable(CAP_SYS_RAWIO) ||
++ kernel_is_locked_down("Direct PCI access"))
+ return -EPERM;
+
+ if (fpriv->mmap_state == pci_mmap_io) {
+Index: linux/drivers/pci/syscall.c
+===================================================================
+--- linux.orig/drivers/pci/syscall.c
++++ linux/drivers/pci/syscall.c
+@@ -90,7 +90,8 @@ SYSCALL_DEFINE5(pciconfig_write, unsigne
+ u32 dword;
+ int err = 0;
+
+- if (!capable(CAP_SYS_ADMIN))
++ if (!capable(CAP_SYS_ADMIN) ||
++ kernel_is_locked_down("Direct PCI access"))
+ return -EPERM;
+
+ dev = pci_get_domain_bus_and_slot(0, bus, dfn);
diff --git a/debian/patches/features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch b/debian/patches/features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch
new file mode 100644
index 000000000..3a9d69dcb
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch
@@ -0,0 +1,46 @@
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Wed, 8 Nov 2017 15:11:34 +0000
+Subject: [12/29] x86: Lock down IO port access when the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=00ebba940247d4c37c06da4aedecf6b80db213cf
+
+IO port access would permit users to gain access to PCI configuration
+registers, which in turn (on a lot of hardware) give access to MMIO
+register space. This would potentially permit root to trigger arbitrary
+DMA, so lock it down by default.
+
+This also implicitly locks down the KDADDIO, KDDELIO, KDENABIO and
+KDDISABIO console ioctls.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: x86@kernel.org
+---
+ arch/x86/kernel/ioport.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+Index: linux/arch/x86/kernel/ioport.c
+===================================================================
+--- linux.orig/arch/x86/kernel/ioport.c
++++ linux/arch/x86/kernel/ioport.c
+@@ -31,7 +31,8 @@ long ksys_ioperm(unsigned long from, uns
+
+ if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
+ return -EINVAL;
+- if (turn_on && !capable(CAP_SYS_RAWIO))
++ if (turn_on && (!capable(CAP_SYS_RAWIO) ||
++ kernel_is_locked_down("ioperm")))
+ return -EPERM;
+
+ /*
+@@ -126,7 +127,8 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve
+ return -EINVAL;
+ /* Trying to gain more privileges? */
+ if (level > old) {
+- if (!capable(CAP_SYS_RAWIO))
++ if (!capable(CAP_SYS_RAWIO) ||
++ kernel_is_locked_down("iopl"))
+ return -EPERM;
+ }
+ regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
diff --git a/debian/patches/features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch b/debian/patches/features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch
new file mode 100644
index 000000000..1a7a4d879
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch
@@ -0,0 +1,50 @@
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Wed, 8 Nov 2017 15:11:34 +0000
+Subject: [13/29] x86/msr: Restrict MSR access when the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=696dcddb285558b4febf318fe620a344d2b2fa47
+
+Writing to MSRs should not be allowed if the kernel is locked down, since
+it could lead to execution of arbitrary code in kernel mode. Based on a
+patch by Kees Cook.
+
+MSR accesses are logged for the purposes of building up a whitelist as per
+Alan Cox's suggestion.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Kees Cook <keescook@chromium.org>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: x86@kernel.org
+---
+ arch/x86/kernel/msr.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+Index: linux/arch/x86/kernel/msr.c
+===================================================================
+--- linux.orig/arch/x86/kernel/msr.c
++++ linux/arch/x86/kernel/msr.c
+@@ -84,6 +84,11 @@ static ssize_t msr_write(struct file *fi
+ int err = 0;
+ ssize_t bytes = 0;
+
++ if (kernel_is_locked_down("Direct MSR access")) {
++ pr_info("Direct access to MSR %x\n", reg);
++ return -EPERM;
++ }
++
+ if (count % 8)
+ return -EINVAL; /* Invalid chunk size */
+
+@@ -135,6 +140,11 @@ static long msr_ioctl(struct file *file,
+ err = -EFAULT;
+ break;
+ }
++ if (kernel_is_locked_down("Direct MSR access")) {
++ pr_info("Direct access to MSR %x\n", regs[1]); /* Display %ecx */
++ err = -EPERM;
++ break;
++ }
+ err = wrmsr_safe_regs_on_cpu(cpu, regs);
+ if (err)
+ break;
diff --git a/debian/patches/features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch b/debian/patches/features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch
new file mode 100644
index 000000000..295b46e88
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch
@@ -0,0 +1,55 @@
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Wed, 8 Nov 2017 15:11:34 +0000
+Subject: [14/29] asus-wmi: Restrict debugfs interface when the kernel is
+ locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=2e6d31b3176ee27d216bb92a3b108f6b19d4719a
+
+We have no way of validating what all of the Asus WMI methods do on a given
+machine - and there's a risk that some will allow hardware state to be
+manipulated in such a way that arbitrary code can be executed in the
+kernel, circumventing module loading restrictions. Prevent that if the
+kernel is locked down.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: acpi4asus-user@lists.sourceforge.net
+cc: platform-driver-x86@vger.kernel.org
+---
+ drivers/platform/x86/asus-wmi.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+Index: linux/drivers/platform/x86/asus-wmi.c
+===================================================================
+--- linux.orig/drivers/platform/x86/asus-wmi.c
++++ linux/drivers/platform/x86/asus-wmi.c
+@@ -2002,6 +2002,9 @@ static int show_dsts(struct seq_file *m,
+ int err;
+ u32 retval = -1;
+
++ if (kernel_is_locked_down("Asus WMI"))
++ return -EPERM;
++
+ err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
+
+ if (err < 0)
+@@ -2018,6 +2021,9 @@ static int show_devs(struct seq_file *m,
+ int err;
+ u32 retval = -1;
+
++ if (kernel_is_locked_down("Asus WMI"))
++ return -EPERM;
++
+ err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
+ &retval);
+
+@@ -2042,6 +2048,9 @@ static int show_call(struct seq_file *m,
+ union acpi_object *obj;
+ acpi_status status;
+
++ if (kernel_is_locked_down("Asus WMI"))
++ return -EPERM;
++
+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
+ 0, asus->debug.method_id,
+ &input, &output);
diff --git a/debian/patches/features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch b/debian/patches/features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch
new file mode 100644
index 000000000..17778da72
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch
@@ -0,0 +1,32 @@
+From: Matthew Garrett <matthew.garrett@nebula.com>
+Date: Wed, 8 Nov 2017 15:11:34 +0000
+Subject: [15/29] ACPI: Limit access to custom_method when the kernel is locked
+ down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=5ff99c830aacf02f25816a0da427216fb63ba16d
+
+custom_method effectively allows arbitrary access to system memory, making
+it possible for an attacker to circumvent restrictions on module loading.
+Disable it if the kernel is locked down.
+
+Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: linux-acpi@vger.kernel.org
+---
+ drivers/acpi/custom_method.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/drivers/acpi/custom_method.c
+===================================================================
+--- linux.orig/drivers/acpi/custom_method.c
++++ linux/drivers/acpi/custom_method.c
+@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *fil
+ struct acpi_table_header table;
+ acpi_status status;
+
++ if (kernel_is_locked_down("ACPI custom methods"))
++ return -EPERM;
++
+ if (!(*ppos)) {
+ /* parse the table header to get the table length */
+ if (count <= sizeof(struct acpi_table_header))
diff --git a/debian/patches/features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch b/debian/patches/features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch
new file mode 100644
index 000000000..f8ee397c8
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch
@@ -0,0 +1,32 @@
+From: Josh Boyer <jwboyer@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:34 +0000
+Subject: [16/29] acpi: Ignore acpi_rsdp kernel param when the kernel has been
+ locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=67890a0361626ec3e035264656896c77670c414b
+
+This option allows userspace to pass the RSDP address to the kernel, which
+makes it possible for a user to modify the workings of hardware . Reject
+the option when the kernel is locked down.
+
+Signed-off-by: Josh Boyer <jwboyer@redhat.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: Dave Young <dyoung@redhat.com>
+cc: linux-acpi@vger.kernel.org
+---
+ drivers/acpi/osl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/drivers/acpi/osl.c
+===================================================================
+--- linux.orig/drivers/acpi/osl.c
++++ linux/drivers/acpi/osl.c
+@@ -194,7 +194,7 @@ acpi_physical_address __init acpi_os_get
+ acpi_physical_address pa;
+
+ #ifdef CONFIG_KEXEC
+- if (acpi_rsdp)
++ if (acpi_rsdp && !kernel_is_locked_down("ACPI RSDP specification"))
+ return acpi_rsdp;
+ #endif
+ pa = acpi_arch_get_root_pointer();
diff --git a/debian/patches/features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch b/debian/patches/features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch
new file mode 100644
index 000000000..fd12eedb2
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch
@@ -0,0 +1,40 @@
+From: Linn Crosetto <linn@hpe.com>
+Date: Wed, 8 Nov 2017 15:11:34 +0000
+Subject: [17/29] acpi: Disable ACPI table override if the kernel is locked
+ down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=5976d26de05569951641ebeb95f7240993b66063
+
+From the kernel documentation (initrd_table_override.txt):
+
+ If the ACPI_INITRD_TABLE_OVERRIDE compile option is true, it is possible
+ to override nearly any ACPI table provided by the BIOS with an
+ instrumented, modified one.
+
+When securelevel is set, the kernel should disallow any unauthenticated
+changes to kernel space. ACPI tables contain code invoked by the kernel,
+so do not allow ACPI tables to be overridden if the kernel is locked down.
+
+Signed-off-by: Linn Crosetto <linn@hpe.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: linux-acpi@vger.kernel.org
+---
+ drivers/acpi/tables.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+Index: linux/drivers/acpi/tables.c
+===================================================================
+--- linux.orig/drivers/acpi/tables.c
++++ linux/drivers/acpi/tables.c
+@@ -532,6 +532,11 @@ void __init acpi_table_upgrade(void)
+ if (table_nr == 0)
+ return;
+
++ if (kernel_is_locked_down("ACPI table override")) {
++ pr_notice("kernel is locked down, ignoring table override\n");
++ return;
++ }
++
+ acpi_tables_addr =
+ memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS,
+ all_tables_size, PAGE_SIZE);
diff --git a/debian/patches/features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch b/debian/patches/features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch
new file mode 100644
index 000000000..396a506ac
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch
@@ -0,0 +1,43 @@
+From: Linn Crosetto <linn@hpe.com>
+Date: Wed, 8 Nov 2017 15:11:35 +0000
+Subject: [18/29] acpi: Disable APEI error injection if the kernel is locked
+ down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a9c239382bce17b9108f941130392151d5fff262
+
+ACPI provides an error injection mechanism, EINJ, for debugging and testing
+the ACPI Platform Error Interface (APEI) and other RAS features. If
+supported by the firmware, ACPI specification 5.0 and later provide for a
+way to specify a physical memory address to which to inject the error.
+
+Injecting errors through EINJ can produce errors which to the platform are
+indistinguishable from real hardware errors. This can have undesirable
+side-effects, such as causing the platform to mark hardware as needing
+replacement.
+
+While it does not provide a method to load unauthenticated privileged code,
+the effect of these errors may persist across reboots and affect trust in
+the underlying hardware, so disable error injection through EINJ if
+the kernel is locked down.
+
+Signed-off-by: Linn Crosetto <linn@hpe.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com>
+cc: linux-acpi@vger.kernel.org
+---
+ drivers/acpi/apei/einj.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/drivers/acpi/apei/einj.c
+===================================================================
+--- linux.orig/drivers/acpi/apei/einj.c
++++ linux/drivers/acpi/apei/einj.c
+@@ -518,6 +518,9 @@ static int einj_error_inject(u32 type, u
+ int rc;
+ u64 base_addr, size;
+
++ if (kernel_is_locked_down("ACPI error injection"))
++ return -EPERM;
++
+ /* If user manually set "flags", make sure it is legal */
+ if (flags && (flags &
+ ~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF)))
diff --git a/debian/patches/features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch b/debian/patches/features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch
new file mode 100644
index 000000000..2ed56ad5b
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch
@@ -0,0 +1,29 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:35 +0000
+Subject: [20/29] Prohibit PCMCIA CIS storage when the kernel is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=18b2dfc74efeafbdbb8f5d4d28da6334b7e1f1ac
+
+Prohibit replacement of the PCMCIA Card Information Structure when the
+kernel is locked down.
+
+Suggested-by: Dominik Brodowski <linux@dominikbrodowski.net>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: linux-pcmcia@lists.infradead.org
+---
+ drivers/pcmcia/cistpl.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/drivers/pcmcia/cistpl.c
+===================================================================
+--- linux.orig/drivers/pcmcia/cistpl.c
++++ linux/drivers/pcmcia/cistpl.c
+@@ -1578,6 +1578,9 @@ static ssize_t pccard_store_cis(struct f
+ struct pcmcia_socket *s;
+ int error;
+
++ if (kernel_is_locked_down("Direct PCMCIA CIS storage"))
++ return -EPERM;
++
+ s = to_socket(container_of(kobj, struct device, kobj));
+
+ if (off)
diff --git a/debian/patches/features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch b/debian/patches/features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch
new file mode 100644
index 000000000..d906326a9
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch
@@ -0,0 +1,34 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:35 +0000
+Subject: [21/29] Lock down TIOCSSERIAL
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=f5fdeda0622ca040961521819794193777a03e8a
+
+Lock down TIOCSSERIAL as that can be used to change the ioport and irq
+settings on a serial port. This only appears to be an issue for the serial
+drivers that use the core serial code. All other drivers seem to either
+ignore attempts to change port/irq or give an error.
+
+Reported-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Jiri Slaby <jslaby@suse.com>
+---
+ drivers/tty/serial/serial_core.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+Index: linux/drivers/tty/serial/serial_core.c
+===================================================================
+--- linux.orig/drivers/tty/serial/serial_core.c
++++ linux/drivers/tty/serial/serial_core.c
+@@ -850,6 +850,12 @@ static int uart_set_info(struct tty_stru
+ new_flags = (__force upf_t)new_info->flags;
+ old_custom_divisor = uport->custom_divisor;
+
++ if ((change_port || change_irq) &&
++ kernel_is_locked_down("Using TIOCSSERIAL to change device addresses, irqs and dma channels")) {
++ retval = -EPERM;
++ goto exit;
++ }
++
+ if (!capable(CAP_SYS_ADMIN)) {
+ retval = -EPERM;
+ if (change_irq || change_port ||
diff --git a/debian/patches/features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch b/debian/patches/features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch
new file mode 100644
index 000000000..3582e3106
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch
@@ -0,0 +1,80 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:36 +0000
+Subject: [22/29] Lock down module params that specify hardware parameters (eg.
+ ioport)
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=d20a28efda02a7ce70b943c15246ea2f07e780f4
+
+Provided an annotation for module parameters that specify hardware
+parameters (such as io ports, iomem addresses, irqs, dma channels, fixed
+dma buffers and other types).
+
+Suggested-by: Alan Cox <gnomes@lxorguk.ukuu.org.uk>
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ kernel/params.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+Index: linux/kernel/params.c
+===================================================================
+--- linux.orig/kernel/params.c
++++ linux/kernel/params.c
+@@ -108,13 +108,19 @@ bool parameq(const char *a, const char *
+ return parameqn(a, b, strlen(a)+1);
+ }
+
+-static void param_check_unsafe(const struct kernel_param *kp)
++static bool param_check_unsafe(const struct kernel_param *kp,
++ const char *doing)
+ {
+ if (kp->flags & KERNEL_PARAM_FL_UNSAFE) {
+ pr_notice("Setting dangerous option %s - tainting kernel\n",
+ kp->name);
+ add_taint(TAINT_USER, LOCKDEP_STILL_OK);
+ }
++
++ if (kp->flags & KERNEL_PARAM_FL_HWPARAM &&
++ kernel_is_locked_down("Command line-specified device addresses, irqs and dma channels"))
++ return false;
++ return true;
+ }
+
+ static int parse_one(char *param,
+@@ -144,8 +150,10 @@ static int parse_one(char *param,
+ pr_debug("handling %s with %p\n", param,
+ params[i].ops->set);
+ kernel_param_lock(params[i].mod);
+- param_check_unsafe(&params[i]);
+- err = params[i].ops->set(val, &params[i]);
++ if (param_check_unsafe(&params[i], doing))
++ err = params[i].ops->set(val, &params[i]);
++ else
++ err = -EPERM;
+ kernel_param_unlock(params[i].mod);
+ return err;
+ }
+@@ -553,6 +561,12 @@ static ssize_t param_attr_show(struct mo
+ return count;
+ }
+
++#ifdef CONFIG_MODULES
++#define mod_name(mod) (mod)->name
++#else
++#define mod_name(mod) "unknown"
++#endif
++
+ /* sysfs always hands a nul-terminated string in buf. We rely on that. */
+ static ssize_t param_attr_store(struct module_attribute *mattr,
+ struct module_kobject *mk,
+@@ -565,8 +579,10 @@ static ssize_t param_attr_store(struct m
+ return -EPERM;
+
+ kernel_param_lock(mk->mod);
+- param_check_unsafe(attribute->param);
+- err = attribute->param->ops->set(buf, attribute->param);
++ if (param_check_unsafe(attribute->param, mod_name(mk->mod)))
++ err = attribute->param->ops->set(buf, attribute->param);
++ else
++ err = -EPERM;
+ kernel_param_unlock(mk->mod);
+ if (!err)
+ return len;
diff --git a/debian/patches/features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch b/debian/patches/features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch
new file mode 100644
index 000000000..47edb3442
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch
@@ -0,0 +1,33 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:36 +0000
+Subject: [23/29] x86/mmiotrace: Lock down the testmmiotrace module
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=20af3be0bcf6a78e3632770561fba6531dd3b444
+
+The testmmiotrace module shouldn't be permitted when the kernel is locked
+down as it can be used to arbitrarily read and write MMIO space.
+
+Suggested-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: David Howells <dhowells@redhat.com
+cc: Thomas Gleixner <tglx@linutronix.de>
+cc: Steven Rostedt <rostedt@goodmis.org>
+cc: Ingo Molnar <mingo@kernel.org>
+cc: "H. Peter Anvin" <hpa@zytor.com>
+cc: x86@kernel.org
+---
+ arch/x86/mm/testmmiotrace.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/arch/x86/mm/testmmiotrace.c
+===================================================================
+--- linux.orig/arch/x86/mm/testmmiotrace.c
++++ linux/arch/x86/mm/testmmiotrace.c
+@@ -115,6 +115,9 @@ static int __init init(void)
+ {
+ unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
+
++ if (kernel_is_locked_down("MMIO trace testing"))
++ return -EPERM;
++
+ if (mmio_address == 0) {
+ pr_err("you have to use the module argument mmio_address.\n");
+ pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
diff --git a/debian/patches/features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch b/debian/patches/features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch
new file mode 100644
index 000000000..2dd3fa020
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch
@@ -0,0 +1,53 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:36 +0000
+Subject: [24/29] debugfs: Disallow use of debugfs files when the kernel is
+ locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=118cc5e1c27e1a75640cf2379c1299e12791063e
+
+Disallow opening of debugfs files when the kernel is locked down as various
+drivers give raw access to hardware through debugfs.
+
+Accesses to tracefs should use /sys/kernel/tracing/ rather than
+/sys/kernel/debug/tracing/. Possibly a symlink should be emplaced.
+
+Normal device interaction should be done through configfs or a miscdev, not
+debugfs.
+
+Note that this makes it unnecessary to specifically lock down show_dsts(),
+show_devs() and show_call() in the asus-wmi driver.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Andy Shevchenko <andy.shevchenko@gmail.com>
+cc: acpi4asus-user@lists.sourceforge.net
+cc: platform-driver-x86@vger.kernel.org
+cc: Matthew Garrett <matthew.garrett@nebula.com>
+cc: Thomas Gleixner <tglx@linutronix.de>
+[bwh: Forward-ported to 4.15]
+---
+ fs/debugfs/file.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+Index: linux/fs/debugfs/file.c
+===================================================================
+--- linux.orig/fs/debugfs/file.c
++++ linux/fs/debugfs/file.c
+@@ -142,6 +142,9 @@ static int open_proxy_open(struct inode
+ const struct file_operations *real_fops = NULL;
+ int r;
+
++ if (kernel_is_locked_down("debugfs"))
++ return -EPERM;
++
+ r = debugfs_file_get(dentry);
+ if (r)
+ return r == -EIO ? -ENOENT : r;
+@@ -267,6 +270,9 @@ static int full_proxy_open(struct inode
+ struct file_operations *proxy_fops = NULL;
+ int r;
+
++ if (kernel_is_locked_down("debugfs"))
++ return -EPERM;
++
+ r = debugfs_file_get(dentry);
+ if (r)
+ return r == -EIO ? -ENOENT : r;
diff --git a/debian/patches/features/all/lockdown/0025-Lock-down-proc-kcore.patch b/debian/patches/features/all/lockdown/0025-Lock-down-proc-kcore.patch
new file mode 100644
index 000000000..58df9739b
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0025-Lock-down-proc-kcore.patch
@@ -0,0 +1,27 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:37 +0000
+Subject: [25/29] Lock down /proc/kcore
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=797378dc4498207c3abc1101cfdc9ef2581d8c71
+
+Disallow access to /proc/kcore when the kernel is locked down to prevent
+access to cryptographic data.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+---
+ fs/proc/kcore.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+Index: linux/fs/proc/kcore.c
+===================================================================
+--- linux.orig/fs/proc/kcore.c
++++ linux/fs/proc/kcore.c
+@@ -545,6 +545,8 @@ out:
+
+ static int open_kcore(struct inode *inode, struct file *filp)
+ {
++ if (kernel_is_locked_down("/proc/kcore"))
++ return -EPERM;
+ if (!capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
diff --git a/debian/patches/features/all/lockdown/0026-Lock-down-kprobes.patch b/debian/patches/features/all/lockdown/0026-Lock-down-kprobes.patch
new file mode 100644
index 000000000..e7d9f0b4e
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0026-Lock-down-kprobes.patch
@@ -0,0 +1,29 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 16:14:12 +0000
+Subject: [26/29] Lock down kprobes
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=cfacbbe6ef95336d99817fb8063c19bd36dfaa3d
+
+Disallow the creation of kprobes when the kernel is locked down by
+preventing their registration. This prevents kprobes from being used to
+access kernel memory, either to make modifications or to steal crypto data.
+
+Reported-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+---
+ kernel/kprobes.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/kernel/kprobes.c
+===================================================================
+--- linux.orig/kernel/kprobes.c
++++ linux/kernel/kprobes.c
+@@ -1548,6 +1548,9 @@ int register_kprobe(struct kprobe *p)
+ struct module *probed_mod;
+ kprobe_opcode_t *addr;
+
++ if (kernel_is_locked_down("Use of kprobes"))
++ return -EPERM;
++
+ /* Adjust probe address from symbol */
+ addr = kprobe_addr(p);
+ if (IS_ERR(addr))
diff --git a/debian/patches/features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch b/debian/patches/features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch
new file mode 100644
index 000000000..87273834c
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch
@@ -0,0 +1,39 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 24 May 2017 14:56:05 +0100
+Subject: [27/29] bpf: Restrict kernel image access functions when the kernel
+ is locked down
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a13e9f58894129d9fd02fdb81b56ac7590704155
+
+There are some bpf functions can be used to read kernel memory:
+bpf_probe_read, bpf_probe_write_user and bpf_trace_printk. These allow
+private keys in kernel memory (e.g. the hibernation image signing key) to
+be read by an eBPF program and kernel memory to be altered without
+restriction.
+
+Completely prohibit the use of BPF when the kernel is locked down.
+
+Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: netdev@vger.kernel.org
+cc: Chun-Yi Lee <jlee@suse.com>
+cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
+[bwh: Adjust context to apply after commit dcab51f19b29
+ "bpf: Expose check_uarg_tail_zero()"]
+---
+ kernel/bpf/syscall.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+Index: linux/kernel/bpf/syscall.c
+===================================================================
+--- linux.orig/kernel/bpf/syscall.c
++++ linux/kernel/bpf/syscall.c
+@@ -2378,6 +2378,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf
+ if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
++ if (kernel_is_locked_down("BPF"))
++ return -EPERM;
++
+ err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size);
+ if (err)
+ return err;
diff --git a/debian/patches/features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch b/debian/patches/features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch
new file mode 100644
index 000000000..be357055b
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch
@@ -0,0 +1,152 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:37 +0000
+Subject: [28/29] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=eb4a8603eb727afaeb9c6123eda2eda4b2757bf3
+
+UEFI machines can be booted in Secure Boot mode. Add an EFI_SECURE_BOOT
+flag that can be passed to efi_enabled() to find out whether secure boot is
+enabled.
+
+Move the switch-statement in x86's setup_arch() that inteprets the
+secure_boot boot parameter to generic code and set the bit there.
+
+Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+cc: linux-efi@vger.kernel.org
+---
+ arch/x86/kernel/setup.c | 14 +-------------
+ drivers/firmware/efi/Makefile | 1 +
+ drivers/firmware/efi/secureboot.c | 38 ++++++++++++++++++++++++++++++++++++++
+ include/linux/efi.h | 16 ++++++++++------
+ 4 files changed, 50 insertions(+), 19 deletions(-)
+ create mode 100644 drivers/firmware/efi/secureboot.c
+
+Index: linux/arch/x86/kernel/setup.c
+===================================================================
+--- linux.orig/arch/x86/kernel/setup.c
++++ linux/arch/x86/kernel/setup.c
+@@ -1159,19 +1159,7 @@ void __init setup_arch(char **cmdline_p)
+ /* Allocate bigger log buffer */
+ setup_log_buf(1);
+
+- if (efi_enabled(EFI_BOOT)) {
+- switch (boot_params.secure_boot) {
+- case efi_secureboot_mode_disabled:
+- pr_info("Secure boot disabled\n");
+- break;
+- case efi_secureboot_mode_enabled:
+- pr_info("Secure boot enabled\n");
+- break;
+- default:
+- pr_info("Secure boot could not be determined\n");
+- break;
+- }
+- }
++ efi_set_secure_boot(boot_params.secure_boot);
+
+ reserve_initrd();
+
+Index: linux/drivers/firmware/efi/Makefile
+===================================================================
+--- linux.orig/drivers/firmware/efi/Makefile
++++ linux/drivers/firmware/efi/Makefile
+@@ -24,6 +24,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m
+ obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o
+ obj-$(CONFIG_EFI_TEST) += test/
+ obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o
++obj-$(CONFIG_EFI) += secureboot.o
+ obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o
+
+ arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o
+Index: linux/drivers/firmware/efi/secureboot.c
+===================================================================
+--- /dev/null
++++ linux/drivers/firmware/efi/secureboot.c
+@@ -0,0 +1,38 @@
++/* Core kernel secure boot support.
++ *
++ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells@redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public Licence
++ * as published by the Free Software Foundation; either version
++ * 2 of the Licence, or (at your option) any later version.
++ */
++
++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
++
++#include <linux/efi.h>
++#include <linux/kernel.h>
++#include <linux/printk.h>
++
++/*
++ * Decide what to do when UEFI secure boot mode is enabled.
++ */
++void __init efi_set_secure_boot(enum efi_secureboot_mode mode)
++{
++ if (efi_enabled(EFI_BOOT)) {
++ switch (mode) {
++ case efi_secureboot_mode_disabled:
++ pr_info("Secure boot disabled\n");
++ break;
++ case efi_secureboot_mode_enabled:
++ set_bit(EFI_SECURE_BOOT, &efi.flags);
++ pr_info("Secure boot enabled\n");
++ break;
++ default:
++ pr_warning("Secure boot could not be determined (mode %u)\n",
++ mode);
++ break;
++ }
++ }
++}
+Index: linux/include/linux/efi.h
+===================================================================
+--- linux.orig/include/linux/efi.h
++++ linux/include/linux/efi.h
+@@ -1152,6 +1152,14 @@ extern int __init efi_setup_pcdp_console
+ #define EFI_DBG 8 /* Print additional debug info at runtime */
+ #define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */
+ #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */
++#define EFI_SECURE_BOOT 11 /* Are we in Secure Boot mode? */
++
++enum efi_secureboot_mode {
++ efi_secureboot_mode_unset,
++ efi_secureboot_mode_unknown,
++ efi_secureboot_mode_disabled,
++ efi_secureboot_mode_enabled,
++};
+
+ #ifdef CONFIG_EFI
+ /*
+@@ -1164,6 +1172,7 @@ static inline bool efi_enabled(int featu
+ extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
+
+ extern bool efi_is_table_address(unsigned long phys_addr);
++extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode);
+ #else
+ static inline bool efi_enabled(int feature)
+ {
+@@ -1182,6 +1191,7 @@ static inline bool efi_is_table_address(
+ {
+ return false;
+ }
++static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {}
+ #endif
+
+ extern int efi_status_to_err(efi_status_t status);
+@@ -1572,12 +1582,6 @@ static inline bool efi_runtime_disabled(
+
+ extern void efi_call_virt_check_flags(unsigned long flags, const char *call);
+
+-enum efi_secureboot_mode {
+- efi_secureboot_mode_unset,
+- efi_secureboot_mode_unknown,
+- efi_secureboot_mode_disabled,
+- efi_secureboot_mode_enabled,
+-};
+ enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table);
+
+ #ifdef CONFIG_RESET_ATTACK_MITIGATION
diff --git a/debian/patches/features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch b/debian/patches/features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch
new file mode 100644
index 000000000..9ab10afb3
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch
@@ -0,0 +1,83 @@
+From: David Howells <dhowells@redhat.com>
+Date: Wed, 8 Nov 2017 15:11:37 +0000
+Subject: [29/29] efi: Lock down the kernel if booted in secure boot mode
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a364bd945ffc141a7b17cb331bda0d8ad68f7e72
+
+UEFI Secure Boot provides a mechanism for ensuring that the firmware will
+only load signed bootloaders and kernels. Certain use cases may also
+require that all kernel modules also be signed. Add a configuration option
+that to lock down the kernel - which includes requiring validly signed
+modules - if the kernel is secure-booted.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+cc: linux-efi@vger.kernel.org
+---
+ arch/x86/kernel/setup.c | 6 ++++--
+ security/Kconfig | 14 ++++++++++++++
+ security/lock_down.c | 1 +
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -65,6 +65,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/ctype.h>
+ #include <linux/uaccess.h>
++#include <linux/security.h>
+
+ #include <linux/percpu.h>
+ #include <linux/crash_dump.h>
+@@ -1005,6 +1006,9 @@ void __init setup_arch(char **cmdline_p)
+ if (efi_enabled(EFI_BOOT))
+ efi_init();
+
++ efi_set_secure_boot(boot_params.secure_boot);
++ init_lockdown();
++
+ dmi_scan_machine();
+ dmi_memdev_walk();
+ dmi_set_dump_stack_arch_desc();
+@@ -1159,8 +1163,6 @@ void __init setup_arch(char **cmdline_p)
+ /* Allocate bigger log buffer */
+ setup_log_buf(1);
+
+- efi_set_secure_boot(boot_params.secure_boot);
+-
+ reserve_initrd();
+
+ acpi_table_upgrade();
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -247,6 +247,21 @@ config LOCK_DOWN_KERNEL
+ turns off various features that might otherwise allow access to the
+ kernel image (eg. setting MSR registers).
+
++config LOCK_DOWN_IN_EFI_SECURE_BOOT
++ bool "Lock down the kernel in EFI Secure Boot mode"
++ default n
++ select LOCK_DOWN_KERNEL
++ depends on EFI
++ help
++ UEFI Secure Boot provides a mechanism for ensuring that the firmware
++ will only load signed bootloaders and kernels. Secure boot mode may
++ be determined from EFI variables provided by the system firmware if
++ not indicated by the boot parameters.
++
++ Enabling this option turns on results in kernel lockdown being
++ triggered if EFI Secure Boot is set.
++
++
+ source security/selinux/Kconfig
+ source security/smack/Kconfig
+ source security/tomoyo/Kconfig
+--- a/security/lock_down.c
++++ b/security/lock_down.c
+@@ -11,6 +11,7 @@
+
+ #include <linux/security.h>
+ #include <linux/export.h>
++#include <linux/efi.h>
+
+ static __ro_after_init bool kernel_locked_down;
+
diff --git a/debian/patches/features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch b/debian/patches/features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch
new file mode 100644
index 000000000..bb2f4f60b
--- /dev/null
+++ b/debian/patches/features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch
@@ -0,0 +1,36 @@
+From: Matthew Garrett <matthewgarrett@google.com>
+Date: Wed, 31 Jul 2019 15:16:16 -0700
+Subject: efi: Restrict efivar_ssdt_load when the kernel is locked down
+Origin: https://patchwork.kernel.org/patch/11069659/
+
+efivar_ssdt_load allows the kernel to import arbitrary ACPI code from an
+EFI variable, which gives arbitrary code execution in ring 0. Prevent
+that when the kernel is locked down.
+
+Signed-off-by: Matthew Garrett <mjg59@google.com>
+Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Cc: linux-efi@vger.kernel.org
+[bwh: Convert back to the non-LSM lockdown API]
+---
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -30,6 +30,7 @@
+ #include <linux/acpi.h>
+ #include <linux/ucs2_string.h>
+ #include <linux/memblock.h>
++#include <linux/security.h>
+
+ #include <asm/early_ioremap.h>
+
+@@ -241,6 +242,9 @@ static void generic_ops_unregister(void)
+ static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata;
+ static int __init efivar_ssdt_setup(char *str)
+ {
++ if (kernel_is_locked_down("ACPI tables"))
++ return -EPERM;
++
+ if (strlen(str) < sizeof(efivar_ssdt))
+ memcpy(efivar_ssdt, str, strlen(str));
+ else
diff --git a/debian/patches/features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch b/debian/patches/features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch
new file mode 100644
index 000000000..4970a4bd4
--- /dev/null
+++ b/debian/patches/features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch
@@ -0,0 +1,44 @@
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Mon, 15 Jun 2020 04:43:32 -0600
+Subject: ACPI: configfs: Disallow loading ACPI tables when locked down
+Origin: https://git.kernel.org/linus/75b0cea7bf307f362057cc778efe89af4c615354
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-15780
+
+Like other vectors already patched, this one here allows the root
+user to load ACPI tables, which enables arbitrary physical address
+writes, which in turn makes it possible to disable lockdown.
+
+Prevents this by checking the lockdown status before allowing a new
+ACPI table to be installed. The link in the trailer shows a PoC of
+how this might be used.
+
+Link: https://git.zx2c4.com/american-unsigned-language/tree/american-unsigned-language-2.sh
+Cc: 5.4+ <stable@vger.kernel.org> # 5.4+
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+[Salvatore Bonaccorso: Backport to v4.19.y: Use kernel_is_locked_down instead
+of security_locked_down]
+---
+ drivers/acpi/acpi_configfs.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/acpi/acpi_configfs.c
++++ b/drivers/acpi/acpi_configfs.c
+@@ -14,6 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/configfs.h>
+ #include <linux/acpi.h>
++#include <linux/security.h>
+
+ #include "acpica/accommon.h"
+ #include "acpica/actables.h"
+@@ -33,6 +34,9 @@ static ssize_t acpi_table_aml_write(stru
+ struct acpi_table *table;
+ int ret;
+
++ if (kernel_is_locked_down("Modifying ACPI tables"))
++ return -EPERM;
++
+ table = container_of(cfg, struct acpi_table, cfg);
+
+ if (table->header) {
diff --git a/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch
new file mode 100644
index 000000000..beb09c3e6
--- /dev/null
+++ b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch
@@ -0,0 +1,97 @@
+From: Linn Crosetto <linn@hpe.com>
+Date: Tue, 30 Aug 2016 11:54:38 -0600
+Subject: arm64: add kernel config option to lock down when in Secure Boot mode
+Bug-Debian: https://bugs.debian.org/831827
+Forwarded: no
+
+Add a kernel configuration option to lock down the kernel, to restrict
+userspace's ability to modify the running kernel when UEFI Secure Boot is
+enabled. Based on the x86 patch by Matthew Garrett.
+
+Determine the state of Secure Boot in the EFI stub and pass this to the
+kernel using the FDT.
+
+Signed-off-by: Linn Crosetto <linn@hpe.com>
+[bwh: Forward-ported to 4.10: adjust context]
+[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream]
+[bwh: Forward-ported to 4.15 and lockdown patch set:
+ - Pass result of efi_get_secureboot() in stub through to
+ efi_set_secure_boot() in main kernel
+ - Use lockdown API and naming]
+[bwh: Forward-ported to 4.19.3: adjust context in update_fdt()]
+[dannf: Moved init_lockdown() call after uefi_init(), fixing SB detection]
+---
+ arch/arm64/Kconfig | 13 +++++++++++++
+ drivers/firmware/efi/arm-init.c | 7 +++++++
+ drivers/firmware/efi/efi.c | 3 ++-
+ drivers/firmware/efi/libstub/arm-stub.c | 2 +-
+ drivers/firmware/efi/libstub/efistub.h | 1 +
+ drivers/firmware/efi/libstub/fdt.c | 7 +++++++
+ include/linux/efi.h | 1 +
+ 7 files changed, 32 insertions(+), 2 deletions(-)
+
+Index: linux/drivers/firmware/efi/arm-init.c
+===================================================================
+--- linux.orig/drivers/firmware/efi/arm-init.c
++++ linux/drivers/firmware/efi/arm-init.c
+@@ -21,6 +21,7 @@
+ #include <linux/of_fdt.h>
+ #include <linux/platform_device.h>
+ #include <linux/screen_info.h>
++#include <linux/security.h>
+
+ #include <asm/efi.h>
+
+@@ -257,6 +258,9 @@ void __init efi_init(void)
+ return;
+ }
+
++ efi_set_secure_boot(params.secure_boot);
++ init_lockdown();
++
+ reserve_regions();
+ efi_esrt_init();
+
+Index: linux/drivers/firmware/efi/efi.c
+===================================================================
+--- linux.orig/drivers/firmware/efi/efi.c
++++ linux/drivers/firmware/efi/efi.c
+@@ -660,7 +660,8 @@ static __initdata struct params fdt_para
+ UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap),
+ UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size),
+ UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size),
+- UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver)
++ UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver),
++ UEFI_PARAM("Secure Boot Enabled", "linux,uefi-secure-boot", secure_boot)
+ };
+
+ static __initdata struct params xen_fdt_params[] = {
+Index: linux/drivers/firmware/efi/libstub/fdt.c
+===================================================================
+--- linux.orig/drivers/firmware/efi/libstub/fdt.c
++++ linux/drivers/firmware/efi/libstub/fdt.c
+@@ -159,6 +159,12 @@ static efi_status_t update_fdt(efi_syste
+ }
+ }
+
++ fdt_val32 = cpu_to_fdt32(efi_get_secureboot(sys_table));
++ status = fdt_setprop(fdt, node, "linux,uefi-secure-boot",
++ &fdt_val32, sizeof(fdt_val32));
++ if (status)
++ goto fdt_set_fail;
++
+ /* shrink the FDT back to its minimum size */
+ fdt_pack(fdt);
+
+Index: linux/include/linux/efi.h
+===================================================================
+--- linux.orig/include/linux/efi.h
++++ linux/include/linux/efi.h
+@@ -786,6 +786,7 @@ struct efi_fdt_params {
+ u32 mmap_size;
+ u32 desc_size;
+ u32 desc_ver;
++ u32 secure_boot;
+ };
+
+ typedef struct {
diff --git a/debian/patches/features/all/lockdown/enable-cold-boot-attack-mitigation.patch b/debian/patches/features/all/lockdown/enable-cold-boot-attack-mitigation.patch
new file mode 100644
index 000000000..7a3b8e9bb
--- /dev/null
+++ b/debian/patches/features/all/lockdown/enable-cold-boot-attack-mitigation.patch
@@ -0,0 +1,50 @@
+From: Matthew Garrett <mjg59@coreos.com>
+Date: Tue, 12 Jan 2016 12:51:27 -0800
+Subject: [18/18] Enable cold boot attack mitigation
+Origin: https://github.com/mjg59/linux/commit/02d999574936dd234a508c0112a0200c135a5c34
+
+[Lukas Wunner: Forward-ported to 4.11: adjust context]
+---
+ arch/x86/boot/compressed/eboot.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+Index: linux/arch/x86/boot/compressed/eboot.c
+===================================================================
+--- linux.orig/arch/x86/boot/compressed/eboot.c
++++ linux/arch/x86/boot/compressed/eboot.c
+@@ -372,6 +372,22 @@ void setup_graphics(struct boot_params *
+ }
+ }
+
++#define MEMORY_ONLY_RESET_CONTROL_GUID \
++ EFI_GUID (0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
++
++static void enable_reset_attack_mitigation(void)
++{
++ u8 val = 1;
++ efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
++
++ /* Ignore the return value here - there's not really a lot we can do */
++ efi_early->call((unsigned long)sys_table->runtime->set_variable,
++ L"MemoryOverwriteRequestControl", &var_guid,
++ EFI_VARIABLE_NON_VOLATILE |
++ EFI_VARIABLE_BOOTSERVICE_ACCESS |
++ EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), val);
++}
++
+ /*
+ * Because the x86 boot code expects to be passed a boot_params we
+ * need to create one ourselves (usually the bootloader would create
+@@ -783,6 +799,12 @@ efi_main(struct efi_config *c, struct bo
+ efi_parse_options((char *)cmdline_paddr);
+
+ /*
++ * Ask the firmware to clear memory if we don't have a clean
++ * shutdown
++ */
++ enable_reset_attack_mitigation();
++
++ /*
+ * If the boot loader gave us a value for secure_boot then we use that,
+ * otherwise we ask the BIOS.
+ */
diff --git a/debian/patches/features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch b/debian/patches/features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch
new file mode 100644
index 000000000..586be8cab
--- /dev/null
+++ b/debian/patches/features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch
@@ -0,0 +1,34 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sun, 21 Apr 2019 00:17:13 +0100
+Subject: lockdown: Refer to Debian wiki until manual page exists
+Forwarded: not-needed
+
+The lockdown denial log message currently refers to a
+"kernel_lockdown.7" manual page, which is supposed to document it.
+That manual page hasn't been accepted by the man-pages project and
+doesn't even seem to have been submitted yet. For now, refer to the
+Debian wiki.
+
+---
+Index: linux/security/lock_down.c
+===================================================================
+--- linux.orig/security/lock_down.c
++++ linux/security/lock_down.c
+@@ -28,7 +28,7 @@ static void __init lock_kernel_down(cons
+ {
+ if (!kernel_locked_down) {
+ kernel_locked_down = true;
+- pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n",
++ pr_notice("Kernel is locked down from %s; see https://wiki.debian.org/SecureBoot\n",
+ where);
+ }
+ }
+@@ -60,7 +60,7 @@ void __init init_lockdown(void)
+ bool __kernel_is_locked_down(const char *what, bool first)
+ {
+ if (what && first && kernel_locked_down)
+- pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n",
++ pr_notice("Lockdown: %s is restricted; see https://wiki.debian.org/SecureBoot\n",
+ what);
+ return kernel_locked_down;
+ }
diff --git a/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch
new file mode 100644
index 000000000..f02392f10
--- /dev/null
+++ b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch
@@ -0,0 +1,41 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 03 Jun 2016 00:48:39 +0100
+Subject: mtd: Disable slram and phram when locked down
+Forwarded: no
+
+The slram and phram drivers both allow mapping regions of physical
+address space such that they can then be read and written by userland
+through the MTD interface. This is probably usable to manipulate
+hardware into overwriting kernel code on many systems. Prevent that
+if locked down.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/drivers/mtd/devices/phram.c
+===================================================================
+--- linux.orig/drivers/mtd/devices/phram.c
++++ linux/drivers/mtd/devices/phram.c
+@@ -219,6 +219,9 @@ static int phram_setup(const char *val)
+ uint64_t len;
+ int i, ret;
+
++ if (kernel_is_locked_down("Command line-specified device addresses"))
++ return -EPERM;
++
+ if (strnlen(val, sizeof(buf)) >= sizeof(buf))
+ parse_err("parameter too long\n");
+
+Index: linux/drivers/mtd/devices/slram.c
+===================================================================
+--- linux.orig/drivers/mtd/devices/slram.c
++++ linux/drivers/mtd/devices/slram.c
+@@ -226,6 +226,9 @@ static int parse_cmdline(char *devname,
+ unsigned long devstart;
+ unsigned long devlength;
+
++ if (kernel_is_locked_down("Command line-specified device addresses"))
++ return -EPERM;
++
+ if ((!devname) || (!szstart) || (!szlength)) {
+ unregister_devices();
+ return(-EINVAL);
diff --git a/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch
new file mode 100644
index 000000000..22cd1283a
--- /dev/null
+++ b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch
@@ -0,0 +1,81 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 11 Jan 2016 15:23:55 +0000
+Subject: security,perf: Allow further restriction of perf_event_open
+Forwarded: https://lkml.org/lkml/2016/1/11/587
+
+When kernel.perf_event_open is set to 3 (or greater), disallow all
+access to performance events by users without CAP_SYS_ADMIN.
+Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that
+makes this value the default.
+
+This is based on a similar feature in grsecurity
+(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making
+the variable read-only. It also allows enabling further restriction
+at run-time regardless of whether the default is changed.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+Index: linux/include/linux/perf_event.h
+===================================================================
+--- linux.orig/include/linux/perf_event.h
++++ linux/include/linux/perf_event.h
+@@ -1189,6 +1189,11 @@ extern int perf_cpu_time_max_percent_han
+ int perf_event_max_stack_handler(struct ctl_table *table, int write,
+ void __user *buffer, size_t *lenp, loff_t *ppos);
+
++static inline bool perf_paranoid_any(void)
++{
++ return sysctl_perf_event_paranoid > 2;
++}
++
+ static inline bool perf_paranoid_tracepoint_raw(void)
+ {
+ return sysctl_perf_event_paranoid > -1;
+Index: linux/kernel/events/core.c
+===================================================================
+--- linux.orig/kernel/events/core.c
++++ linux/kernel/events/core.c
+@@ -397,8 +397,13 @@ static cpumask_var_t perf_online_mask;
+ * 0 - disallow raw tracepoint access for unpriv
+ * 1 - disallow cpu events for unpriv
+ * 2 - disallow kernel profiling for unpriv
++ * 3 - disallow all unpriv perf event use
+ */
++#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT
++int sysctl_perf_event_paranoid __read_mostly = 3;
++#else
+ int sysctl_perf_event_paranoid __read_mostly = 2;
++#endif
+
+ /* Minimum for 512 kiB + 1 user control page */
+ int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */
+@@ -10485,6 +10490,9 @@ SYSCALL_DEFINE5(perf_event_open,
+ if (flags & ~PERF_FLAG_ALL)
+ return -EINVAL;
+
++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
+ err = perf_copy_attr(attr_uptr, &attr);
+ if (err)
+ return err;
+Index: linux/security/Kconfig
+===================================================================
+--- linux.orig/security/Kconfig
++++ linux/security/Kconfig
+@@ -18,6 +18,15 @@ config SECURITY_DMESG_RESTRICT
+
+ If you are unsure how to answer this question, answer N.
+
++config SECURITY_PERF_EVENTS_RESTRICT
++ bool "Restrict unprivileged use of performance events"
++ depends on PERF_EVENTS
++ help
++ If you say Y here, the kernel.perf_event_paranoid sysctl
++ will be set to 3 by default, and no unprivileged use of the
++ perf_event_open syscall will be permitted unless it is
++ changed.
++
+ config SECURITY
+ bool "Enable different security models"
+ depends on SYSFS
diff --git a/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch
new file mode 100644
index 000000000..45f7696da
--- /dev/null
+++ b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch
@@ -0,0 +1,211 @@
+From: Stefan Wahren <stefan.wahren@i2se.com>
+Date: Fri, 28 Dec 2018 23:09:26 +0100
+Subject: ARM: dts: add Raspberry Pi 3 A+
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=bd80be88e05792db948bf3567a216743fdea5027
+
+The Raspberry Pi 3 A+ is similar to the Pi 3 B+ but has only 512 MB RAM,
+1 USB 2.0 port and no Ethernet.
+
+Compared to the Raspberry Pi 3 B it isn't possible to control BT_ON and
+WL_ON separately.
+
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Acked-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm/boot/dts/Makefile | 1 +
+ arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 175 +++++++++++++++++++++
+ 2 files changed, 176 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+
+Index: debian-kernel/arch/arm/boot/dts/Makefile
+===================================================================
+--- debian-kernel.orig/arch/arm/boot/dts/Makefile
++++ debian-kernel/arch/arm/boot/dts/Makefile
+@@ -79,6 +79,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2835-rpi-a-plus.dtb \
+ bcm2835-rpi-cm1-io1.dtb \
+ bcm2836-rpi-2-b.dtb \
++ bcm2837-rpi-3-a-plus.dtb \
+ bcm2837-rpi-3-b.dtb \
+ bcm2837-rpi-3-b-plus.dtb \
+ bcm2837-rpi-cm3-io3.dtb \
+Index: debian-kernel/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+===================================================================
+--- /dev/null
++++ debian-kernel/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
+@@ -0,0 +1,175 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++#include "bcm2837.dtsi"
++#include "bcm2836-rpi.dtsi"
++#include "bcm283x-rpi-usb-host.dtsi"
++
++/ {
++ compatible = "raspberrypi,3-model-a-plus", "brcm,bcm2837";
++ model = "Raspberry Pi 3 Model A+";
++
++ chosen {
++ /* 8250 auxiliary UART instead of pl011 */
++ stdout-path = "serial1:115200n8";
++ };
++
++ memory {
++ reg = <0 0x20000000>;
++ };
++
++ leds {
++ act {
++ gpios = <&gpio 29 GPIO_ACTIVE_HIGH>;
++ };
++
++ pwr {
++ label = "PWR";
++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>;
++ };
++ };
++};
++
++&firmware {
++ expgpio: gpio {
++ compatible = "raspberrypi,firmware-gpio";
++ gpio-controller;
++ #gpio-cells = <2>;
++ gpio-line-names = "",
++ "BT_WL_ON",
++ "STATUS_LED_R",
++ "",
++ "",
++ "CAM_GPIO0",
++ "CAM_GPIO1",
++ "";
++ status = "okay";
++ };
++};
++
++&gpio {
++ /*
++ * This is mostly based on the official GPU firmware DT blob.
++ *
++ * Legend:
++ * "NC" = not connected (no rail from the SoC)
++ * "FOO" = GPIO line named "FOO" on the schematic
++ * "FOO_N" = GPIO line named "FOO" on schematic, active low
++ */
++ gpio-line-names = "ID_SDA",
++ "ID_SCL",
++ "SDA1",
++ "SCL1",
++ "GPIO_GCLK",
++ "GPIO5",
++ "GPIO6",
++ "SPI_CE1_N",
++ "SPI_CE0_N",
++ "SPI_MISO",
++ "SPI_MOSI",
++ "SPI_SCLK",
++ "GPIO12",
++ "GPIO13",
++ /* Serial port */
++ "TXD1",
++ "RXD1",
++ "GPIO16",
++ "GPIO17",
++ "GPIO18",
++ "GPIO19",
++ "GPIO20",
++ "GPIO21",
++ "GPIO22",
++ "GPIO23",
++ "GPIO24",
++ "GPIO25",
++ "GPIO26",
++ "GPIO27",
++ "HDMI_HPD_N",
++ "STATUS_LED_G",
++ /* Used by BT module */
++ "CTS0",
++ "RTS0",
++ "TXD0",
++ "RXD0",
++ /* Used by Wifi */
++ "SD1_CLK",
++ "SD1_CMD",
++ "SD1_DATA0",
++ "SD1_DATA1",
++ "SD1_DATA2",
++ "SD1_DATA3",
++ "PWM0_OUT",
++ "PWM1_OUT",
++ "", /* GPIO42 */
++ "WIFI_CLK",
++ "SDA0",
++ "SCL0",
++ "SMPS_SCL",
++ "SMPS_SDA",
++ /* Used by SD Card */
++ "SD_CLK_R",
++ "SD_CMD_R",
++ "SD_DATA0_R",
++ "SD_DATA1_R",
++ "SD_DATA2_R",
++ "SD_DATA3_R";
++};
++
++&hdmi {
++ hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
++};
++
++&pwm {
++ pinctrl-names = "default";
++ pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio41>;
++ status = "okay";
++};
++
++/*
++ * SDHCI is used to control the SDIO for wireless
++ *
++ * WL_REG_ON and BT_REG_ON of the CYW43455 Wifi/BT module are driven
++ * by a single GPIO. We can't give GPIO control to one of the drivers,
++ * otherwise the other part would get unexpectedly disturbed.
++ */
++&sdhci {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ pinctrl-names = "default";
++ pinctrl-0 = <&emmc_gpio34>;
++ status = "okay";
++ bus-width = <4>;
++ non-removable;
++
++ brcmf: wifi@1 {
++ reg = <1>;
++ compatible = "brcm,bcm4329-fmac";
++ };
++};
++
++/* SDHOST is used to drive the SD card */
++&sdhost {
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhost_gpio48>;
++ status = "okay";
++ bus-width = <4>;
++};
++
++/* uart0 communicates with the BT module */
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>;
++ status = "okay";
++
++ bluetooth {
++ compatible = "brcm,bcm43438-bt";
++ max-speed = <2000000>;
++ };
++};
++
++/* uart1 is mapped to the pin header */
++&uart1 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart1_gpio14>;
++ status = "okay";
++};
diff --git a/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch
new file mode 100644
index 000000000..e746f9e1a
--- /dev/null
+++ b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch
@@ -0,0 +1,183 @@
+From: Stefan Wahren <stefan.wahren@i2se.com>
+Date: Mon, 27 Aug 2018 19:31:17 +0200
+Subject: ARM: dts: add Raspberry Pi Compute Module 3 and IO board
+Origin: https://git.kernel.org/linus/a54fe8a6cf66828499b121c3c39c194b43b8ed94
+
+The Raspberry Pi Compute Module 3 (CM3) and the Raspberry Pi
+Compute Module 3 Lite (CM3L) are SoMs which contains a BCM2837 processor,
+1 GB RAM and a GPIO expander. The CM3 has a 4 GB eMMC, but on the CM3L
+the eMMC is unpopulated and it's up to the user to connect their
+own SD/MMC device. The dtsi file is designed to work for both modules.
+There is also a matching carrier board which is called
+Compute Module IO Board V3.
+
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+---
+ arch/arm/boot/dts/Makefile | 1 +
+ arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts | 87 +++++++++++++++++++++++++++++++
+ arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 52 ++++++++++++++++++
+ 3 files changed, 140 insertions(+)
+ create mode 100644 arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
+ create mode 100644 arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+
+Index: linux/arch/arm/boot/dts/Makefile
+===================================================================
+--- linux.orig/arch/arm/boot/dts/Makefile
++++ linux/arch/arm/boot/dts/Makefile
+@@ -81,6 +81,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \
+ bcm2836-rpi-2-b.dtb \
+ bcm2837-rpi-3-b.dtb \
+ bcm2837-rpi-3-b-plus.dtb \
++ bcm2837-rpi-cm3-io3.dtb \
+ bcm2835-rpi-zero.dtb \
+ bcm2835-rpi-zero-w.dtb
+ dtb-$(CONFIG_ARCH_BCM_5301X) += \
+Index: linux/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
+===================================================================
+--- /dev/null
++++ linux/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
+@@ -0,0 +1,87 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++#include "bcm2837-rpi-cm3.dtsi"
++#include "bcm283x-rpi-usb-host.dtsi"
++
++/ {
++ compatible = "raspberrypi,3-compute-module", "brcm,bcm2837";
++ model = "Raspberry Pi Compute Module 3 IO board V3.0";
++};
++
++&gpio {
++ /*
++ * This is based on the official GPU firmware DT blob.
++ *
++ * Legend:
++ * "NC" = not connected (no rail from the SoC)
++ * "FOO" = GPIO line named "FOO" on the schematic
++ * "FOO_N" = GPIO line named "FOO" on schematic, active low
++ */
++ gpio-line-names = "GPIO0",
++ "GPIO1",
++ "GPIO2",
++ "GPIO3",
++ "GPIO4",
++ "GPIO5",
++ "GPIO6",
++ "GPIO7",
++ "GPIO8",
++ "GPIO9",
++ "GPIO10",
++ "GPIO11",
++ "GPIO12",
++ "GPIO13",
++ "GPIO14",
++ "GPIO15",
++ "GPIO16",
++ "GPIO17",
++ "GPIO18",
++ "GPIO19",
++ "GPIO20",
++ "GPIO21",
++ "GPIO22",
++ "GPIO23",
++ "GPIO24",
++ "GPIO25",
++ "GPIO26",
++ "GPIO27",
++ "GPIO28",
++ "GPIO29",
++ "GPIO30",
++ "GPIO31",
++ "GPIO32",
++ "GPIO33",
++ "GPIO34",
++ "GPIO35",
++ "GPIO36",
++ "GPIO37",
++ "GPIO38",
++ "GPIO39",
++ "GPIO40",
++ "GPIO41",
++ "GPIO42",
++ "GPIO43",
++ "GPIO44",
++ "GPIO45",
++ "GPIO46",
++ "GPIO47",
++ /* Used by eMMC */
++ "SD_CLK_R",
++ "SD_CMD_R",
++ "SD_DATA0_R",
++ "SD_DATA1_R",
++ "SD_DATA2_R",
++ "SD_DATA3_R";
++
++ pinctrl-0 = <&gpioout &alt0>;
++};
++
++&hdmi {
++ hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
++};
++
++&uart0 {
++ pinctrl-names = "default";
++ pinctrl-0 = <&uart0_gpio14>;
++ status = "okay";
++};
+Index: linux/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+===================================================================
+--- /dev/null
++++ linux/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
+@@ -0,0 +1,52 @@
++// SPDX-License-Identifier: GPL-2.0
++/dts-v1/;
++#include "bcm2837.dtsi"
++#include "bcm2835-rpi.dtsi"
++
++/ {
++ memory {
++ reg = <0 0x40000000>;
++ };
++
++ reg_3v3: fixed-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "3V3";
++ regulator-min-microvolt = <3300000>;
++ regulator-max-microvolt = <3300000>;
++ regulator-always-on;
++ };
++
++ reg_1v8: fixed-regulator {
++ compatible = "regulator-fixed";
++ regulator-name = "1V8";
++ regulator-min-microvolt = <1800000>;
++ regulator-max-microvolt = <1800000>;
++ regulator-always-on;
++ };
++};
++
++&firmware {
++ expgpio: gpio {
++ compatible = "raspberrypi,firmware-gpio";
++ gpio-controller;
++ #gpio-cells = <2>;
++ gpio-line-names = "HDMI_HPD_N",
++ "EMMC_EN_N",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "NC",
++ "NC";
++ status = "okay";
++ };
++};
++
++&sdhost {
++ pinctrl-names = "default";
++ pinctrl-0 = <&sdhost_gpio48>;
++ bus-width = <4>;
++ vmmc-supply = <&reg_3v3>;
++ vqmmc-supply = <&reg_1v8>;
++ status = "okay";
++};
diff --git a/debian/patches/features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch b/debian/patches/features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch
new file mode 100644
index 000000000..8dfed0cb1
--- /dev/null
+++ b/debian/patches/features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch
@@ -0,0 +1,35 @@
+From: Romain Perier <romain.perier@gmail.com>
+Date: Wed, 16 Oct 2019 19:03:00 +0200
+Subject: ARM: dts: bcm283x: Correct vchiq compatible string
+
+This allows VCHIQ to determine the correct cache line size, use the new
+"brcm,bcm2836-vchiq" compatible string on BCM2836. It is based on commit
+499770 ("ARM: dts: bcm283x: Correct vchiq compatible string")
+
+Signed-off-by: Romain Perier <romain.perier@gmail.com>
+---
+ arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +-
+ arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 ++++++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi
+
+--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi
++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi
+@@ -30,7 +30,7 @@
+ #power-domain-cells = <1>;
+ };
+
+- mailbox@7e00b840 {
++ vchiq: mmailbox@7e00b840 {
+ compatible = "brcm,bcm2835-vchiq";
+ reg = <0x7e00b840 0x3c>;
+ interrupts = <0 2>;
+--- /dev/null
++++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi
+@@ -0,0 +1,6 @@
++// SPDX-License-Identifier: GPL-2.0
++#include "bcm2835-rpi.dtsi"
++
++&vchiq {
++ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq";
++};
diff --git a/debian/patches/features/arm/staging-vc04_services-Use-correct-cache-line-size.patch b/debian/patches/features/arm/staging-vc04_services-Use-correct-cache-line-size.patch
new file mode 100644
index 000000000..b77ae1b02
--- /dev/null
+++ b/debian/patches/features/arm/staging-vc04_services-Use-correct-cache-line-size.patch
@@ -0,0 +1,133 @@
+From: Phil Elwell <phil@raspberrypi.org>
+Date: Mon, 17 Sep 2018 09:22:21 +0100
+Subject: staging/vc04_services: Use correct cache line size
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=c683db8860a80562a2bb5b451d77b3e471d24f36
+
+Use the compatible string in the DTB to select the correct cache line
+size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837.
+
+Signed-off-by: Phil Elwell <phil@raspberrypi.org>
+Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../interface/vchiq_arm/vchiq_2835_arm.c | 4 ++-
+ .../interface/vchiq_arm/vchiq_arm.c | 35 +++++++++++++------
+ .../interface/vchiq_arm/vchiq_arm.h | 5 +++
+ 3 files changed, 33 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+index 3bece6b86831..dd67b80c0f99 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+@@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo,
+ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
+ {
+ struct device *dev = &pdev->dev;
+- struct rpi_firmware *fw = platform_get_drvdata(pdev);
++ struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev);
++ struct rpi_firmware *fw = drvdata->fw;
+ VCHIQ_SLOT_ZERO_T *vchiq_slot_zero;
+ struct resource *res;
+ void *slot_mem;
+@@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state)
+ if (err < 0)
+ return err;
+
++ g_cache_line_size = drvdata->cache_line_size;
+ g_fragments_size = 2 * g_cache_line_size;
+
+ /* Allocate space for the channels in coherent memory */
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+index fe431302a030..45de21c210c1 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
+@@ -170,6 +170,14 @@ static struct device *vchiq_dev;
+ static DEFINE_SPINLOCK(msg_queue_spinlock);
+ static struct platform_device *bcm2835_camera;
+
++static struct vchiq_drvdata bcm2835_drvdata = {
++ .cache_line_size = 32,
++};
++
++static struct vchiq_drvdata bcm2836_drvdata = {
++ .cache_line_size = 64,
++};
++
+ static const char *const ioctl_names[] = {
+ "CONNECT",
+ "SHUTDOWN",
+@@ -3578,12 +3586,25 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state,
+ }
+ }
+
++static const struct of_device_id vchiq_of_match[] = {
++ { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata },
++ { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata },
++ {},
++};
++MODULE_DEVICE_TABLE(of, vchiq_of_match);
++
+ static int vchiq_probe(struct platform_device *pdev)
+ {
+ struct device_node *fw_node;
+- struct rpi_firmware *fw;
++ const struct of_device_id *of_id;
++ struct vchiq_drvdata *drvdata;
+ int err;
+
++ of_id = of_match_node(vchiq_of_match, pdev->dev.of_node);
++ drvdata = (struct vchiq_drvdata *)of_id->data;
++ if (!drvdata)
++ return -EINVAL;
++
+ fw_node = of_find_compatible_node(NULL, NULL,
+ "raspberrypi,bcm2835-firmware");
+ if (!fw_node) {
+@@ -3591,12 +3612,12 @@ static int vchiq_probe(struct platform_device *pdev)
+ return -ENOENT;
+ }
+
+- fw = rpi_firmware_get(fw_node);
++ drvdata->fw = rpi_firmware_get(fw_node);
+ of_node_put(fw_node);
+- if (!fw)
++ if (!drvdata->fw)
+ return -EPROBE_DEFER;
+
+- platform_set_drvdata(pdev, fw);
++ platform_set_drvdata(pdev, drvdata);
+
+ err = vchiq_platform_init(pdev, &g_state);
+ if (err != 0)
+@@ -3666,12 +3687,6 @@ static int vchiq_remove(struct platform_device *pdev)
+ return 0;
+ }
+
+-static const struct of_device_id vchiq_of_match[] = {
+- { .compatible = "brcm,bcm2835-vchiq", },
+- {},
+-};
+-MODULE_DEVICE_TABLE(of, vchiq_of_match);
+-
+ static struct platform_driver vchiq_driver = {
+ .driver = {
+ .name = "bcm2835_vchiq",
+diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+index 40bb0c63b1a9..2f3ebc99cbcf 100644
+--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h
+@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct {
+
+ } VCHIQ_ARM_STATE_T;
+
++struct vchiq_drvdata {
++ const unsigned int cache_line_size;
++ struct rpi_firmware *fw;
++};
++
+ extern int vchiq_arm_log_level;
+ extern int vchiq_susp_log_level;
+
+--
+2.23.0
+
diff --git a/debian/patches/features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch b/debian/patches/features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch
new file mode 100644
index 000000000..c87b9f1a9
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch
@@ -0,0 +1,55 @@
+From: Andre Przywara <andre.przywara@arm.com>
+Date: Mon, 30 Jul 2018 13:31:20 +0100
+Subject: arm64: dts: allwinner: a64: Add Pine64-LTS device tree file
+Origin: https://git.kernel.org/linus/b3ee15a509ffd7473b77b21cb921b3128efdd005
+
+The Pine64-LTS is a variant of the Pine64 board, from the software
+visible side resembling a SoPine module on a baseboard, though the
+board has the SoC and DRAM integrated on one PCB.
+Due to this it basically shares the DT with the SoPine baseboard, which
+we mimic in our DT by inclucing the boardboard .dts into the new file,
+just overwriting the model name.
+Having a separate .dts for this seems useful, since we don't know yet if
+there are subtle differences between the two. Also the SoC on the LTS
+board is technically an "R18" instead of the original "A64", although as
+far as we know this is just a relabelled version of the original SoC.
+
+Signed-off-by: Andre Przywara <andre.przywara@arm.com>
+Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+---
+ arch/arm64/boot/dts/allwinner/Makefile | 1 +
+ .../boot/dts/allwinner/sun50i-a64-pine64-lts.dts | 13 +++++++++++++
+ 2 files changed, 14 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
+
+Index: linux/arch/arm64/boot/dts/allwinner/Makefile
+===================================================================
+--- linux.orig/arch/arm64/boot/dts/allwinner/Makefile
++++ linux/arch/arm64/boot/dts/allwinner/Makefile
+@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-b
+ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb
+ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb
+ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb
++dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-lts.dtb
+ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
+ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinebook.dtb
+ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb
+Index: linux/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
+===================================================================
+--- /dev/null
++++ linux/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
+@@ -0,0 +1,13 @@
++/*
++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
++ *
++ * Copyright (c) 2018 ARM Ltd.
++ */
++
++#include "sun50i-a64-sopine-baseboard.dts"
++
++/ {
++ model = "Pine64 LTS";
++ compatible = "pine64,pine64-lts", "allwinner,sun50i-r18",
++ "allwinner,sun50i-a64";
++};
diff --git a/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch
new file mode 100644
index 000000000..1d34ce743
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch
@@ -0,0 +1,35 @@
+From: Stefan Wahren <stefan.wahren@i2se.com>
+Date: Mon, 27 Aug 2018 19:33:28 +0200
+Subject: arm64: dts: broadcom: Add reference to Compute Module IO Board V3
+Origin: https://git.kernel.org/linus/a7eb26392b893bff92b1eb6483f4af3d2eb19510
+
+This adds a reference to the dts of the Compute Module IO Board V3 in arm,
+so we don't need to maintain the content in arm64.
+
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+---
+ arch/arm64/boot/dts/broadcom/Makefile | 3 ++-
+ arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts | 2 ++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts
+
+Index: linux/arch/arm64/boot/dts/broadcom/Makefile
+===================================================================
+--- linux.orig/arch/arm64/boot/dts/broadcom/Makefile
++++ linux/arch/arm64/boot/dts/broadcom/Makefile
+@@ -1,6 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \
+- bcm2837-rpi-3-b-plus.dtb
++ bcm2837-rpi-3-b-plus.dtb \
++ bcm2837-rpi-cm3-io3.dts
+
+ subdir-y += northstar2
+ subdir-y += stingray
+Index: linux/arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts
+===================================================================
+--- /dev/null
++++ linux/arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts
+@@ -0,0 +1,2 @@
++// SPDX-License-Identifier: GPL-2.0
++#include "arm/bcm2837-rpi-cm3-io3.dts"
diff --git a/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch
new file mode 100644
index 000000000..745cc8d09
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch
@@ -0,0 +1,35 @@
+From: Stefan Wahren <stefan.wahren@i2se.com>
+Date: Fri, 28 Dec 2018 23:09:27 +0100
+Subject: arm64: dts: broadcom: Add reference to RPi 3 A+
+Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=441d8020d8fc8654698f5518cdf76832f84101f4
+
+This adds a reference to the dts of the Raspberry Pi 3 A+,
+so we don't need to maintain the content in arm64.
+
+Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
+Reviewed-by: Eric Anholt <eric@anholt.net>
+---
+ arch/arm64/boot/dts/broadcom/Makefile | 3 ++-
+ arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts | 2 ++
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+ create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts
+
+Index: debian-kernel/arch/arm64/boot/dts/broadcom/Makefile
+===================================================================
+--- debian-kernel.orig/arch/arm64/boot/dts/broadcom/Makefile
++++ debian-kernel/arch/arm64/boot/dts/broadcom/Makefile
+@@ -1,5 +1,6 @@
+ # SPDX-License-Identifier: GPL-2.0
+-dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \
++dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-a-plus.dtb \
++ bcm2837-rpi-3-b.dtb \
+ bcm2837-rpi-3-b-plus.dtb \
+ bcm2837-rpi-cm3-io3.dtb
+
+Index: debian-kernel/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts
+===================================================================
+--- /dev/null
++++ debian-kernel/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts
+@@ -0,0 +1,2 @@
++// SPDX-License-Identifier: GPL-2.0
++#include "arm/bcm2837-rpi-3-a-plus.dts"
diff --git a/debian/patches/features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch b/debian/patches/features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch
new file mode 100644
index 000000000..d2c9849bb
--- /dev/null
+++ b/debian/patches/features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch
@@ -0,0 +1,32 @@
+From: Liviu Dudau <liviu@dudau.co.uk>
+Date: Mon, 24 Sep 2018 11:22:28 +0100
+Subject: arm64: dts: broadcom: Use the .dtb name in the rule, rather than .dts
+Origin: https://git.kernel.org/linus/74cf77e8be35795b4cc57b7010bc348295e421b9
+
+Commit a7eb26392b893 ("arm64: dts: broadcom: Add reference to Compute
+Module IO Board V3") adds the bcm2837-rpi-cm3-io3.dts file as a target
+in the Makefile, rather than the .dtb name. This will skip the
+generation of the .dtb file at compile time and will fail the dtbs_install
+target.
+
+Fixes: a7eb26392b893 ("arm64: dts: broadcom: Add reference to Compute Module IO Board V3")
+Signed-off-by: Liviu Dudau <liviu@dudau.co.uk>
+Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
+Signed-off-by: Olof Johansson <olof@lixom.net>
+---
+ arch/arm64/boot/dts/broadcom/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: linux/arch/arm64/boot/dts/broadcom/Makefile
+===================================================================
+--- linux.orig/arch/arm64/boot/dts/broadcom/Makefile
++++ linux/arch/arm64/boot/dts/broadcom/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \
+ bcm2837-rpi-3-b-plus.dtb \
+- bcm2837-rpi-cm3-io3.dts
++ bcm2837-rpi-cm3-io3.dtb
+
+ subdir-y += northstar2
+ subdir-y += stingray
diff --git a/debian/patches/features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch b/debian/patches/features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch
new file mode 100644
index 000000000..73f420b6c
--- /dev/null
+++ b/debian/patches/features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch
@@ -0,0 +1,65 @@
+From: Aurelien Jarno <aurelien@aurel32.net>
+Date: Sun, 20 Jul 2014 19:16:31 +0200
+Subject: MIPS: Loongson 3: Add Loongson LS3A RS780E 1-way machine definition
+Forwarded: no
+
+Add a Loongson LS3A RS780E 1-way machine definition, which only differs
+from other Loongson 3 based machines by the UART base clock speed.
+
+Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
+[bwh: Forward-ported to 4.2]
+---
+ arch/mips/include/asm/bootinfo.h | 1 +
+ arch/mips/loongson64/common/machtype.c | 1 +
+ arch/mips/loongson64/common/serial.c | 1 +
+ arch/mips/loongson64/common/uart_base.c | 1 +
+ 4 files changed, 4 insertions(+)
+
+Index: linux/arch/mips/include/asm/bootinfo.h
+===================================================================
+--- linux.orig/arch/mips/include/asm/bootinfo.h
++++ linux/arch/mips/include/asm/bootinfo.h
+@@ -71,6 +71,7 @@ enum loongson_machine_type {
+ MACH_LEMOTE_NAS,
+ MACH_LEMOTE_LL2F,
+ MACH_LOONGSON_GENERIC,
++ MACH_LOONGSON_3A780E1W,
+ MACH_LOONGSON_END
+ };
+
+Index: linux/arch/mips/loongson64/common/machtype.c
+===================================================================
+--- linux.orig/arch/mips/loongson64/common/machtype.c
++++ linux/arch/mips/loongson64/common/machtype.c
+@@ -28,6 +28,7 @@ static const char *system_types[] = {
+ [MACH_LEMOTE_NAS] = "lemote-nas-2f",
+ [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f",
+ [MACH_LOONGSON_GENERIC] = "generic-loongson-machine",
++ [MACH_LOONGSON_3A780E1W] = "loongson-ls3a-rs780e-1w",
+ [MACH_LOONGSON_END] = NULL,
+ };
+
+Index: linux/arch/mips/loongson64/common/serial.c
+===================================================================
+--- linux.orig/arch/mips/loongson64/common/serial.c
++++ linux/arch/mips/loongson64/common/serial.c
+@@ -48,6 +48,7 @@ static struct plat_serial8250_port uart8
+ [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} },
+ [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} },
+ [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} },
++ [MACH_LOONGSON_3A780E1W] = {PORT_M(2, 33177600), {} },
+ [MACH_LOONGSON_END] = {},
+ };
+
+Index: linux/arch/mips/loongson64/common/uart_base.c
+===================================================================
+--- linux.orig/arch/mips/loongson64/common/uart_base.c
++++ linux/arch/mips/loongson64/common/uart_base.c
+@@ -25,6 +25,7 @@ void prom_init_loongson_uart_base(void)
+ {
+ switch (mips_machtype) {
+ case MACH_LOONGSON_GENERIC:
++ case MACH_LOONGSON_3A780E1W:
+ /* The CPU provided serial port (CPU) */
+ loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0;
+ break;
diff --git a/debian/patches/features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch b/debian/patches/features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch
new file mode 100644
index 000000000..3de14026f
--- /dev/null
+++ b/debian/patches/features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch
@@ -0,0 +1,29 @@
+From: Aurelien Jarno <aurelien@aurel32.net>
+Subject: MIPS: increase MAX_PHYSMEM_BITS on Loongson 3 only
+Bug-Debian: https://bugs.debian.org/764223
+Forwarded: no
+
+Commit c4617318 broke Loongson-2 support and maybe even more by increasing
+the value of MAX_PHYSMEM_BITS. At it is currently only needed on
+Loongson-3, define it conditionally.
+
+Note: this should be replace by upstream fix when available.
+
+Index: linux/arch/mips/include/asm/sparsemem.h
+===================================================================
+--- linux.orig/arch/mips/include/asm/sparsemem.h
++++ linux/arch/mips/include/asm/sparsemem.h
+@@ -12,7 +12,12 @@
+ #else
+ # define SECTION_SIZE_BITS 28
+ #endif
+-#define MAX_PHYSMEM_BITS 48
++
++#if defined(CONFIG_CPU_LOONGSON3)
++# define MAX_PHYSMEM_BITS 48
++#else
++# define MAX_PHYSMEM_BITS 35
++#endif
+
+ #endif /* CONFIG_SPARSEMEM */
+ #endif /* _MIPS_SPARSEMEM_H */
diff --git a/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch
new file mode 100644
index 000000000..d56f9f289
--- /dev/null
+++ b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch
@@ -0,0 +1,101 @@
+From: Juergen Gross <jgross@suse.com>
+Date: Wed, 10 Oct 2018 08:14:56 +0200
+Subject: x86/acpi, x86/boot: Take RSDP address for boot params if available
+Origin: https://git.kernel.org/linus/e7b66d16fe41722350ba87f5788052ef53ee28bb
+
+In case the RSDP address in struct boot_params is specified don't try
+to find the table by searching, but take the address directly as set
+by the boot loader.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: Baoquan He <bhe@redhat.com>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Jia Zhang <qianyue.zj@alibaba-inc.com>
+Cc: Len Brown <len.brown@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Pavel Machek <pavel@ucw.cz>
+Cc: Pavel Tatashin <pasha.tatashin@oracle.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: boris.ostrovsky@oracle.com
+Cc: linux-kernel@vger.kernel.org
+Cc: linux-pm@vger.kernel.org
+Cc: xen-devel@lists.xenproject.org
+Link: http://lkml.kernel.org/r/20181010061456.22238-4-jgross@suse.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+---
+ arch/x86/include/asm/acpi.h | 7 +++++++
+ arch/x86/kernel/acpi/boot.c | 6 ++++++
+ arch/x86/kernel/x86_init.c | 3 +--
+ 3 files changed, 14 insertions(+), 2 deletions(-)
+
+Index: linux/arch/x86/include/asm/acpi.h
+===================================================================
+--- linux.orig/arch/x86/include/asm/acpi.h
++++ linux/arch/x86/include/asm/acpi.h
+@@ -142,6 +142,8 @@ static inline u64 acpi_arch_get_root_poi
+
+ void acpi_generic_reduced_hw_init(void);
+
++u64 x86_default_get_root_pointer(void);
++
+ #else /* !CONFIG_ACPI */
+
+ #define acpi_lapic 0
+@@ -153,6 +155,11 @@ static inline void disable_acpi(void) {
+
+ static inline void acpi_generic_reduced_hw_init(void) { }
+
++static inline u64 x86_default_get_root_pointer(void)
++{
++ return 0;
++}
++
+ #endif /* !CONFIG_ACPI */
+
+ #define ARCH_HAS_POWER_INIT 1
+Index: linux/arch/x86/kernel/acpi/boot.c
+===================================================================
+--- linux.orig/arch/x86/kernel/acpi/boot.c
++++ linux/arch/x86/kernel/acpi/boot.c
+@@ -48,6 +48,7 @@
+ #include <asm/mpspec.h>
+ #include <asm/smp.h>
+ #include <asm/i8259.h>
++#include <asm/setup.h>
+
+ #include "sleep.h" /* To include x86_acpi_suspend_lowlevel */
+ static int __initdata acpi_force = 0;
+@@ -1771,3 +1772,8 @@ void __init arch_reserve_mem_area(acpi_p
+ e820__range_add(addr, size, E820_TYPE_ACPI);
+ e820__update_table_print();
+ }
++
++u64 x86_default_get_root_pointer(void)
++{
++ return boot_params.hdr.acpi_rsdp_addr;
++}
+Index: linux/arch/x86/kernel/x86_init.c
+===================================================================
+--- linux.orig/arch/x86/kernel/x86_init.c
++++ linux/arch/x86/kernel/x86_init.c
+@@ -31,7 +31,6 @@ static int __init iommu_init_noop(void)
+ static void iommu_shutdown_noop(void) { }
+ static bool __init bool_x86_init_noop(void) { return false; }
+ static void x86_op_int_noop(int cpu) { }
+-static u64 u64_x86_init_noop(void) { return 0; }
+
+ /*
+ * The platform setup functions are preset with the default functions
+@@ -96,7 +95,7 @@ struct x86_init_ops x86_init __initdata
+ },
+
+ .acpi = {
+- .get_root_pointer = u64_x86_init_noop,
++ .get_root_pointer = x86_default_get_root_pointer,
+ .reduced_hw_early_init = acpi_generic_reduced_hw_init,
+ },
+ };
diff --git a/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch
new file mode 100644
index 000000000..5382acce3
--- /dev/null
+++ b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch
@@ -0,0 +1,51 @@
+From: Juergen Gross <jgross@suse.com>
+Date: Tue, 20 Nov 2018 08:25:29 +0100
+Subject: x86/acpi, x86/boot: Take RSDP address from boot params if available
+Origin: https://git.kernel.org/linus/e6e094e053af75cbc164e950814d3d084fb1e698
+
+In case the RSDP address in struct boot_params is specified don't try
+to find the table by searching, but take the address directly as set
+by the boot loader.
+
+Suggested-by: "H. Peter Anvin" <hpa@zytor.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: boris.ostrovsky@oracle.com
+Cc: bp@alien8.de
+Cc: daniel.kiper@oracle.com
+Cc: sstabellini@kernel.org
+Cc: xen-devel@lists.xenproject.org
+Link: http://lkml.kernel.org/r/20181120072529.5489-3-jgross@suse.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+---
+ arch/x86/include/uapi/asm/bootparam.h | 3 ++-
+ arch/x86/kernel/acpi/boot.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+Index: linux/arch/x86/include/uapi/asm/bootparam.h
+===================================================================
+--- linux.orig/arch/x86/include/uapi/asm/bootparam.h
++++ linux/arch/x86/include/uapi/asm/bootparam.h
+@@ -155,7 +155,8 @@ struct boot_params {
+ __u8 _pad2[4]; /* 0x054 */
+ __u64 tboot_addr; /* 0x058 */
+ struct ist_info ist_info; /* 0x060 */
+- __u8 _pad3[16]; /* 0x070 */
++ __u64 acpi_rsdp_addr; /* 0x070 */
++ __u8 _pad3[8]; /* 0x078 */
+ __u8 hd0_info[16]; /* obsolete! */ /* 0x080 */
+ __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */
+ struct sys_desc_table sys_desc_table; /* obsolete! */ /* 0x0a0 */
+Index: linux/arch/x86/kernel/acpi/boot.c
+===================================================================
+--- linux.orig/arch/x86/kernel/acpi/boot.c
++++ linux/arch/x86/kernel/acpi/boot.c
+@@ -1775,5 +1775,5 @@ void __init arch_reserve_mem_area(acpi_p
+
+ u64 x86_default_get_root_pointer(void)
+ {
+- return 0;
++ return boot_params.acpi_rsdp_addr;
+ }
diff --git a/debian/patches/features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch b/debian/patches/features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch
new file mode 100644
index 000000000..55b116db9
--- /dev/null
+++ b/debian/patches/features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch
@@ -0,0 +1,232 @@
+From: Juergen Gross <jgross@suse.com>
+Date: Wed, 10 Oct 2018 08:14:55 +0200
+Subject: x86/boot: Add ACPI RSDP address to setup_header
+Origin: https://git.kernel.org/linus/ae7e1238e68f2a472a125673ab506d49158c1889
+
+Xen PVH guests receive the address of the RSDP table from Xen. In order
+to support booting a Xen PVH guest via Grub2 using the standard x86
+boot entry we need a way for Grub2 to pass the RSDP address to the
+kernel.
+
+For this purpose expand the struct setup_header to hold the physical
+address of the RSDP address. Being zero means it isn't specified and
+has to be located the legacy way (searching through low memory or
+EBDA).
+
+While documenting the new setup_header layout and protocol version
+2.14 add the missing documentation of protocol version 2.13.
+
+There are Grub2 versions in several distros with a downstream patch
+violating the boot protocol by writing past the end of setup_header.
+This requires another update of the boot protocol to enable the kernel
+to distinguish between a specified RSDP address and one filled with
+garbage by such a broken Grub2.
+
+From protocol 2.14 on Grub2 will write the version it is supporting
+(but never a higher value than found to be supported by the kernel)
+ored with 0x8000 to the version field of setup_header. This enables
+the kernel to know up to which field Grub2 has written information
+to. All fields after that are supposed to be clobbered.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: boris.ostrovsky@oracle.com
+Cc: bp@alien8.de
+Cc: corbet@lwn.net
+Cc: linux-doc@vger.kernel.org
+Cc: xen-devel@lists.xenproject.org
+Link: http://lkml.kernel.org/r/20181010061456.22238-3-jgross@suse.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+---
+ Documentation/x86/boot.txt | 32 ++++++++++++++++++++++++++-
+ arch/x86/boot/header.S | 6 ++++-
+ arch/x86/include/asm/x86_init.h | 2 ++
+ arch/x86/include/uapi/asm/bootparam.h | 4 ++++
+ arch/x86/kernel/head32.c | 1 +
+ arch/x86/kernel/head64.c | 2 ++
+ arch/x86/kernel/setup.c | 17 ++++++++++++++
+ 7 files changed, 62 insertions(+), 2 deletions(-)
+
+Index: linux/Documentation/x86/boot.txt
+===================================================================
+--- linux.orig/Documentation/x86/boot.txt
++++ linux/Documentation/x86/boot.txt
+@@ -61,6 +61,18 @@ Protocol 2.12: (Kernel 3.8) Added the xl
+ to struct boot_params for loading bzImage and ramdisk
+ above 4G in 64bit.
+
++Protocol 2.13: (Kernel 3.14) Support 32- and 64-bit flags being set in
++ xloadflags to support booting a 64-bit kernel from 32-bit
++ EFI
++
++Protocol 2.14: (Kernel 4.20) Added acpi_rsdp_addr holding the physical
++ address of the ACPI RSDP table.
++ The bootloader updates version with:
++ 0x8000 | min(kernel-version, bootloader-version)
++ kernel-version being the protocol version supported by
++ the kernel and bootloader-version the protocol version
++ supported by the bootloader.
++
+ **** MEMORY LAYOUT
+
+ The traditional memory map for the kernel loader, used for Image or
+@@ -197,6 +209,7 @@ Offset Proto Name Meaning
+ 0258/8 2.10+ pref_address Preferred loading address
+ 0260/4 2.10+ init_size Linear memory required during initialization
+ 0264/4 2.11+ handover_offset Offset of handover entry point
++0268/8 2.14+ acpi_rsdp_addr Physical address of RSDP table
+
+ (1) For backwards compatibility, if the setup_sects field contains 0, the
+ real value is 4.
+@@ -309,7 +322,7 @@ Protocol: 2.00+
+ Contains the magic number "HdrS" (0x53726448).
+
+ Field name: version
+-Type: read
++Type: modify
+ Offset/size: 0x206/2
+ Protocol: 2.00+
+
+@@ -317,6 +330,12 @@ Protocol: 2.00+
+ e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
+ 10.17.
+
++ Up to protocol version 2.13 this information is only read by the
++ bootloader. From protocol version 2.14 onwards the bootloader will
++ write the used protocol version or-ed with 0x8000 to the field. The
++ used protocol version will be the minimum of the supported protocol
++ versions of the bootloader and the kernel.
++
+ Field name: realmode_swtch
+ Type: modify (optional)
+ Offset/size: 0x208/4
+@@ -744,6 +763,17 @@ Offset/size: 0x264/4
+
+ See EFI HANDOVER PROTOCOL below for more details.
+
++Field name: acpi_rsdp_addr
++Type: write
++Offset/size: 0x268/8
++Protocol: 2.14+
++
++ This field can be set by the boot loader to tell the kernel the
++ physical address of the ACPI RSDP table.
++
++ A value of 0 indicates the kernel should fall back to the standard
++ methods to locate the RSDP.
++
+
+ **** THE IMAGE CHECKSUM
+
+Index: linux/arch/x86/boot/header.S
+===================================================================
+--- linux.orig/arch/x86/boot/header.S
++++ linux/arch/x86/boot/header.S
+@@ -300,7 +300,7 @@ _start:
+ # Part 2 of the header, from the old setup.S
+
+ .ascii "HdrS" # header signature
+- .word 0x020d # header version number (>= 0x0105)
++ .word 0x020e # header version number (>= 0x0105)
+ # or else old loadlin-1.5 will fail)
+ .globl realmode_swtch
+ realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
+@@ -558,6 +558,10 @@ pref_address: .quad LOAD_PHYSICAL_ADDR
+ init_size: .long INIT_SIZE # kernel initialization size
+ handover_offset: .long 0 # Filled in by build.c
+
++acpi_rsdp_addr: .quad 0 # 64-bit physical pointer to the
++ # ACPI RSDP table, added with
++ # version 2.14
++
+ # End of setup header #####################################################
+
+ .section ".entrytext", "ax"
+Index: linux/arch/x86/include/asm/x86_init.h
+===================================================================
+--- linux.orig/arch/x86/include/asm/x86_init.h
++++ linux/arch/x86/include/asm/x86_init.h
+@@ -303,4 +303,6 @@ extern void x86_init_noop(void);
+ extern void x86_init_uint_noop(unsigned int unused);
+ extern bool x86_pnpbios_disabled(void);
+
++void x86_verify_bootdata_version(void);
++
+ #endif
+Index: linux/arch/x86/include/uapi/asm/bootparam.h
+===================================================================
+--- linux.orig/arch/x86/include/uapi/asm/bootparam.h
++++ linux/arch/x86/include/uapi/asm/bootparam.h
+@@ -16,6 +16,9 @@
+ #define RAMDISK_PROMPT_FLAG 0x8000
+ #define RAMDISK_LOAD_FLAG 0x4000
+
++/* version flags */
++#define VERSION_WRITTEN 0x8000
++
+ /* loadflags */
+ #define LOADED_HIGH (1<<0)
+ #define KASLR_FLAG (1<<1)
+@@ -86,6 +89,7 @@ struct setup_header {
+ __u64 pref_address;
+ __u32 init_size;
+ __u32 handover_offset;
++ __u64 acpi_rsdp_addr;
+ } __attribute__((packed));
+
+ struct sys_desc_table {
+Index: linux/arch/x86/kernel/head32.c
+===================================================================
+--- linux.orig/arch/x86/kernel/head32.c
++++ linux/arch/x86/kernel/head32.c
+@@ -37,6 +37,7 @@ asmlinkage __visible void __init i386_st
+ cr4_init_shadow();
+
+ sanitize_boot_params(&boot_params);
++ x86_verify_bootdata_version();
+
+ x86_early_init_platform_quirks();
+
+Index: linux/arch/x86/kernel/head64.c
+===================================================================
+--- linux.orig/arch/x86/kernel/head64.c
++++ linux/arch/x86/kernel/head64.c
+@@ -477,6 +477,8 @@ void __init x86_64_start_reservations(ch
+ if (!boot_params.hdr.version)
+ copy_bootdata(__va(real_mode_data));
+
++ x86_verify_bootdata_version();
++
+ x86_early_init_platform_quirks();
+
+ switch (boot_params.hdr.hardware_subarch) {
+Index: linux/arch/x86/kernel/setup.c
+===================================================================
+--- linux.orig/arch/x86/kernel/setup.c
++++ linux/arch/x86/kernel/setup.c
+@@ -1281,6 +1281,23 @@ void __init setup_arch(char **cmdline_p)
+ unwind_init();
+ }
+
++/*
++ * From boot protocol 2.14 onwards we expect the bootloader to set the
++ * version to "0x8000 | <used version>". In case we find a version >= 2.14
++ * without the 0x8000 we assume the boot loader supports 2.13 only and
++ * reset the version accordingly. The 0x8000 flag is removed in any case.
++ */
++void __init x86_verify_bootdata_version(void)
++{
++ if (boot_params.hdr.version & VERSION_WRITTEN)
++ boot_params.hdr.version &= ~VERSION_WRITTEN;
++ else if (boot_params.hdr.version >= 0x020e)
++ boot_params.hdr.version = 0x020d;
++
++ if (boot_params.hdr.version < 0x020e)
++ boot_params.hdr.acpi_rsdp_addr = 0;
++}
++
+ #ifdef CONFIG_X86_32
+
+ static struct resource video_ram_resource = {
diff --git a/debian/patches/features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch b/debian/patches/features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch
new file mode 100644
index 000000000..d2b67f4ea
--- /dev/null
+++ b/debian/patches/features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch
@@ -0,0 +1,236 @@
+From: Juergen Gross <jgross@suse.com>
+Date: Tue, 20 Nov 2018 08:25:28 +0100
+Subject: x86/boot: Mostly revert commit ae7e1238e68f2a ("Add ACPI RSDP address
+ to setup_header")
+Origin: https://git.kernel.org/linus/3841840449817ba6cf3e636008bc4e1061a03388
+
+Peter Anvin pointed out that commit:
+
+ ae7e1238e68f2a ("x86/boot: Add ACPI RSDP address to setup_header")
+
+should be reverted as setup_header should only contain items set by the
+legacy BIOS.
+
+So revert said commit. Instead of fully reverting the dependent commit
+of:
+
+ e7b66d16fe4172 ("x86/acpi, x86/boot: Take RSDP address for boot params if available")
+
+just remove the setup_header reference in order to replace it by
+a boot_params in a followup patch.
+
+Suggested-by: "H. Peter Anvin" <hpa@zytor.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: boris.ostrovsky@oracle.com
+Cc: bp@alien8.de
+Cc: daniel.kiper@oracle.com
+Cc: sstabellini@kernel.org
+Cc: xen-devel@lists.xenproject.org
+Link: http://lkml.kernel.org/r/20181120072529.5489-2-jgross@suse.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+---
+ Documentation/x86/boot.txt | 32 +--------------------------
+ arch/x86/boot/header.S | 6 +----
+ arch/x86/include/asm/x86_init.h | 2 --
+ arch/x86/include/uapi/asm/bootparam.h | 4 ----
+ arch/x86/kernel/acpi/boot.c | 2 +-
+ arch/x86/kernel/head32.c | 1 -
+ arch/x86/kernel/head64.c | 2 --
+ arch/x86/kernel/setup.c | 17 --------------
+ 8 files changed, 3 insertions(+), 63 deletions(-)
+
+Index: linux/Documentation/x86/boot.txt
+===================================================================
+--- linux.orig/Documentation/x86/boot.txt
++++ linux/Documentation/x86/boot.txt
+@@ -61,18 +61,6 @@ Protocol 2.12: (Kernel 3.8) Added the xl
+ to struct boot_params for loading bzImage and ramdisk
+ above 4G in 64bit.
+
+-Protocol 2.13: (Kernel 3.14) Support 32- and 64-bit flags being set in
+- xloadflags to support booting a 64-bit kernel from 32-bit
+- EFI
+-
+-Protocol 2.14: (Kernel 4.20) Added acpi_rsdp_addr holding the physical
+- address of the ACPI RSDP table.
+- The bootloader updates version with:
+- 0x8000 | min(kernel-version, bootloader-version)
+- kernel-version being the protocol version supported by
+- the kernel and bootloader-version the protocol version
+- supported by the bootloader.
+-
+ **** MEMORY LAYOUT
+
+ The traditional memory map for the kernel loader, used for Image or
+@@ -209,7 +197,6 @@ Offset Proto Name Meaning
+ 0258/8 2.10+ pref_address Preferred loading address
+ 0260/4 2.10+ init_size Linear memory required during initialization
+ 0264/4 2.11+ handover_offset Offset of handover entry point
+-0268/8 2.14+ acpi_rsdp_addr Physical address of RSDP table
+
+ (1) For backwards compatibility, if the setup_sects field contains 0, the
+ real value is 4.
+@@ -322,7 +309,7 @@ Protocol: 2.00+
+ Contains the magic number "HdrS" (0x53726448).
+
+ Field name: version
+-Type: modify
++Type: read
+ Offset/size: 0x206/2
+ Protocol: 2.00+
+
+@@ -330,12 +317,6 @@ Protocol: 2.00+
+ e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
+ 10.17.
+
+- Up to protocol version 2.13 this information is only read by the
+- bootloader. From protocol version 2.14 onwards the bootloader will
+- write the used protocol version or-ed with 0x8000 to the field. The
+- used protocol version will be the minimum of the supported protocol
+- versions of the bootloader and the kernel.
+-
+ Field name: realmode_swtch
+ Type: modify (optional)
+ Offset/size: 0x208/4
+@@ -763,17 +744,6 @@ Offset/size: 0x264/4
+
+ See EFI HANDOVER PROTOCOL below for more details.
+
+-Field name: acpi_rsdp_addr
+-Type: write
+-Offset/size: 0x268/8
+-Protocol: 2.14+
+-
+- This field can be set by the boot loader to tell the kernel the
+- physical address of the ACPI RSDP table.
+-
+- A value of 0 indicates the kernel should fall back to the standard
+- methods to locate the RSDP.
+-
+
+ **** THE IMAGE CHECKSUM
+
+Index: linux/arch/x86/boot/header.S
+===================================================================
+--- linux.orig/arch/x86/boot/header.S
++++ linux/arch/x86/boot/header.S
+@@ -300,7 +300,7 @@ _start:
+ # Part 2 of the header, from the old setup.S
+
+ .ascii "HdrS" # header signature
+- .word 0x020e # header version number (>= 0x0105)
++ .word 0x020d # header version number (>= 0x0105)
+ # or else old loadlin-1.5 will fail)
+ .globl realmode_swtch
+ realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
+@@ -558,10 +558,6 @@ pref_address: .quad LOAD_PHYSICAL_ADDR
+ init_size: .long INIT_SIZE # kernel initialization size
+ handover_offset: .long 0 # Filled in by build.c
+
+-acpi_rsdp_addr: .quad 0 # 64-bit physical pointer to the
+- # ACPI RSDP table, added with
+- # version 2.14
+-
+ # End of setup header #####################################################
+
+ .section ".entrytext", "ax"
+Index: linux/arch/x86/include/asm/x86_init.h
+===================================================================
+--- linux.orig/arch/x86/include/asm/x86_init.h
++++ linux/arch/x86/include/asm/x86_init.h
+@@ -303,6 +303,4 @@ extern void x86_init_noop(void);
+ extern void x86_init_uint_noop(unsigned int unused);
+ extern bool x86_pnpbios_disabled(void);
+
+-void x86_verify_bootdata_version(void);
+-
+ #endif
+Index: linux/arch/x86/include/uapi/asm/bootparam.h
+===================================================================
+--- linux.orig/arch/x86/include/uapi/asm/bootparam.h
++++ linux/arch/x86/include/uapi/asm/bootparam.h
+@@ -16,9 +16,6 @@
+ #define RAMDISK_PROMPT_FLAG 0x8000
+ #define RAMDISK_LOAD_FLAG 0x4000
+
+-/* version flags */
+-#define VERSION_WRITTEN 0x8000
+-
+ /* loadflags */
+ #define LOADED_HIGH (1<<0)
+ #define KASLR_FLAG (1<<1)
+@@ -89,7 +86,6 @@ struct setup_header {
+ __u64 pref_address;
+ __u32 init_size;
+ __u32 handover_offset;
+- __u64 acpi_rsdp_addr;
+ } __attribute__((packed));
+
+ struct sys_desc_table {
+Index: linux/arch/x86/kernel/acpi/boot.c
+===================================================================
+--- linux.orig/arch/x86/kernel/acpi/boot.c
++++ linux/arch/x86/kernel/acpi/boot.c
+@@ -1775,5 +1775,5 @@ void __init arch_reserve_mem_area(acpi_p
+
+ u64 x86_default_get_root_pointer(void)
+ {
+- return boot_params.hdr.acpi_rsdp_addr;
++ return 0;
+ }
+Index: linux/arch/x86/kernel/head32.c
+===================================================================
+--- linux.orig/arch/x86/kernel/head32.c
++++ linux/arch/x86/kernel/head32.c
+@@ -37,7 +37,6 @@ asmlinkage __visible void __init i386_st
+ cr4_init_shadow();
+
+ sanitize_boot_params(&boot_params);
+- x86_verify_bootdata_version();
+
+ x86_early_init_platform_quirks();
+
+Index: linux/arch/x86/kernel/head64.c
+===================================================================
+--- linux.orig/arch/x86/kernel/head64.c
++++ linux/arch/x86/kernel/head64.c
+@@ -477,8 +477,6 @@ void __init x86_64_start_reservations(ch
+ if (!boot_params.hdr.version)
+ copy_bootdata(__va(real_mode_data));
+
+- x86_verify_bootdata_version();
+-
+ x86_early_init_platform_quirks();
+
+ switch (boot_params.hdr.hardware_subarch) {
+Index: linux/arch/x86/kernel/setup.c
+===================================================================
+--- linux.orig/arch/x86/kernel/setup.c
++++ linux/arch/x86/kernel/setup.c
+@@ -1281,23 +1281,6 @@ void __init setup_arch(char **cmdline_p)
+ unwind_init();
+ }
+
+-/*
+- * From boot protocol 2.14 onwards we expect the bootloader to set the
+- * version to "0x8000 | <used version>". In case we find a version >= 2.14
+- * without the 0x8000 we assume the boot loader supports 2.13 only and
+- * reset the version accordingly. The 0x8000 flag is removed in any case.
+- */
+-void __init x86_verify_bootdata_version(void)
+-{
+- if (boot_params.hdr.version & VERSION_WRITTEN)
+- boot_params.hdr.version &= ~VERSION_WRITTEN;
+- else if (boot_params.hdr.version >= 0x020e)
+- boot_params.hdr.version = 0x020d;
+-
+- if (boot_params.hdr.version < 0x020e)
+- boot_params.hdr.acpi_rsdp_addr = 0;
+-}
+-
+ #ifdef CONFIG_X86_32
+
+ static struct resource video_ram_resource = {
diff --git a/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch b/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch
new file mode 100644
index 000000000..3dde15cce
--- /dev/null
+++ b/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch
@@ -0,0 +1,227 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 12 Feb 2018 23:59:26 +0000
+Subject: x86: Make x32 syscall support conditional on a kernel parameter
+Bug-Debian: https://bugs.debian.org/708070
+Forwarded: https://lore.kernel.org/lkml/1415245982.3398.53.camel@decadent.org.uk/T/#u
+
+Enabling x32 in the standard amd64 kernel would increase its attack
+surface while provide no benefit to the vast majority of its users.
+No-one seems interested in regularly checking for vulnerabilities
+specific to x32 (at least no-one with a white hat).
+
+Still, adding another flavour just to turn on x32 seems wasteful. And
+the only differences on syscall entry are a few instructions that mask
+out the x32 flag and compare the syscall number.
+
+Use a static key to control whether x32 syscalls are really enabled, a
+Kconfig parameter to set its default value and a kernel parameter
+"syscall.x32" to change it at boot time.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ Documentation/admin-guide/kernel-parameters.txt | 4 ++
+ arch/x86/Kconfig | 8 ++++
+ arch/x86/entry/common.c | 11 +++++-
+ arch/x86/entry/syscall_64.c | 41 ++++++++++++++++++++++++
+ arch/x86/include/asm/elf.h | 4 +-
+ arch/x86/include/asm/syscall.h | 13 +++++++
+ arch/x86/include/asm/unistd.h | 4 +-
+ 7 files changed, 80 insertions(+), 5 deletions(-)
+
+Index: linux/Documentation/admin-guide/kernel-parameters.txt
+===================================================================
+--- linux.orig/Documentation/admin-guide/kernel-parameters.txt
++++ linux/Documentation/admin-guide/kernel-parameters.txt
+@@ -4501,6 +4501,10 @@
+
+ switches= [HW,M68k]
+
++ syscall.x32= [KNL,x86_64] Enable/disable use of x32 syscalls on
++ an x86_64 kernel where CONFIG_X86_X32 is enabled.
++ Default depends on CONFIG_X86_X32_DISABLED.
++
+ sysfs.deprecated=0|1 [KNL]
+ Enable/disable old style sysfs layout for old udev
+ on older distributions. When this option is enabled
+Index: linux/arch/x86/Kconfig
+===================================================================
+--- linux.orig/arch/x86/Kconfig
++++ linux/arch/x86/Kconfig
+@@ -2884,6 +2884,14 @@ config COMPAT_32
+ select HAVE_UID16
+ select OLD_SIGSUSPEND3
+
++config X86_X32_DISABLED
++ bool "x32 ABI disabled by default"
++ depends on X86_X32
++ default n
++ help
++ Disable the x32 ABI unless explicitly enabled using the
++ kernel paramter "syscall.x32=y".
++
+ config COMPAT
+ def_bool y
+ depends on IA32_EMULATION || X86_X32
+Index: linux/arch/x86/entry/common.c
+===================================================================
+--- linux.orig/arch/x86/entry/common.c
++++ linux/arch/x86/entry/common.c
+@@ -287,12 +287,21 @@ __visible void do_syscall_64(unsigned lo
+ * table. The only functional difference is the x32 bit in
+ * regs->orig_ax, which changes the behavior of some syscalls.
+ */
+- nr &= __SYSCALL_MASK;
+- if (likely(nr < NR_syscalls)) {
++ if (x32_enabled) {
++ nr &= ~__X32_SYSCALL_BIT;
++ if (unlikely(nr >= NR_syscalls))
++ goto bad;
+ nr = array_index_nospec(nr, NR_syscalls);
++ goto good;
++ } else {
++ nr &= ~0U;
++ if (unlikely(nr >= NR_non_x32_syscalls))
++ goto bad;
++ nr = array_index_nospec(nr, NR_non_x32_syscalls);
++good:
+ regs->ax = sys_call_table[nr](regs);
+ }
+-
++bad:
+ syscall_return_slowpath(regs);
+ }
+ #endif
+Index: linux/arch/x86/entry/syscall_64.c
+===================================================================
+--- linux.orig/arch/x86/entry/syscall_64.c
++++ linux/arch/x86/entry/syscall_64.c
+@@ -4,6 +4,9 @@
+ #include <linux/linkage.h>
+ #include <linux/sys.h>
+ #include <linux/cache.h>
++#include <linux/moduleparam.h>
++#undef MODULE_PARAM_PREFIX
++#define MODULE_PARAM_PREFIX "syscall."
+ #include <asm/asm-offsets.h>
+ #include <asm/syscall.h>
+
+@@ -23,3 +26,50 @@ asmlinkage const sys_call_ptr_t sys_call
+ [0 ... __NR_syscall_max] = &sys_ni_syscall,
+ #include <asm/syscalls_64.h>
+ };
++
++#ifdef CONFIG_X86_X32_ABI
++
++/* Maybe enable x32 syscalls */
++
++#if defined(CONFIG_X86_X32_DISABLED)
++DEFINE_STATIC_KEY_FALSE(x32_enabled_skey);
++#else
++DEFINE_STATIC_KEY_TRUE(x32_enabled_skey);
++#endif
++
++static int __init x32_param_set(const char *val, const struct kernel_param *p)
++{
++ bool enabled;
++ int ret;
++
++ ret = kstrtobool(val, &enabled);
++ if (ret)
++ return ret;
++ if (IS_ENABLED(CONFIG_X86_X32_DISABLED)) {
++ if (enabled) {
++ static_key_enable(&x32_enabled_skey.key);
++ pr_info("Enabled x32 syscalls\n");
++ }
++ } else {
++ if (!enabled) {
++ static_key_disable(&x32_enabled_skey.key);
++ pr_info("Disabled x32 syscalls\n");
++ }
++ }
++ return 0;
++}
++
++static int x32_param_get(char *buffer, const struct kernel_param *p)
++{
++ return sprintf(buffer, "%c\n",
++ static_key_enabled(&x32_enabled_skey) ? 'Y' : 'N');
++}
++
++static const struct kernel_param_ops x32_param_ops = {
++ .set = x32_param_set,
++ .get = x32_param_get,
++};
++
++arch_param_cb(x32, &x32_param_ops, NULL, 0444);
++
++#endif
+Index: linux/arch/x86/include/asm/elf.h
+===================================================================
+--- linux.orig/arch/x86/include/asm/elf.h
++++ linux/arch/x86/include/asm/elf.h
+@@ -10,6 +10,7 @@
+ #include <asm/ptrace.h>
+ #include <asm/user.h>
+ #include <asm/auxvec.h>
++#include <asm/syscall.h>
+
+ typedef unsigned long elf_greg_t;
+
+@@ -163,7 +164,8 @@ do { \
+
+ #define compat_elf_check_arch(x) \
+ (elf_check_arch_ia32(x) || \
+- (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64))
++ (IS_ENABLED(CONFIG_X86_X32_ABI) && x32_enabled && \
++ (x)->e_machine == EM_X86_64))
+
+ #if __USER32_DS != __USER_DS
+ # error "The following code assumes __USER32_DS == __USER_DS"
+Index: linux/arch/x86/include/asm/syscall.h
+===================================================================
+--- linux.orig/arch/x86/include/asm/syscall.h
++++ linux/arch/x86/include/asm/syscall.h
+@@ -16,6 +16,7 @@
+ #include <uapi/linux/audit.h>
+ #include <linux/sched.h>
+ #include <linux/err.h>
++#include <linux/jump_label.h>
+ #include <asm/asm-offsets.h> /* For NR_syscalls */
+ #include <asm/thread_info.h> /* for TS_COMPAT */
+ #include <asm/unistd.h>
+@@ -39,6 +40,18 @@ extern const sys_call_ptr_t sys_call_tab
+ extern const sys_call_ptr_t ia32_sys_call_table[];
+ #endif
+
++#if defined(CONFIG_X86_X32_ABI)
++#if defined(CONFIG_X86_X32_DISABLED)
++DECLARE_STATIC_KEY_FALSE(x32_enabled_skey);
++#define x32_enabled static_branch_unlikely(&x32_enabled_skey)
++#else
++DECLARE_STATIC_KEY_TRUE(x32_enabled_skey);
++#define x32_enabled static_branch_likely(&x32_enabled_skey)
++#endif
++#else
++#define x32_enabled 0
++#endif
++
+ /*
+ * Only the low 32 bits of orig_ax are meaningful, so we return int.
+ * This importantly ignores the high bits on 64-bit, so comparisons
+Index: linux/arch/x86/include/asm/unistd.h
+===================================================================
+--- linux.orig/arch/x86/include/asm/unistd.h
++++ linux/arch/x86/include/asm/unistd.h
+@@ -6,9 +6,9 @@
+
+
+ # ifdef CONFIG_X86_X32_ABI
+-# define __SYSCALL_MASK (~(__X32_SYSCALL_BIT))
++# define NR_non_x32_syscalls 512
+ # else
+-# define __SYSCALL_MASK (~0)
++# define NR_non_x32_syscalls NR_syscalls
+ # endif
+
+ # ifdef CONFIG_X86_32
diff --git a/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch b/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch
new file mode 100644
index 000000000..87b90de80
--- /dev/null
+++ b/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch
@@ -0,0 +1,30 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Mon, 5 Dec 2011 04:00:58 +0000
+Subject: x86: memtest: WARN if bad RAM found
+Bug-Debian: https://bugs.debian.org/613321
+Forwarded: http://thread.gmane.org/gmane.linux.kernel/1286471
+
+Since this is not a particularly thorough test, if we find any bad
+bits of RAM then there is a fair chance that there are other bad bits
+we fail to detect.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+---
+ mm/memtest.c | 2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+Index: linux/mm/memtest.c
+===================================================================
+--- linux.orig/mm/memtest.c
++++ linux/mm/memtest.c
+@@ -27,6 +27,10 @@ static u64 patterns[] __initdata = {
+
+ static void __init reserve_bad_mem(u64 pattern, phys_addr_t start_bad, phys_addr_t end_bad)
+ {
++#ifdef CONFIG_X86
++ WARN_ONCE(1, "Bad RAM detected. Use memtest86+ to perform a thorough test\n"
++ "and the memmap= parameter to reserve the bad areas.");
++#endif
+ pr_info(" %016llx bad mem addr %pa - %pa reserved\n",
+ cpu_to_be64(pattern), &start_bad, &end_bad);
+ memblock_reserve(start_bad, end_bad - start_bad);
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 000000000..9563bf8b8
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,315 @@
+# Disable features broken by exclusion of upstream files
+debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch
+debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch
+debian/dfsg/vs6624-disable.patch
+debian/dfsg/drivers-net-appletalk-cops.patch
+debian/dfsg/video-remove-nvidiafb-and-rivafb.patch
+
+# Changes to support package build system
+debian/version.patch
+debian/uname-version-timestamp.patch
+debian/kernelvariables.patch
+debian/gitignore.patch
+debian/ia64-hardcode-arch-script-output.patch
+debian/mips-disable-werror.patch
+debian/mips-boston-disable-its.patch
+debian/arch-sh4-fix-uimage-build.patch
+debian/powerpcspe-omit-uimage.patch
+debian/tools-perf-version.patch
+debian/tools-perf-install.patch
+debian/wireless-add-debian-wireless-regdb-certificates.patch
+debian/export-symbols-needed-by-android-drivers.patch
+debian/android-enable-building-ashmem-and-binder-as-modules.patch
+
+# Fixes/improvements to firmware loading
+features/all/drivers-media-dvb-usb-af9005-request_firmware.patch
+debian/iwlwifi-do-not-request-unreleased-firmware.patch
+bugfix/all/firmware_class-log-every-success-and-failure.patch
+bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch
+bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch
+debian/firmware_class-refer-to-debian-wiki-firmware-page.patch
+
+# Patches from aufs4 repository, imported with debian/bin/genpatch-aufs.
+# These are only the changes needed to allow aufs to be built out-of-tree.
+features/all/aufs4/aufs4-base.patch
+features/all/aufs4/aufs4-mmap.patch
+features/all/aufs4/aufs4-standalone.patch
+
+# Change some defaults for security reasons
+debian/af_802154-Disable-auto-loading-as-mitigation-against.patch
+debian/rds-Disable-auto-loading-as-mitigation-against-local.patch
+debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch
+debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch
+debian/fs-enable-link-security-restrictions-by-default.patch
+
+# Set various features runtime-disabled by default
+debian/sched-autogroup-disabled.patch
+debian/yama-disable-by-default.patch
+debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch
+features/all/security-perf-allow-further-restriction-of-perf_event_open.patch
+
+# Disable autoloading/probing of various drivers by default
+debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch
+debian/snd-pcsp-disable-autoload.patch
+bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch
+debian/fjes-disable-autoload.patch
+
+# Taint if dangerous features are used
+debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch
+debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch
+
+# Arch bug fixes
+bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch
+bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch
+bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch
+bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch
+bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch
+bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch
+bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch
+bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch
+bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch
+bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch
+bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch
+bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch
+bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch
+bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch
+bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch
+bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch
+bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch
+bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch
+bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch
+
+# Arch features
+features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch
+features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch
+features/x86/x86-memtest-WARN-if-bad-RAM-found.patch
+features/x86/x86-make-x32-syscall-support-conditional.patch
+features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch
+features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch
+features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch
+features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch
+features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch
+
+# Miscellaneous bug fixes
+bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch
+bugfix/all/disable-some-marvell-phys.patch
+bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch
+bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch
+debian/revert-objtool-fix-config_stack_validation-y-warning.patch
+bugfix/all/mt76-use-the-correct-hweight8-function.patch
+bugfix/all/rtc-s35390a-set-uie_unsupported.patch
+bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch
+bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch
+bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch
+bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch
+bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch
+bugfix/all/usb-dont-create-dma-pools-for-HCD.patch
+bugfix/all/usb-add-a-hcd_uses_dma-helper.patch
+bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch
+bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch
+bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch
+
+# Miscellaneous features
+features/all/e1000e-Add-support-for-Comet-Lake.patch
+
+# Lockdown (formerly 'securelevel') patchset
+features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch
+features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch
+features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch
+features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch
+features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch
+features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch
+features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch
+features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch
+features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch
+features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch
+features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch
+features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch
+features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch
+features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch
+features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch
+features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch
+features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch
+features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch
+features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch
+features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch
+features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch
+features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch
+features/all/lockdown/0025-Lock-down-proc-kcore.patch
+features/all/lockdown/0026-Lock-down-kprobes.patch
+features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch
+features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch
+features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch
+features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch
+# some missing pieces
+features/all/lockdown/enable-cold-boot-attack-mitigation.patch
+features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch
+features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch
+features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch
+# until the "kernel_lockdown.7" manual page exists
+features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch
+
+# load db and MOK keys into secondary keyring for kernel modules verification
+features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch
+features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch
+features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch
+features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch
+features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch
+features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch
+features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch
+features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch
+features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch
+features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch
+features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch
+features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch
+
+# Fix exported symbol versions
+bugfix/all/module-disable-matching-missing-version-crc.patch
+
+# Tools bug fixes
+bugfix/all/usbip-document-tcp-wrappers.patch
+bugfix/all/kbuild-fix-recordmcount-dependency.patch
+bugfix/all/tools-perf-man-date.patch
+bugfix/all/tools-perf-remove-shebangs.patch
+bugfix/all/tools-lib-traceevent-use-ldflags.patch
+bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch
+bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch
+bugfix/all/cpupower-bump-soname-version.patch
+bugfix/all/libcpupower-hide-private-function.patch
+bugfix/all/cpupower-fix-checks-for-cpu-existence.patch
+bugfix/all/usbip-fix-misuse-of-strncpy.patch
+bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch
+bugfix/all/libbpf-add-soname-to-shared-object.patch
+bugfix/all/libbpf-link-shared-object-with-libelf.patch
+bugfix/all/libbpf-generate-pkg-config.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch
+bugfix/all/perf-script-python-Remove-mixed-indentation.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch
+bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch
+bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch
+
+# wireless: Disable regulatory.db direct loading (until we sort out signing)
+debian/wireless-disable-regulatory.db-direct-loading.patch
+
+# Licence clarification
+bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch
+
+# overlay: allow mounting in user namespaces
+debian/overlayfs-permit-mounts-in-userns.patch
+
+# Amazon ENA ethernet driver backport from Linux 4.20
+features/all/ena/0001-net-ethernet-remove-redundant-include.patch
+features/all/ena/0002-net-ena-minor-performance-improvement.patch
+features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch
+features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch
+features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch
+features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch
+features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch
+features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch
+features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch
+features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch
+features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch
+features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch
+features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch
+features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch
+features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch
+features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch
+features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch
+
+features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch
+features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch
+features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch
+features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch
+features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch
+features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch
+features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch
+features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch
+features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch
+features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch
+features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch
+features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch
+features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch
+features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch
+features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch
+features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch
+features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch
+features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch
+features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch
+features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch
+features/all/ena/net-ena-add-good-checksum-counter.patch
+features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch
+features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch
+features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch
+features/all/ena/net-ena-reimplement-set-get_coalesce.patch
+features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch
+features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch
+features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch
+features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch
+features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch
+features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch
+features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch
+features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch
+
+# Backported bugfixes from 4.20/4.21 for the Huawei TaiShan server platform (aka D06)
+bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch
+bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch
+bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch
+bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch
+bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch
+bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch
+bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch
+bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch
+bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch
+bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch
+bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch
+bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch
+bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch
+bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch
+bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch
+bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch
+bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch
+bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch
+bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch
+bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch
+bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch
+bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch
+bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch
+bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch
+bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch
+bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch
+bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch
+
+# Backported DTB support for Raspberry Pi Compute Module 3 from 4.20-rc1:
+features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch
+features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch
+features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch
+
+# Backported devicetree support for Raspberry Pi 3 1+ from 5.1
+features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch
+features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch
+features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch
+features/arm/staging-vc04_services-Use-correct-cache-line-size.patch
+
+# Preserve PCI bridge boot configuration if requested by firmware
+bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch
+bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch
+bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch
+bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch
+
+# Security fixes
+debian/i386-686-pae-pci-set-pci-nobios-by-default.patch
+debian/ntfs-mark-it-as-broken.patch
+
+# ABI maintenance