Home Home > GIT Browse > openSUSE-15.1
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Tesarik <ptesarik@suse.cz>2019-05-24 09:57:46 +0200
committerPetr Tesarik <ptesarik@suse.cz>2019-05-24 09:57:46 +0200
commitaf35fd11466ddb32ce5df4bc094d71af8b3b86aa (patch)
tree55e40d65b09b9548ea21729064a56987708bd081
parent0736b39ae22571739d83078e67700be3b670289b (diff)
parentb2dfaba9440a21681c7826eeaa842b173c718ce9 (diff)
Merge branch 'SLE15-SP1' into openSUSE-15.1openSUSE-15.1
- Update config/armv7hl/default - Update config/armv7hl/lpae Conflicts: config/ppc64le/debug config/x86_64/debug
-rw-r--r--blacklist.conf16
-rw-r--r--config/armv7hl/default1
-rw-r--r--config/armv7hl/lpae2
-rw-r--r--config/x86_64/default1
-rw-r--r--patches.arch/ARM-8824-1-fix-a-migrating-irq-bug-when-hotplug-cpu.patch158
-rw-r--r--patches.arch/ARM-8833-1-Ensure-that-NEON-code-always-compiles-wit.patch113
-rw-r--r--patches.arch/ARM-8839-1-kprobe-make-patch_lock-a-raw_spinlock_t.patch69
-rw-r--r--patches.arch/ARM-8840-1-use-a-raw_spinlock_t-in-unwind.patch94
-rw-r--r--patches.arch/ARM-OMAP2-Variable-reg-in-function-omap4_dsi_mux_pad.patch49
-rw-r--r--patches.arch/ARM-OMAP2-fix-lack-of-timer-interrupts-on-CPU1-after.patch81
-rw-r--r--patches.arch/ARM-avoid-Cortex-A9-livelock-on-tight-dmb-loops.patch194
-rw-r--r--patches.arch/ARM-imx6q-cpuidle-fix-bug-that-CPU-might-not-wake-up.patch80
-rw-r--r--patches.arch/ARM-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch46
-rw-r--r--patches.arch/ARM-s3c24xx-Fix-boolean-expressions-in-osiris_dvs_no.patch52
-rw-r--r--patches.arch/ARM-samsung-Limit-SAMSUNG_PM_CHECK-config-option-to-.patch60
-rw-r--r--patches.arch/acpi-add-hygon-dhyana-support.patch48
-rw-r--r--patches.arch/cpufreq-add-hygon-dhyana-support.patch91
-rw-r--r--patches.arch/cpufreq-amd-ignore-the-check-for-procfeedback-in-st-cz.patch52
-rw-r--r--patches.arch/edac-amd64-add-hygon-dhyana-support.patch92
-rw-r--r--patches.arch/perf-tools-add-hygon-dhyana-support.patch39
-rw-r--r--patches.arch/s390-qdio-clear-intparm-during-shutdown44
-rw-r--r--patches.arch/tools-cpupower-add-hygon-dhyana-support.patch115
-rw-r--r--patches.arch/x86-alternative-init-ideal_nops-for-hygon-dhyana.patch38
-rw-r--r--patches.arch/x86-amd_nb-add-support-for-newer-pci-topologies.patch19
-rw-r--r--patches.arch/x86-amd_nb-check-vendor-in-amd-only-functions.patch57
-rw-r--r--patches.arch/x86-apic-add-hygon-dhyana-support.patch62
-rw-r--r--patches.arch/x86-bugs-add-hygon-dhyana-to-the-respective-mitigation-machinery.patch60
-rw-r--r--patches.arch/x86-cpu-create-hygon-dhyana-architecture-support-file.patch503
-rw-r--r--patches.arch/x86-cpu-get-cache-info-and-setup-cache-cpumap-for-hygon-dhyana.patch141
-rw-r--r--patches.arch/x86-cpu-mtrr-support-top_mem2-and-get-mtrr-number.patch55
-rw-r--r--patches.arch/x86-events-add-hygon-dhyana-support-to-pmu-infrastructure.patch133
-rw-r--r--patches.arch/x86-kvm-add-hygon-dhyana-support-to-kvm.patch83
-rw-r--r--patches.arch/x86-mce-add-hygon-dhyana-support-to-the-mca-infrastructure.patch111
-rw-r--r--patches.arch/x86-mce-don-t-disable-mca-banks-when-offlining-a-cpu-on-amd.patch53
-rw-r--r--patches.arch/x86-pci-x86-amd_nb-add-hygon-dhyana-support-to-pci-and-northbridge.patch163
-rw-r--r--patches.arch/x86-smpboot-do-not-use-bsp-init-delay-and-mwait-to-idle-on-dhyana.patch47
-rw-r--r--patches.arch/x86-speculation-consolidate-cpu-whitelists.patch16
-rw-r--r--patches.arch/x86-speculation-mds-add-basic-bug-infrastructure-for-mds.patch21
-rw-r--r--patches.arch/x86-speculation-mds-add-bug_msbds_only.patch11
-rw-r--r--patches.arch/x86-xen-add-hygon-dhyana-support-to-xen.patch78
-rw-r--r--patches.drivers/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch110
-rw-r--r--patches.drivers/ALSA-hda-Use-a-macro-for-snd_array-iteration-loops.patch12
-rw-r--r--patches.drivers/ALSA-hda-realtek-Avoid-superfluous-COEF-EAPD-setups.patch143
-rw-r--r--patches.drivers/ALSA-hda-realtek-Corrected-fixup-for-System76-Gazell.patch43
-rw-r--r--patches.drivers/ALSA-hda-realtek-Fix-for-Lenovo-B50-70-inverted-inte.patch44
-rw-r--r--patches.drivers/ALSA-hda-realtek-Fixup-headphone-noise-via-runtime-s.patch113
-rw-r--r--patches.drivers/HID-input-add-mapping-for-Expose-Overview-key.patch39
-rw-r--r--patches.drivers/HID-input-add-mapping-for-Toggle-Display-key.patch41
-rw-r--r--patches.drivers/HID-input-add-mapping-for-keyboard-Brightness-Up-Dow.patch36
-rw-r--r--patches.drivers/Input-elan_i2c-add-hardware-ID-for-multiple-Lenovo-l.patch70
-rw-r--r--patches.drivers/Input-synaptics-rmi4-fix-possible-double-free.patch47
-rw-r--r--patches.drivers/ath10k-snoc-fix-unbalanced-clock-error-handling.patch39
-rw-r--r--patches.drivers/iio-adc-xilinx-fix-potential-use-after-free-on-remov.patch35
-rw-r--r--patches.drivers/iommu-arm-smmu-v3-Don-t-disable-SMMU-in-kdump-kernel.patch3
-rw-r--r--patches.drivers/ipmi-Prevent-use-after-free-in-deliver_response.patch74
-rw-r--r--patches.drivers/ipmi-fix-sleep-in-atomic-in-free_user-at-cleanup-SRC.patch100
-rw-r--r--patches.drivers/iw_cxgb4-only-allow-1-flush-on-user-qps.patch7
-rw-r--r--patches.drivers/leds-pwm-silently-error-out-on-EPROBE_DEFER.patch38
-rw-r--r--patches.drivers/mac8390-Fix-mmio-access-size-probe.patch74
-rw-r--r--patches.drivers/media-atmel-atmel-isc-fix-INIT_WORK-misplacement.patch46
-rw-r--r--patches.drivers/media-davinci-vpbe-array-underflow-in-vpbe_enum_outp.patch54
-rw-r--r--patches.drivers/media-omap_vout-potential-buffer-overflow-in-vidioc_.patch68
-rw-r--r--patches.drivers/power-supply-axp20x_usb_power-Fix-typo-in-VBUS-curre.patch66
-rw-r--r--patches.drivers/power-supply-axp288_charger-Fix-unchecked-return-val.patch46
-rw-r--r--patches.drivers/scsi-smartpqi-add-h3c-controller-ids47
-rw-r--r--patches.drivers/scsi-smartpqi-add-h3c-ssid40
-rw-r--r--patches.drivers/scsi-smartpqi-add-no_write_same-for-logical-volumes52
-rw-r--r--patches.drivers/scsi-smartpqi-add-ofa-support1144
-rw-r--r--patches.drivers/scsi-smartpqi-add-retries-for-device-reset75
-rw-r--r--patches.drivers/scsi-smartpqi-add-smp_utils-support690
-rw-r--r--patches.drivers/scsi-smartpqi-add-spdx140
-rw-r--r--patches.drivers/scsi-smartpqi-add-support-for-huawei-controllers56
-rw-r--r--patches.drivers/scsi-smartpqi-add-support-for-pqi-config-table-handshake418
-rw-r--r--patches.drivers/scsi-smartpqi-add-sysfs-attributes319
-rw-r--r--patches.drivers/scsi-smartpqi-allow-for-larger-raid-maps123
-rw-r--r--patches.drivers/scsi-smartpqi-bump-driver-version36
-rw-r--r--patches.drivers/scsi-smartpqi-bump-driver-version-171f188739
-rw-r--r--patches.drivers/scsi-smartpqi-call-pqi_free_interrupts-in-pqi_shutdown63
-rw-r--r--patches.drivers/scsi-smartpqi-check-for-null-device-pointers181
-rw-r--r--patches.drivers/scsi-smartpqi-correct-host-serial-num-for-ssa44
-rw-r--r--patches.drivers/scsi-smartpqi-correct-lun-reset-issues77
-rw-r--r--patches.drivers/scsi-smartpqi-correct-volume-status41
-rw-r--r--patches.drivers/scsi-smartpqi-do-not-offline-disks-for-transient-did-no-connect-conditions45
-rw-r--r--patches.drivers/scsi-smartpqi-enhance-numa-node-detection52
-rw-r--r--patches.drivers/scsi-smartpqi-fix-build-warnings48
-rw-r--r--patches.drivers/scsi-smartpqi-fix-disk-name-mount-point40
-rw-r--r--patches.drivers/scsi-smartpqi-fully-convert-to-the-generic-dma-api389
-rw-r--r--patches.drivers/scsi-smartpqi-increase-fw-status-register-read-timeout44
-rw-r--r--patches.drivers/scsi-smartpqi-increase-lun-reset-timeout68
-rw-r--r--patches.drivers/scsi-smartpqi-refactor-sending-controller-raid-requests237
-rw-r--r--patches.drivers/scsi-smartpqi-reporting-logical-unit-failure42
-rw-r--r--patches.drivers/scsi-smartpqi-turn-off-lun-data-caching-for-ptraid195
-rw-r--r--patches.drivers/scsi-smartpqi-update-copyright134
-rw-r--r--patches.drivers/scsi-smartpqi-update-driver-version38
-rw-r--r--patches.drivers/scsi-smartpqi-wake-up-drives-after-os-resumes-from-suspend37
-rw-r--r--patches.drivers/serial-fix-race-between-flush_to_ldisc-and-tty_open.patch4
-rw-r--r--patches.drivers/soc-fsl-qe-Fix-an-error-code-in-qe_pin_request.patch38
-rw-r--r--patches.drivers/spi-Micrel-eth-switch-declare-missing-of-table.patch65
-rw-r--r--patches.drivers/spi-ST-ST95HF-NFC-declare-missing-of-table.patch57
-rw-r--r--patches.drivers/thermal-cpu_cooling-Actually-trace-CPU-load-in-therm.patch58
-rw-r--r--patches.drm/drm-amd-display-If-one-stream-full-updates-full-upda.patch122
-rw-r--r--patches.drm/drm-amd-display-extending-AUX-SW-Timeout.patch71
-rw-r--r--patches.drm/drm-bridge-adv7511-Fix-low-refresh-rate-selection.patch51
-rw-r--r--patches.drm/drm-i915-Disable-LP3-watermarks-on-all-SNB-machines.patch (renamed from patches.drm/0004-drm-i915-Disable-LP3-watermarks-on-all-SNB-machines.patch)30
-rw-r--r--patches.drm/drm-i915-Downgrade-Gen9-Plane-WM-latency-error.patch (renamed from patches.drm/0001-drm-i915-Downgrade-Gen9-Plane-WM-latency-error.patch)9
-rw-r--r--patches.drm/drm-i915-Force-2-96-MHz-cdclk-on-glk-cnl-when-audio-.patch271
-rw-r--r--patches.drm/drm-i915-fbc-disable-framebuffer-compression-on-Gemi.patch55
-rw-r--r--patches.drm/drm-imx-don-t-skip-DP-channel-disable-for-background.patch34
-rw-r--r--patches.drm/drm-pl111-Initialize-clock-spinlock-early.patch67
-rw-r--r--patches.drm/drm-rockchip-fix-for-mailbox-read-validation.patch2
-rw-r--r--patches.drm/gpu-ipu-v3-dp-fix-CSC-handling.patch71
-rw-r--r--patches.fixes/0001-PCI-pciehp-Tolerate-Presence-Detect-hardwired-to-zer.patch200
-rw-r--r--patches.fixes/0001-netfilter-nf_log-fix-uninit-read-in-nf_log_proc_dost.patch37
-rw-r--r--patches.fixes/0001-netlink-fix-uninit-value-in-netlink_sendmsg.patch36
-rw-r--r--patches.fixes/0001-packet-fix-reserve-calculation.patch49
-rw-r--r--patches.fixes/0001-tools-lib-traceevent-Fix-missing-equality-check-for-.patch60
-rw-r--r--patches.fixes/0001-x86-speculation-mds-Fix-documentation-typo.patch34
-rw-r--r--patches.fixes/0002-net-fix-rtnh_ok.patch40
-rw-r--r--patches.fixes/0002-netfilter-nf_log-don-t-hold-nf_log_mutex-during-user.patch52
-rw-r--r--patches.fixes/0002-packet-reset-network-header-if-packet-shorter-than-l.patch37
-rw-r--r--patches.fixes/0003-l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_io.patch48
-rw-r--r--patches.fixes/0003-net-initialize-skb-peeked-when-cloning.patch35
-rw-r--r--patches.fixes/0003-xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch116
-rw-r--r--patches.fixes/0004-net-fix-uninit-value-in-__hw_addr_add_ex.patch57
-rw-r--r--patches.fixes/0004-rxrpc-Fix-transport-sockopts-to-get-IPv4-errors-on-a.patch82
-rw-r--r--patches.fixes/0004-xfrm-fix-missing-dst_release-after-policy-blocking-l.patch70
-rw-r--r--patches.fixes/0005-inetpeer-fix-uninit-value-in-inet_getpeer.patch119
-rw-r--r--patches.fixes/0005-net-socket-fix-potential-spectre-v1-gadget-in-socket.patch47
-rw-r--r--patches.fixes/0006-ipvs-fix-rtnl_lock-lockups-caused-by-start_sync_thre.patch641
-rw-r--r--patches.fixes/0006-packet-refine-ring-v3-block-size-test-to-hold-one-fr.patch68
-rw-r--r--patches.fixes/0007-net-ipv6-fix-addrconf_sysctl_addr_gen_mode.patch99
-rw-r--r--patches.fixes/0007-netfilter-nf_tables-can-t-fail-after-linking-rule-in.patch112
-rw-r--r--patches.fixes/0008-net-ipv6-don-t-reinitialize-ndev-cnf.addr_gen_mode-o.patch36
-rw-r--r--patches.fixes/0008-rxrpc-Fix-error-reception-on-AF_INET6-sockets.patch95
-rw-r--r--patches.fixes/0009-net-ipv6-reserve-room-for-IFLA_INET6_ADDR_GEN_MODE.patch38
-rw-r--r--patches.fixes/0009-packet-in-packet_snd-start-writing-at-link-layer-all.patch59
-rw-r--r--patches.fixes/0010-ipvs-fix-stats-update-from-local-clients.patch124
-rw-r--r--patches.fixes/0010-net-ipv6-propagate-net.ipv6.conf.all.addr_gen_mode-t.patch45
-rw-r--r--patches.fixes/0011-tcp-purge-write-queue-in-tcp_connect_init.patch90
-rw-r--r--patches.fixes/0011-xfrm-fix-passing-zero-to-ERR_PTR-warning.patch41
-rw-r--r--patches.fixes/0012-ip6_tunnel-collect_md-xmit-Use-ip_tunnel_key-s-provi.patch62
-rw-r--r--patches.fixes/0012-net-test-tailroom-before-appending-to-linear-skb.patch58
-rw-r--r--patches.fixes/0013-ipv6-fix-cleanup-ordering-for-ip6_mr-failure.patch65
-rw-r--r--patches.fixes/0013-net-Fix-a-bug-in-removing-queues-from-XPS-map.patch35
-rw-r--r--patches.fixes/0014-ipv6-fix-cleanup-ordering-for-pingv6-registration.patch58
-rw-r--r--patches.fixes/0014-netfilter-nf_tables-fix-NULL-pointer-dereference-on-.patch164
-rw-r--r--patches.fixes/0015-igmp-fix-incorrect-unsolicit-report-count-when-join-.patch39
-rw-r--r--patches.fixes/0015-netfilter-ebtables-handle-string-from-userspace-with.patch102
-rw-r--r--patches.fixes/0016-ipvs-fix-buffer-overflow-with-sync-daemon-and-servic.patch147
-rw-r--r--patches.fixes/0016-netfilter-nf_tables-release-chain-in-flushing-set.patch79
-rw-r--r--patches.fixes/0017-netfilter-bridge-Don-t-sabotage-nf_hook-calls-from-a.patch56
-rw-r--r--patches.fixes/0017-xfrm6-avoid-potential-infinite-loop-in-_decode_sessi.patch100
-rw-r--r--patches.fixes/0018-sctp-fix-identification-of-new-acks-for-SFR-CACC.patch120
-rw-r--r--patches.fixes/0018-xfrm-Validate-address-prefix-lengths-in-the-xfrm-sel.patch64
-rw-r--r--patches.fixes/0019-ip_tunnel-Fix-name-string-concatenate-in-__ip_tunnel.patch39
-rw-r--r--patches.fixes/0019-xfrm6-call-kfree_skb-when-skb-is-toobig.patch46
-rw-r--r--patches.fixes/0020-netfilter-nf_tables-check-msg_type-before-nft_trans_.patch145
-rw-r--r--patches.fixes/0020-xfrm-reset-transport-header-back-to-network-header-a.patch99
-rw-r--r--patches.fixes/0021-xfrm-reset-crypto_done-when-iterating-over-multiple-.patch37
-rw-r--r--patches.fixes/0022-ipvs-fix-check-on-xmit-to-non-local-addresses.patch42
-rw-r--r--patches.fixes/0023-netfilter-ebtables-reject-non-bridge-targets.patch66
-rw-r--r--patches.fixes/0024-netfilter-x_tables-initialise-match-target-check-par.patch77
-rw-r--r--patches.fixes/0025-l2tp-only-accept-PPP-sessions-in-pppol2tp_connect.patch40
-rw-r--r--patches.fixes/0026-l2tp-prevent-pppol2tp_connect-from-creating-kernel-s.patch49
-rw-r--r--patches.fixes/0027-l2tp-filter-out-non-PPP-sessions-in-pppol2tp_tunnel_.patch41
-rw-r--r--patches.fixes/0028-ipv6-mcast-fix-unsolicited-report-interval-after-rec.patch60
-rw-r--r--patches.fixes/0038-xfs-split-xfs_bmap_shift_extents.patch32
-rw-r--r--patches.fixes/9p-locks-add-mount-option-for-lock-retry-interval.patch123
-rw-r--r--patches.fixes/9p-locks-fix-glock.client_id-leak-in-do_lock.patch12
-rw-r--r--patches.fixes/ACPI-PM-Set-enable_for_wake-for-wakeup-GPEs-during-s.patch91
-rw-r--r--patches.fixes/ACPI-button-reinitialize-button-state-upon-resume.patch46
-rw-r--r--patches.fixes/ACPI-utils-Drop-reference-in-test-for-device-presenc.patch35
-rw-r--r--patches.fixes/ACPICA-AML-interpreter-add-region-addresses-in-globa.patch49
-rw-r--r--patches.fixes/ACPICA-Namespace-remove-address-node-from-global-lis.patch66
-rw-r--r--patches.fixes/MD-fix-invalid-stored-role-for-a-disk.patch47
-rw-r--r--patches.fixes/appletalk-Fix-compile-regression.patch71
-rw-r--r--patches.fixes/appletalk-Fix-use-after-free-in-atalk_proc_exit.patch204
-rw-r--r--patches.fixes/block-do-not-leak-memory-in-bio_copy_user_iov.patch46
-rw-r--r--patches.fixes/block-fix-the-return-errno-for-direct-IO.patch59
-rw-r--r--patches.fixes/block-fix-use-after-free-on-gendisk.patch135
-rw-r--r--patches.fixes/configfs-fix-possible-use-after-free-in-configfs_reg.patch134
-rw-r--r--patches.fixes/crypto-caam-fix-caam_dump_sg-that-iterates-through-s.patch40
-rw-r--r--patches.fixes/crypto-vmx-CTR-always-increment-IV-as-quadword.patch61
-rw-r--r--patches.fixes/dccp-Fix-memleak-in-__feat_register_sp.patch43
-rw-r--r--patches.fixes/debugfs-fix-use-after-free-on-symlink-traversal.patch51
-rw-r--r--patches.fixes/devres-Align-data-to-ARCH_KMALLOC_MINALIGN.patch62
-rw-r--r--patches.fixes/ext4-actually-request-zeroing-of-inode-table-after-g.patch41
-rw-r--r--patches.fixes/ext4-fix-ext4_show_options-for-file-systems-w-o-jour.patch39
-rw-r--r--patches.fixes/ext4-fix-use-after-free-race-with-debug_want_extra_i.patch105
-rw-r--r--patches.fixes/ext4-zero-out-the-unused-memory-region-in-the-extent.patch87
-rw-r--r--patches.fixes/ipconfig-Correctly-initialise-ic_nameservers.patch85
-rw-r--r--patches.fixes/ipvlan-Add-the-skb-mark-as-flow4-s-member-to-lookup-.patch34
-rw-r--r--patches.fixes/ipvlan-fix-ipv6-outbound-device.patch36
-rw-r--r--patches.fixes/ipvlan-use-ETH_MAX_MTU-as-max-mtu.patch35
-rw-r--r--patches.fixes/ipvs-Fix-signed-integer-overflow-when-setsockopt-tim.patch93
-rw-r--r--patches.fixes/ipvs-fix-race-between-ip_vs_conn_new-and-ip_vs_del_d.patch87
-rw-r--r--patches.fixes/l2tp-cleanup-l2tp_tunnel_delete-calls.patch58
-rw-r--r--patches.fixes/l2tp-revert-l2tp-fix-missing-print-session-offset-in.patch35
-rw-r--r--patches.fixes/mISDN-Check-address-length-before-reading-address-fa.patch39
-rw-r--r--patches.fixes/mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch49
-rw-r--r--patches.fixes/mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch35
-rw-r--r--patches.fixes/mm-huge_memory-fix-vmf_insert_pfn_-pmd-pud-crash-han.patch79
-rw-r--r--patches.fixes/mm-mincore-c-make-mincore-more-conservative.patch91
-rw-r--r--patches.fixes/net-smc-check-for-ip-prefix-and-subnet76
-rw-r--r--patches.fixes/net-smc-cleanup-of-get-vlan-id74
-rw-r--r--patches.fixes/net-smc-code-cleanup-smc_listen_work118
-rw-r--r--patches.fixes/net-smc-consolidate-function-parameters750
-rw-r--r--patches.fixes/net-smc-fallback-to-tcp-after-connect-problems36
-rw-r--r--patches.fixes/net-smc-fix-a-null-pointer-dereference32
-rw-r--r--patches.fixes/net-smc-fix-return-code-from-flush-command37
-rw-r--r--patches.fixes/net-smc-improve-smc_conn_create-reason-codes375
-rw-r--r--patches.fixes/net-smc-improve-smc_listen_work-reason-codes201
-rw-r--r--patches.fixes/net-smc-move-unhash-before-release-of-clcsock66
-rw-r--r--patches.fixes/net-smc-nonblocking-connect-rework218
-rw-r--r--patches.fixes/net-smc-propagate-file-from-smc-to-tcp-socket115
-rw-r--r--patches.fixes/net-smc-wait-for-pending-work-before-clcsock-release_sock127
-rw-r--r--patches.fixes/nl80211-Add-NL80211_FLAG_CLEAR_SKB-flag-for-other-NL.patch85
-rw-r--r--patches.fixes/nvme-fc-use-separate-work-queue-to-avoid-warning.patch88
-rw-r--r--patches.fixes/nvme-multipath-avoid-crash-on-invalid-subsystem-cntl.patch5
-rw-r--r--patches.fixes/rdma-smc-replace-ib_query_gid-with-rdma_get_gid_attr134
-rw-r--r--patches.fixes/scsi-smartpqi_init-fix-boolean-expression-in-pqi_device_remove_start36
-rw-r--r--patches.fixes/team-set-slave-to-promisc-if-team-is-already-in-prom.patch78
-rw-r--r--patches.fixes/ufs-fix-braino-in-ufs_get_inode_gid-for-solaris-UFS-.patch38
-rw-r--r--patches.fixes/vsock-virtio-Initialize-core-virtio-vsock-before-reg.patch113
-rw-r--r--patches.fixes/vt-always-call-notifier-with-the-console-lock-held.patch32
-rw-r--r--patches.fixes/xfs-add-log-item-pinning-error-injection-tag.patch120
-rw-r--r--patches.fixes/xfs-buffer-lru-reference-count-error-injection-tag.patch137
-rw-r--r--patches.fixes/xfs-check-_btree_check_block-value.patch49
-rw-r--r--patches.fixes/xfs-convert-drop_writes-to-use-the-errortag-mechanis.patch194
-rw-r--r--patches.fixes/xfs-create-block-pointer-check-functions.patch137
-rw-r--r--patches.fixes/xfs-create-inode-pointer-verifiers.patch212
-rw-r--r--patches.fixes/xfs-export-_inobt_btrec_to_irec-and-_ialloc_cluster_.patch111
-rw-r--r--patches.fixes/xfs-export-various-function-for-the-online-scrubber.patch277
-rw-r--r--patches.fixes/xfs-expose-errortag-knobs-via-sysfs.patch244
-rw-r--r--patches.fixes/xfs-fix-unused-variable-warning-in-xfs_buf_set_ref.patch45
-rw-r--r--patches.fixes/xfs-force-summary-counter-recalc-at-next-mount.patch131
-rw-r--r--patches.fixes/xfs-make-errortag-a-per-mountpoint-structure.patch336
-rw-r--r--patches.fixes/xfs-move-error-injection-tags-into-their-own-file.patch425
-rw-r--r--patches.fixes/xfs-refactor-btree-block-header-checking-functions.patch279
-rw-r--r--patches.fixes/xfs-refactor-btree-pointer-checks.patch162
-rw-r--r--patches.fixes/xfs-refactor-unmount-record-write.patch203
-rw-r--r--patches.fixes/xfs-remove-unneeded-parameter-from-XFS_TEST_ERROR.patch306
-rw-r--r--patches.fixes/xfs-rename-MAXPATHLEN-to-XFS_SYMLINK_MAXLEN.patch138
-rw-r--r--patches.fixes/xfs-replace-log_badcrc_factor-knob-with-error-inject.patch158
-rw-r--r--patches.fixes/xfs-sanity-check-the-unused-space-before-trying-to-u.patch321
-rw-r--r--patches.kabi/kabi-protect-ip_options_rcv_srr.patch66
-rw-r--r--patches.kabi/kabi-protect-struct-mlx5_td.patch30
-rw-r--r--patches.kabi/net-smc-preallocated-memory-for-rdma-work-requests2
-rw-r--r--patches.suse/TTY-serial_core-add-install.patch128
-rw-r--r--patches.suse/bnxt_en-Improve-RX-consumer-index-validity-check.patch54
-rw-r--r--patches.suse/bnxt_en-Reset-device-on-RX-buffer-errors.patch39
-rw-r--r--patches.suse/btrfs-do-not-allow-trimming-when-a-fs-is-mounted-wit.patch55
-rw-r--r--patches.suse/btrfs-improve-performance-on-fsync-of-files-with-mul.patch362
-rw-r--r--patches.suse/btrfs-send-flush-dellaloc-in-order-to-avoid-data-los.patch136
-rw-r--r--patches.suse/ip6_tunnel-Match-to-ARPHRD_TUNNEL6-for-dev-type.patch48
-rw-r--r--patches.suse/net-ethtool-not-call-vzalloc-for-zero-sized-memory-r.patch94
-rw-r--r--patches.suse/net-gro-Fix-GRO-flush-when-receiving-a-GSO-packet.patch37
-rw-r--r--patches.suse/net-mlx5-Decrease-default-mr-cache-size.patch55
-rw-r--r--patches.suse/net-mlx5e-Add-a-lock-on-tir-list.patch78
-rw-r--r--patches.suse/net-mlx5e-Fix-error-handling-when-refreshing-TIRs.patch43
-rw-r--r--patches.suse/net-sched-act_sample-fix-divide-by-zero-in-the-traff.patch98
-rw-r--r--patches.suse/net-sched-fix-get-helper-of-the-matchall-cls.patch54
-rw-r--r--patches.suse/qla2xxx-allow-irqbalance-control-in-non-MQ-mode.patch2
-rw-r--r--patches.suse/sched-do-not-re-read-h_load_next-during-hierarchical-load-calculation.patch11
-rw-r--r--patches.suse/sctp-initialize-_pad-of-sockaddr_in-before-copying-t.patch53
-rw-r--r--patches.suse/tcp-Ensure-DCTCP-reacts-to-losses.patch140
-rw-r--r--patches.suse/tun-allow-positive-return-values-on-dev_get_valid_na.patch2
-rw-r--r--patches.suse/tun-call-dev_get_valid_name-before-register_netdevic.patch2
-rw-r--r--patches.suse/vrf-check-accept_source_route-on-the-original-netdev.patch89
-rwxr-xr-xscripts/git_sort/git_sort.py6
-rw-r--r--series.conf260
271 files changed, 25928 insertions, 182 deletions
diff --git a/blacklist.conf b/blacklist.conf
index f92d248c3b..097ac8f80c 100644
--- a/blacklist.conf
+++ b/blacklist.conf
@@ -64,6 +64,7 @@ drivers/ide # IDE not shipped since SLE12
# -----------------------
CVE-2018-16880 # bsc#1122767, needed only for SLE15-SP1+
CVE-2019-9003 # bsc#1126704, needed only for SLE15-SP1+
+CVE-2019-11811 # bsc#1134397, needed only for SLE15-SP1+
# Blacklisted Commits
# -------------------
@@ -1023,5 +1024,20 @@ f58213637206e190453e3bd91f98f535566290a3 # regulator: missing regulator_lock() A
f7a621728a6a23bfd2c6ac4d3e42e1303aefde0f # regulator: missing regulator_lock() API in SLE15
8be64b6d87bd47d81753b60ddafe70102ebfd76b # regulator: missing regulator_lock() API in SLE15
e69b394703e032e56a140172440ec4f9890b536d # regulator: missing regulator_lock() API in SLE15
+b01531db6cec2aa330dbc91bfbfaaef4a0d387a4 # ext4 encryption not supported and this is rare race with mostly benign consequences
+a5fdd713d256887b5f012608701149fa939e5645 # Just a cleanup
+0bf3d5c1604ecbbd4e49e9f5b3c79152b87adb0d # fscrypt not supported
+71921ef85928e95e3d942c747c9d40443a5ff775 # GFS2 not supported, just a performance optimization
+7959cf3a7506d4a2100d5d6f37f605c2f54af488 # ubifs not supported, no CC to stable
+988bec41318f3fa897e2f8af271bd456936d6caf # ubifs not supported, no CC to stable
+9ca2d732644484488db31123ecd3bf122b551566 # ubifs not supported, no CC to stable
98fdaaca9537b997062f1abc0aa87c61b50ce40a # Duplicate of fc89a38d99d4b1b33ca5b0e2329f5ddea02ecfb5: drm/i915/opregion: fix version check
a0f52c3d357af218a9c1f7cd906ab70426176a1a # Duplicate of 16eb0f34cdf4cf04cd92762c7a79f98aa51e053f: drm/i915/opregion: rvda is relative from opregion base in opregion 2.1+
+ed180abba7f1fc3cf04ffa27767b1bcc8e8c842a # sound/hda: breaks kABI
+e2771deb5dece1acde9a406538e4f7ef9262d5cd # recently dropped: drm/sun4i: rgb: Change the pixel clock validation check
+75fdb811d93c8aa4a9f73b63db032b1e6a8668ef # Duplicate of 1e8b15a1988ed3c7429402017d589422628cdf47: drm/i915/gvt: Add in context mmio 0x20D8 to gen9 mmio list
+6fcc44d1d77fea3c7230e4d109b37f6977aa675a # Duplicate of 2c88e3c7ec32d7a40cc7c9b4a487cf90e4671bdd: block: fix use-after-free on gendisk
+c8ea3663f7a8e6996d44500ee818c9330ac4fd88 # virt/fsl: no supported platform
+6a024330650e24556b8a18cc654ad00cfecf6c6c # virt/fsl: no supported platform
+92ff42645028fa6f9b8aa767718457b9264316b4 # ipvlan: reverted in below
+918150cbd6103199fe326e8b1462a7f0d81475e4 # ipvlan: reverting the above
diff --git a/config/armv7hl/default b/config/armv7hl/default
index 3347764454..a358767b41 100644
--- a/config/armv7hl/default
+++ b/config/armv7hl/default
@@ -66,6 +66,7 @@ CONFIG_AUDIT=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
diff --git a/config/armv7hl/lpae b/config/armv7hl/lpae
index 6ac8b72a98..31965d173d 100644
--- a/config/armv7hl/lpae
+++ b/config/armv7hl/lpae
@@ -65,6 +65,7 @@ CONFIG_AUDIT=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
+CONFIG_GENERIC_IRQ_MIGRATION=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_IRQ_DOMAIN=y
@@ -577,7 +578,6 @@ CONFIG_PLAT_SAMSUNG=y
#
# Power management
#
-# CONFIG_SAMSUNG_PM_CHECK is not set
# CONFIG_ARCH_RENESAS is not set
CONFIG_ARCH_SUNXI=y
# CONFIG_MACH_SUN4I is not set
diff --git a/config/x86_64/default b/config/x86_64/default
index 2a5c670015..93aa631003 100644
--- a/config/x86_64/default
+++ b/config/x86_64/default
@@ -496,6 +496,7 @@ CONFIG_X86_DEBUGCTLMSR=y
# CONFIG_PROCESSOR_SELECT is not set
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_AMD=y
+CONFIG_CPU_SUP_HYGON=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
diff --git a/patches.arch/ARM-8824-1-fix-a-migrating-irq-bug-when-hotplug-cpu.patch b/patches.arch/ARM-8824-1-fix-a-migrating-irq-bug-when-hotplug-cpu.patch
new file mode 100644
index 0000000000..04477fa20f
--- /dev/null
+++ b/patches.arch/ARM-8824-1-fix-a-migrating-irq-bug-when-hotplug-cpu.patch
@@ -0,0 +1,158 @@
+From 1b5ba350784242eb1f899bcffd95d2c7cff61e84 Mon Sep 17 00:00:00 2001
+From: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Date: Mon, 21 Jan 2019 14:42:42 +0100
+Subject: [PATCH] ARM: 8824/1: fix a migrating irq bug when hotplug cpu
+Git-commit: 1b5ba350784242eb1f899bcffd95d2c7cff61e84
+Patch-mainline: v5.0-rc8
+References: bsc#1051510
+
+Arm TC2 fails cpu hotplug stress test.
+
+This issue was tracked down to a missing copy of the new affinity
+cpumask for the vexpress-spc interrupt into struct
+irq_common_data.affinity when the interrupt is migrated in
+migrate_one_irq().
+
+Fix it by replacing the arm specific hotplug cpu migration with the
+generic irq code.
+
+This is the counterpart implementation to commit 217d453d473c ("arm64:
+fix a migrating irq bug when hotplug cpu").
+
+Tested with cpu hotplug stress test on Arm TC2 (multi_v7_defconfig plus
+CONFIG_ARM_BIG_LITTLE_CPUFREQ=y and CONFIG_ARM_VEXPRESS_SPC_CPUFREQ=y).
+The vexpress-spc interrupt (irq=22) on this board is affine to CPU0.
+Its affinity cpumask now changes correctly e.g. from 0 to 1-4 when
+CPU0 is hotplugged out.
+
+Suggested-by: Marc Zyngier <marc.zyngier@arm.com>
+Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
+Acked-by: Marc Zyngier <marc.zyngier@arm.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/Kconfig | 1 +
+ arch/arm/include/asm/irq.h | 1 -
+ arch/arm/kernel/irq.c | 62 ----------------------------------------------
+ arch/arm/kernel/smp.c | 2 +-
+ 4 files changed, 2 insertions(+), 64 deletions(-)
+
+diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
+index 664e918e2624..26524b75970a 100644
+--- a/arch/arm/Kconfig
++++ b/arch/arm/Kconfig
+@@ -1400,6 +1400,7 @@ config NR_CPUS
+ config HOTPLUG_CPU
+ bool "Support for hot-pluggable CPUs"
+ depends on SMP
++ select GENERIC_IRQ_MIGRATION
+ help
+ Say Y here to experiment with turning CPUs off and on. CPUs
+ can be controlled through /sys/devices/system/cpu.
+diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
+index c883fcbe93b6..46d41140df27 100644
+--- a/arch/arm/include/asm/irq.h
++++ b/arch/arm/include/asm/irq.h
+@@ -25,7 +25,6 @@
+ #ifndef __ASSEMBLY__
+ struct irqaction;
+ struct pt_regs;
+-extern void migrate_irqs(void);
+
+ extern void asm_do_IRQ(unsigned int, struct pt_regs *);
+ void handle_IRQ(unsigned int, struct pt_regs *);
+diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
+index 9908dacf9229..844861368cd5 100644
+--- a/arch/arm/kernel/irq.c
++++ b/arch/arm/kernel/irq.c
+@@ -31,7 +31,6 @@
+ #include <linux/smp.h>
+ #include <linux/init.h>
+ #include <linux/seq_file.h>
+-#include <linux/ratelimit.h>
+ #include <linux/errno.h>
+ #include <linux/list.h>
+ #include <linux/kallsyms.h>
+@@ -109,64 +108,3 @@ int __init arch_probe_nr_irqs(void)
+ return nr_irqs;
+ }
+ #endif
+-
+-#ifdef CONFIG_HOTPLUG_CPU
+-static bool migrate_one_irq(struct irq_desc *desc)
+-{
+- struct irq_data *d = irq_desc_get_irq_data(desc);
+- const struct cpumask *affinity = irq_data_get_affinity_mask(d);
+- struct irq_chip *c;
+- bool ret = false;
+-
+- /*
+- * If this is a per-CPU interrupt, or the affinity does not
+- * include this CPU, then we have nothing to do.
+- */
+- if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity))
+- return false;
+-
+- if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
+- affinity = cpu_online_mask;
+- ret = true;
+- }
+-
+- c = irq_data_get_irq_chip(d);
+- if (!c->irq_set_affinity)
+- pr_debug("IRQ%u: unable to set affinity\n", d->irq);
+- else if (c->irq_set_affinity(d, affinity, false) == IRQ_SET_MASK_OK && ret)
+- cpumask_copy(irq_data_get_affinity_mask(d), affinity);
+-
+- return ret;
+-}
+-
+-/*
+- * The current CPU has been marked offline. Migrate IRQs off this CPU.
+- * If the affinity settings do not allow other CPUs, force them onto any
+- * available CPU.
+- *
+- * Note: we must iterate over all IRQs, whether they have an attached
+- * action structure or not, as we need to get chained interrupts too.
+- */
+-void migrate_irqs(void)
+-{
+- unsigned int i;
+- struct irq_desc *desc;
+- unsigned long flags;
+-
+- local_irq_save(flags);
+-
+- for_each_irq_desc(i, desc) {
+- bool affinity_broken;
+-
+- raw_spin_lock(&desc->lock);
+- affinity_broken = migrate_one_irq(desc);
+- raw_spin_unlock(&desc->lock);
+-
+- if (affinity_broken)
+- pr_warn_ratelimited("IRQ%u no longer affine to CPU%u\n",
+- i, smp_processor_id());
+- }
+-
+- local_irq_restore(flags);
+-}
+-#endif /* CONFIG_HOTPLUG_CPU */
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 3bf82232b1be..1d6f5ea522f4 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -254,7 +254,7 @@ int __cpu_disable(void)
+ /*
+ * OK - migrate IRQs away from this CPU
+ */
+- migrate_irqs();
++ irq_migrate_all_off_this_cpu();
+
+ /*
+ * Flush user cache and TLB mappings, and then remove this CPU
+--
+2.16.4
+
diff --git a/patches.arch/ARM-8833-1-Ensure-that-NEON-code-always-compiles-wit.patch b/patches.arch/ARM-8833-1-Ensure-that-NEON-code-always-compiles-wit.patch
new file mode 100644
index 0000000000..88d75c8875
--- /dev/null
+++ b/patches.arch/ARM-8833-1-Ensure-that-NEON-code-always-compiles-wit.patch
@@ -0,0 +1,113 @@
+From de9c0d49d85dc563549972edc5589d195cd5e859 Mon Sep 17 00:00:00 2001
+From: Nathan Chancellor <natechancellor@gmail.com>
+Date: Sat, 2 Feb 2019 03:34:36 +0100
+Subject: [PATCH] ARM: 8833/1: Ensure that NEON code always compiles with Clang
+Git-commit: de9c0d49d85dc563549972edc5589d195cd5e859
+Patch-mainline: v5.1-rc1
+References: bsc#1051510
+
+While building arm32 allyesconfig, I ran into the following errors:
+
+ arch/arm/lib/xor-neon.c:17:2: error: You should compile this file with
+ '-mfloat-abi=softfp -mfpu=neon'
+
+ In file included from lib/raid6/neon1.c:27:
+ /home/nathan/cbl/prebuilt/lib/clang/8.0.0/include/arm_neon.h:28:2:
+ error: "NEON support not enabled"
+
+Building V=1 showed NEON_FLAGS getting passed along to Clang but
+__ARM_NEON__ was not getting defined. Ultimately, it boils down to Clang
+only defining __ARM_NEON__ when targeting armv7, rather than armv6k,
+which is the '-march' value for allyesconfig.
+
+>From lib/Basic/Targets/ARM.cpp in the Clang source:
+
+ // This only gets set when Neon instructions are actually available, unlike
+ // the VFP define, hence the soft float and arch check. This is subtly
+ // different from gcc, we follow the intent which was that it should be set
+ // when Neon instructions are actually available.
+ if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
+ Builder.defineMacro("__ARM_NEON", "1");
+ Builder.defineMacro("__ARM_NEON__");
+ // current AArch32 NEON implementations do not support double-precision
+ // floating-point even when it is present in VFP.
+ Builder.defineMacro("__ARM_NEON_FP",
+ "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
+ }
+
+Ard Biesheuvel recommended explicitly adding '-march=armv7-a' at the
+beginning of the NEON_FLAGS definitions so that __ARM_NEON__ always gets
+definined by Clang. This doesn't functionally change anything because
+that code will only run where NEON is supported, which is implicitly
+armv7.
+
+Link: https://github.com/ClangBuiltLinux/linux/issues/287
+
+Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
+Acked-by: Nicolas Pitre <nico@linaro.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Reviewed-by: Stefan Agner <stefan@agner.ch>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ Documentation/arm/kernel_mode_neon.txt | 4 ++--
+ arch/arm/lib/Makefile | 2 +-
+ arch/arm/lib/xor-neon.c | 2 +-
+ lib/raid6/Makefile | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/Documentation/arm/kernel_mode_neon.txt
++++ b/Documentation/arm/kernel_mode_neon.txt
+@@ -6,7 +6,7 @@ TL;DR summary
+ * Use only NEON instructions, or VFP instructions that don't rely on support
+ code
+ * Isolate your NEON code in a separate compilation unit, and compile it with
+- '-mfpu=neon -mfloat-abi=softfp'
++ '-march=armv7-a -mfpu=neon -mfloat-abi=softfp'
+ * Put kernel_neon_begin() and kernel_neon_end() calls around the calls into your
+ NEON code
+ * Don't sleep in your NEON code, and be aware that it will be executed with
+@@ -87,7 +87,7 @@ instructions appearing in unexpected pla
+ Therefore, the recommended and only supported way of using NEON/VFP in the
+ kernel is by adhering to the following rules:
+ * isolate the NEON code in a separate compilation unit and compile it with
+- '-mfpu=neon -mfloat-abi=softfp';
++ '-march=armv7-a -mfpu=neon -mfloat-abi=softfp';
+ * issue the calls to kernel_neon_begin(), kernel_neon_end() as well as the calls
+ into the unit containing the NEON code from a compilation unit which is *not*
+ built with the GCC flag '-mfpu=neon' set.
+--- a/arch/arm/lib/Makefile
++++ b/arch/arm/lib/Makefile
+@@ -38,7 +38,7 @@ $(obj)/csumpartialcopy.o: $(obj)/csumpar
+ $(obj)/csumpartialcopyuser.o: $(obj)/csumpartialcopygeneric.S
+
+ ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
+- NEON_FLAGS := -mfloat-abi=softfp -mfpu=neon
++ NEON_FLAGS := -march=armv7-a -mfloat-abi=softfp -mfpu=neon
+ CFLAGS_xor-neon.o += $(NEON_FLAGS)
+ obj-$(CONFIG_XOR_BLOCKS) += xor-neon.o
+ endif
+--- a/arch/arm/lib/xor-neon.c
++++ b/arch/arm/lib/xor-neon.c
+@@ -14,7 +14,7 @@
+ MODULE_LICENSE("GPL");
+
+ #ifndef __ARM_NEON__
+-#error You should compile this file with '-mfloat-abi=softfp -mfpu=neon'
++#error You should compile this file with '-march=armv7-a -mfloat-abi=softfp -mfpu=neon'
+ #endif
+
+ /*
+--- a/lib/raid6/Makefile
++++ b/lib/raid6/Makefile
+@@ -24,7 +24,7 @@ endif
+ ifeq ($(CONFIG_KERNEL_MODE_NEON),y)
+ NEON_FLAGS := -ffreestanding
+ ifeq ($(ARCH),arm)
+-NEON_FLAGS += -mfloat-abi=softfp -mfpu=neon
++NEON_FLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=neon
+ endif
+ CFLAGS_recov_neon_inner.o += $(NEON_FLAGS)
+ ifeq ($(ARCH),arm64)
diff --git a/patches.arch/ARM-8839-1-kprobe-make-patch_lock-a-raw_spinlock_t.patch b/patches.arch/ARM-8839-1-kprobe-make-patch_lock-a-raw_spinlock_t.patch
new file mode 100644
index 0000000000..202e544be1
--- /dev/null
+++ b/patches.arch/ARM-8839-1-kprobe-make-patch_lock-a-raw_spinlock_t.patch
@@ -0,0 +1,69 @@
+From 143c2a89e0e5fda6c6fd08d7bc1126438c19ae90 Mon Sep 17 00:00:00 2001
+From: Yang Shi <yang.shi@linaro.org>
+Date: Wed, 13 Feb 2019 17:14:23 +0100
+Subject: [PATCH] ARM: 8839/1: kprobe: make patch_lock a raw_spinlock_t
+Git-commit: 143c2a89e0e5fda6c6fd08d7bc1126438c19ae90
+Patch-mainline: v5.1-rc1
+References: bsc#1051510
+
+When running kprobe on -rt kernel, the below bug is caught:
+
+|bug: sleeping function called from invalid context at kernel/locking/rtmutex.c:931
+|in_atomic(): 1, irqs_disabled(): 128, pid: 14, name: migration/0
+|Preemption disabled at:[<802f2b98>] cpu_stopper_thread+0xc0/0x140
+|cpu: 0 PID: 14 Comm: migration/0 Tainted: G O 4.8.3-rt2 #1
+|Hardware name: Freescale LS1021A
+|[<8025a43c>] (___might_sleep)
+|[<80b5b324>] (rt_spin_lock)
+|[<80b5c31c>] (__patch_text_real)
+|[<80b5c3ac>] (patch_text_stop_machine)
+|[<802f2920>] (multi_cpu_stop)
+
+Since patch_text_stop_machine() is called in stop_machine() which
+disables IRQ, sleepable lock should be not used in this atomic context,
+ so replace patch_lock to raw lock.
+
+Signed-off-by: Yang Shi <yang.shi@linaro.org>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/kernel/patch.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
+index a50dc00d79a2..d0a05a3bdb96 100644
+--- a/arch/arm/kernel/patch.c
++++ b/arch/arm/kernel/patch.c
+@@ -16,7 +16,7 @@ struct patch {
+ unsigned int insn;
+ };
+
+-static DEFINE_SPINLOCK(patch_lock);
++static DEFINE_RAW_SPINLOCK(patch_lock);
+
+ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
+ __acquires(&patch_lock)
+@@ -33,7 +33,7 @@ static void __kprobes *patch_map(void *addr, int fixmap, unsigned long *flags)
+ return addr;
+
+ if (flags)
+- spin_lock_irqsave(&patch_lock, *flags);
++ raw_spin_lock_irqsave(&patch_lock, *flags);
+ else
+ __acquire(&patch_lock);
+
+@@ -48,7 +48,7 @@ static void __kprobes patch_unmap(int fixmap, unsigned long *flags)
+ clear_fixmap(fixmap);
+
+ if (flags)
+- spin_unlock_irqrestore(&patch_lock, *flags);
++ raw_spin_unlock_irqrestore(&patch_lock, *flags);
+ else
+ __release(&patch_lock);
+ }
+--
+2.16.4
+
diff --git a/patches.arch/ARM-8840-1-use-a-raw_spinlock_t-in-unwind.patch b/patches.arch/ARM-8840-1-use-a-raw_spinlock_t-in-unwind.patch
new file mode 100644
index 0000000000..7becf9ba4b
--- /dev/null
+++ b/patches.arch/ARM-8840-1-use-a-raw_spinlock_t-in-unwind.patch
@@ -0,0 +1,94 @@
+From 74ffe79ae538283bbf7c155e62339f1e5c87b55a Mon Sep 17 00:00:00 2001
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Date: Wed, 13 Feb 2019 17:14:42 +0100
+Subject: [PATCH] ARM: 8840/1: use a raw_spinlock_t in unwind
+Git-commit: 74ffe79ae538283bbf7c155e62339f1e5c87b55a
+Patch-mainline: v5.1-rc1
+References: bsc#1051510
+
+Mostly unwind is done with irqs enabled however SLUB may call it with
+irqs disabled while creating a new SLUB cache.
+
+I had system freeze while loading a module which called
+kmem_cache_create() on init. That means SLUB's __slab_alloc() disabled
+interrupts and then
+
+->new_slab_objects()
+ ->new_slab()
+ ->setup_object()
+ ->setup_object_debug()
+ ->init_tracking()
+ ->set_track()
+ ->save_stack_trace()
+ ->save_stack_trace_tsk()
+ ->walk_stackframe()
+ ->unwind_frame()
+ ->unwind_find_idx()
+ =>spin_lock_irqsave(&unwind_lock);
+
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/kernel/unwind.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
+index 0bee233fef9a..314cfb232a63 100644
+--- a/arch/arm/kernel/unwind.c
++++ b/arch/arm/kernel/unwind.c
+@@ -93,7 +93,7 @@ extern const struct unwind_idx __start_unwind_idx[];
+ static const struct unwind_idx *__origin_unwind_idx;
+ extern const struct unwind_idx __stop_unwind_idx[];
+
+-static DEFINE_SPINLOCK(unwind_lock);
++static DEFINE_RAW_SPINLOCK(unwind_lock);
+ static LIST_HEAD(unwind_tables);
+
+ /* Convert a prel31 symbol to an absolute address */
+@@ -201,7 +201,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr)
+ /* module unwind tables */
+ struct unwind_table *table;
+
+- spin_lock_irqsave(&unwind_lock, flags);
++ raw_spin_lock_irqsave(&unwind_lock, flags);
+ list_for_each_entry(table, &unwind_tables, list) {
+ if (addr >= table->begin_addr &&
+ addr < table->end_addr) {
+@@ -213,7 +213,7 @@ static const struct unwind_idx *unwind_find_idx(unsigned long addr)
+ break;
+ }
+ }
+- spin_unlock_irqrestore(&unwind_lock, flags);
++ raw_spin_unlock_irqrestore(&unwind_lock, flags);
+ }
+
+ pr_debug("%s: idx = %p\n", __func__, idx);
+@@ -529,9 +529,9 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size,
+ tab->begin_addr = text_addr;
+ tab->end_addr = text_addr + text_size;
+
+- spin_lock_irqsave(&unwind_lock, flags);
++ raw_spin_lock_irqsave(&unwind_lock, flags);
+ list_add_tail(&tab->list, &unwind_tables);
+- spin_unlock_irqrestore(&unwind_lock, flags);
++ raw_spin_unlock_irqrestore(&unwind_lock, flags);
+
+ return tab;
+ }
+@@ -543,9 +543,9 @@ void unwind_table_del(struct unwind_table *tab)
+ if (!tab)
+ return;
+
+- spin_lock_irqsave(&unwind_lock, flags);
++ raw_spin_lock_irqsave(&unwind_lock, flags);
+ list_del(&tab->list);
+- spin_unlock_irqrestore(&unwind_lock, flags);
++ raw_spin_unlock_irqrestore(&unwind_lock, flags);
+
+ kfree(tab);
+ }
+--
+2.16.4
+
diff --git a/patches.arch/ARM-OMAP2-Variable-reg-in-function-omap4_dsi_mux_pad.patch b/patches.arch/ARM-OMAP2-Variable-reg-in-function-omap4_dsi_mux_pad.patch
new file mode 100644
index 0000000000..9471c70785
--- /dev/null
+++ b/patches.arch/ARM-OMAP2-Variable-reg-in-function-omap4_dsi_mux_pad.patch
@@ -0,0 +1,49 @@
+From dc30e70391376ba3987aeb856ae6d9c0706534f1 Mon Sep 17 00:00:00 2001
+From: Yizhuo <yzhai003@ucr.edu>
+Date: Fri, 25 Jan 2019 22:32:20 -0800
+Subject: [PATCH] ARM: OMAP2+: Variable "reg" in function omap4_dsi_mux_pads() could be uninitialized
+Git-commit: dc30e70391376ba3987aeb856ae6d9c0706534f1
+Patch-mainline: v5.0-rc7
+References: bsc#1051510
+
+In function omap4_dsi_mux_pads(), local variable "reg" could
+be uninitialized if function regmap_read() returns -EINVAL.
+However, it will be used directly in the later context, which
+is potentially unsafe.
+
+Signed-off-by: Yizhuo <yzhai003@ucr.edu>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/mach-omap2/display.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
+index f86b72d1d59e..1444b4b4bd9f 100644
+--- a/arch/arm/mach-omap2/display.c
++++ b/arch/arm/mach-omap2/display.c
+@@ -83,6 +83,7 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+ u32 enable_mask, enable_shift;
+ u32 pipd_mask, pipd_shift;
+ u32 reg;
++ int ret;
+
+ if (dsi_id == 0) {
+ enable_mask = OMAP4_DSI1_LANEENABLE_MASK;
+@@ -98,7 +99,11 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
+ return -ENODEV;
+ }
+
+- regmap_read(omap4_dsi_mux_syscon, OMAP4_DSIPHY_SYSCON_OFFSET, &reg);
++ ret = regmap_read(omap4_dsi_mux_syscon,
++ OMAP4_DSIPHY_SYSCON_OFFSET,
++ &reg);
++ if (ret)
++ return ret;
+
+ reg &= ~enable_mask;
+ reg &= ~pipd_mask;
+--
+2.16.4
+
diff --git a/patches.arch/ARM-OMAP2-fix-lack-of-timer-interrupts-on-CPU1-after.patch b/patches.arch/ARM-OMAP2-fix-lack-of-timer-interrupts-on-CPU1-after.patch
new file mode 100644
index 0000000000..019c5ac314
--- /dev/null
+++ b/patches.arch/ARM-OMAP2-fix-lack-of-timer-interrupts-on-CPU1-after.patch
@@ -0,0 +1,81 @@
+From 50d6b3cf9403879911e06d69c7ef41e43f8f7b4b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Wed, 12 Dec 2018 11:49:47 +0000
+Subject: [PATCH] ARM: OMAP2+: fix lack of timer interrupts on CPU1 after hotplug
+Git-commit: 50d6b3cf9403879911e06d69c7ef41e43f8f7b4b
+Patch-mainline: v5.0-rc7
+References: bsc#1051510
+
+If we have a kernel configured for periodic timer interrupts, and we
+have cpuidle enabled, then we end up with CPU1 losing timer interupts
+after a hotplug.
+
+This can manifest itself in RCU stall warnings, or userspace becoming
+unresponsive.
+
+The problem is that the kernel initially wants to use the TWD timer
+for interrupts, but the TWD loses context when we enter the C3 cpuidle
+state. Nothing reprograms the TWD after idle.
+
+We have solved this in the past by switching to broadcast timer ticks,
+and cpuidle44xx switches to that mode at boot time. However, there is
+nothing to switch from periodic mode local timers after a hotplug
+operation.
+
+We call tick_broadcast_enter() in omap_enter_idle_coupled(), which one
+would expect would take care of the issue, but internally this only
+deals with one-shot local timers - tick_broadcast_enable() on the other
+hand only deals with periodic local timers. So, we need to call both.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+[tony@atomide.com: just standardized the subject line]
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/mach-omap2/cpuidle44xx.c | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
+index a8b291f00109..dae514c8276a 100644
+--- a/arch/arm/mach-omap2/cpuidle44xx.c
++++ b/arch/arm/mach-omap2/cpuidle44xx.c
+@@ -152,6 +152,10 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
+ mpuss_can_lose_context = (cx->mpu_state == PWRDM_POWER_RET) &&
+ (cx->mpu_logic_state == PWRDM_POWER_OFF);
+
++ /* Enter broadcast mode for periodic timers */
++ tick_broadcast_enable();
++
++ /* Enter broadcast mode for one-shot timers */
+ tick_broadcast_enter();
+
+ /*
+@@ -218,15 +222,6 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,
+ return index;
+ }
+
+-/*
+- * For each cpu, setup the broadcast timer because local timers
+- * stops for the states above C1.
+- */
+-static void omap_setup_broadcast_timer(void *arg)
+-{
+- tick_broadcast_enable();
+-}
+-
+ static struct cpuidle_driver omap4_idle_driver = {
+ .name = "omap4_idle",
+ .owner = THIS_MODULE,
+@@ -319,8 +314,5 @@ int __init omap4_idle_init(void)
+ if (!cpu_clkdm[0] || !cpu_clkdm[1])
+ return -ENODEV;
+
+- /* Configure the broadcast timer on each cpu */
+- on_each_cpu(omap_setup_broadcast_timer, NULL, 1);
+-
+ return cpuidle_register(idle_driver, cpu_online_mask);
+ }
+--
+2.16.4
+
diff --git a/patches.arch/ARM-avoid-Cortex-A9-livelock-on-tight-dmb-loops.patch b/patches.arch/ARM-avoid-Cortex-A9-livelock-on-tight-dmb-loops.patch
new file mode 100644
index 0000000000..900fb560ff
--- /dev/null
+++ b/patches.arch/ARM-avoid-Cortex-A9-livelock-on-tight-dmb-loops.patch
@@ -0,0 +1,194 @@
+From 5388a5b82199facacd3d7ac0d05aca6e8f902fed Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Tue, 10 Apr 2018 11:35:36 +0100
+Subject: [PATCH] ARM: avoid Cortex-A9 livelock on tight dmb loops
+Git-commit: 5388a5b82199facacd3d7ac0d05aca6e8f902fed
+Patch-mainline: v5.1-rc1
+References: bsc#1051510
+
+machine_crash_nonpanic_core() does this:
+
+ while (1)
+ cpu_relax();
+
+because the kernel has crashed, and we have no known safe way to deal
+with the CPU. So, we place the CPU into an infinite loop which we
+expect it to never exit - at least not until the system as a whole is
+reset by some method.
+
+In the absence of erratum 754327, this code assembles to:
+
+ b .
+
+In other words, an infinite loop. When erratum 754327 is enabled,
+this becomes:
+
+1: dmb b 1b
+
+It has been observed that on some systems (eg, OMAP4) where, if a
+crash is triggered, the system tries to kexec into the panic kernel,
+but fails after taking the secondary CPU down - placing it into one
+of these loops. This causes the system to livelock, and the most
+noticable effect is the system stops after issuing:
+
+ Loading crashdump kernel...
+
+to the system console.
+
+The tested as working solution I came up with was to add wfe() to
+these infinite loops thusly:
+
+ while (1) {
+ cpu_relax();
+ wfe();
+ }
+
+which, without 754327 builds to:
+
+1: wfe b 1b
+
+or with 754327 is enabled:
+
+1: dmb wfe b 1b
+
+Adding "wfe" does two things depending on the environment we're running
+Under:
+- where we're running on bare metal, and the processor implements
+ "wfe", it stops us spinning endlessly in a loop where we're never
+ going to do any useful work.
+- if we're running in a VM, it allows the CPU to be given back to the
+ hypervisor and rescheduled for other purposes (maybe a different VM)
+ rather than wasting CPU cycles inside a crashed VM.
+
+However, in light of erratum 794072, Will Deacon wanted to see 10 nops
+as well - which is reasonable to cover the case where we have erratum
+754327 enabled _and_ we have a processor that doesn't implement the
+wfe hint.
+
+So, we now end up with:
+
+1: wfe b 1b
+
+when erratum 754327 is disabled, or:
+
+1: dmb nop nop nop nop nop nop nop nop nop nop wfe b 1b
+
+when erratum 754327 is enabled. We also get the dmb + 10 nop
+sequence elsewhere in the kernel, in terminating loops.
+
+This is reasonable - it means we get the workaround for erratum
+794072 when erratum 754327 is enabled, but still relinquish the dead
+processor - either by placing it in a lower power mode when wfe is
+implemented as such or by returning it to the hypervisior, or in the
+case where wfe is a no-op, we use the workaround specified in erratum
+794072 to avoid the problem.
+
+These as two entirely orthogonal problems - the 10 nops addresses
+erratum 794072, and the wfe is an optimisation that makes the system
+more efficient when crashed either in terms of power consumption or
+by allowing the host/other VMs to make use of the CPU.
+
+I don't see any reason not to use kexec() inside a VM - it has the
+potential to provide automated recovery from a failure of the VMs
+kernel with the opportunity for saving a crashdump of the failure.
+A panic() with a reboot timeout won't do that, and reading the
+libvirt documentation, setting on_reboot to "preserve" won't either
+(the documentation states "The preserve action for an on_reboot event
+is treated as a destroy".) Surely it has to be a good thing to
+avoiding having CPUs spinning inside a VM that is doing no useful
+work.
+
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/include/asm/barrier.h | 2 ++
+ arch/arm/include/asm/processor.h | 6 +++++-
+ arch/arm/kernel/machine_kexec.c | 5 ++++-
+ arch/arm/kernel/smp.c | 4 +++-
+ arch/arm/mach-omap2/prm_common.c | 4 +++-
+ 5 files changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
+index 69772e742a0a..83ae97c049d9 100644
+--- a/arch/arm/include/asm/barrier.h
++++ b/arch/arm/include/asm/barrier.h
+@@ -11,6 +11,8 @@
+ #define sev() __asm__ __volatile__ ("sev" : : : "memory")
+ #define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
+ #define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
++#else
++#define wfe() do { } while (0)
+ #endif
+
+ #if __LINUX_ARM_ARCH__ >= 7
+diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
+index 120f4c9bbfde..57fe73ea0f72 100644
+--- a/arch/arm/include/asm/processor.h
++++ b/arch/arm/include/asm/processor.h
+@@ -89,7 +89,11 @@ extern void release_thread(struct task_struct *);
+ unsigned long get_wchan(struct task_struct *p);
+
+ #if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
+-#define cpu_relax() smp_mb()
++#define cpu_relax() \
++ do { \
++ smp_mb(); \
++ __asm__ __volatile__("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); \
++ } while (0)
+ #else
+ #define cpu_relax() barrier()
+ #endif
+diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
+index dd2eb5f76b9f..76300f3813e8 100644
+--- a/arch/arm/kernel/machine_kexec.c
++++ b/arch/arm/kernel/machine_kexec.c
+@@ -91,8 +91,11 @@ void machine_crash_nonpanic_core(void *unused)
+
+ set_cpu_online(smp_processor_id(), false);
+ atomic_dec(&waiting_for_crash_ipi);
+- while (1)
++
++ while (1) {
+ cpu_relax();
++ wfe();
++ }
+ }
+
+ void crash_smp_send_stop(void)
+diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
+index 3bf82232b1be..7f0b99e1fff3 100644
+--- a/arch/arm/kernel/smp.c
++++ b/arch/arm/kernel/smp.c
+@@ -604,8 +604,10 @@ static void ipi_cpu_stop(unsigned int cpu)
+ local_fiq_disable();
+ local_irq_disable();
+
+- while (1)
++ while (1) {
+ cpu_relax();
++ wfe();
++ }
+ }
+
+ static DEFINE_PER_CPU(struct completion *, cpu_completion);
+diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
+index 058a37e6d11c..fd6e0671f957 100644
+--- a/arch/arm/mach-omap2/prm_common.c
++++ b/arch/arm/mach-omap2/prm_common.c
+@@ -523,8 +523,10 @@ void omap_prm_reset_system(void)
+
+ prm_ll_data->reset_system();
+
+- while (1)
++ while (1) {
+ cpu_relax();
++ wfe();
++ }
+ }
+
+ /**
+--
+2.16.4
+
diff --git a/patches.arch/ARM-imx6q-cpuidle-fix-bug-that-CPU-might-not-wake-up.patch b/patches.arch/ARM-imx6q-cpuidle-fix-bug-that-CPU-might-not-wake-up.patch
new file mode 100644
index 0000000000..7bf87e1631
--- /dev/null
+++ b/patches.arch/ARM-imx6q-cpuidle-fix-bug-that-CPU-might-not-wake-up.patch
@@ -0,0 +1,80 @@
+From 91740fc8242b4f260cfa4d4536d8551804777fae Mon Sep 17 00:00:00 2001
+From: Kohji Okuno <okuno.kohji@jp.panasonic.com>
+Date: Tue, 26 Feb 2019 11:34:13 +0900
+Subject: [PATCH] ARM: imx6q: cpuidle: fix bug that CPU might not wake up at expected time
+Git-commit: 91740fc8242b4f260cfa4d4536d8551804777fae
+Patch-mainline: v5.1-rc3
+References: bsc#1051510
+
+In the current cpuidle implementation for i.MX6q, the CPU that sets
+'WAIT_UNCLOCKED' and the CPU that returns to 'WAIT_CLOCKED' are always
+the same. While the CPU that sets 'WAIT_UNCLOCKED' is in IDLE state of
+"WAIT", if the other CPU wakes up and enters IDLE state of "WFI"
+istead of "WAIT", this CPU can not wake up at expired time.
+ Because, in the case of "WFI", the CPU must be waked up by the local
+timer interrupt. But, while 'WAIT_UNCLOCKED' is set, the local timer
+is stopped, when all CPUs execute "wfi" instruction. As a result, the
+local timer interrupt is not fired.
+ In this situation, this CPU will wake up by IRQ different from local
+timer. (e.g. broacast timer)
+
+So, this fix changes CPU to return to 'WAIT_CLOCKED'.
+
+Signed-off-by: Kohji Okuno <okuno.kohji@jp.panasonic.com>
+Fixes: e5f9dec8ff5f ("ARM: imx6q: support WAIT mode using cpuidle")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/mach-imx/cpuidle-imx6q.c | 27 ++++++++++-----------------
+ 1 file changed, 10 insertions(+), 17 deletions(-)
+
+diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c
+index bfeb25aaf9a2..326e870d7123 100644
+--- a/arch/arm/mach-imx/cpuidle-imx6q.c
++++ b/arch/arm/mach-imx/cpuidle-imx6q.c
+@@ -16,30 +16,23 @@
+ #include "cpuidle.h"
+ #include "hardware.h"
+
+-static atomic_t master = ATOMIC_INIT(0);
+-static DEFINE_SPINLOCK(master_lock);
++static int num_idle_cpus = 0;
++static DEFINE_SPINLOCK(cpuidle_lock);
+
+ static int imx6q_enter_wait(struct cpuidle_device *dev,
+ struct cpuidle_driver *drv, int index)
+ {
+- if (atomic_inc_return(&master) == num_online_cpus()) {
+- /*
+- * With this lock, we prevent other cpu to exit and enter
+- * this function again and become the master.
+- */
+- if (!spin_trylock(&master_lock))
+- goto idle;
++ spin_lock(&cpuidle_lock);
++ if (++num_idle_cpus == num_online_cpus())
+ imx6_set_lpm(WAIT_UNCLOCKED);
+- cpu_do_idle();
+- imx6_set_lpm(WAIT_CLOCKED);
+- spin_unlock(&master_lock);
+- goto done;
+- }
++ spin_unlock(&cpuidle_lock);
+
+-idle:
+ cpu_do_idle();
+-done:
+- atomic_dec(&master);
++
++ spin_lock(&cpuidle_lock);
++ if (num_idle_cpus-- == num_online_cpus())
++ imx6_set_lpm(WAIT_CLOCKED);
++ spin_unlock(&cpuidle_lock);
+
+ return index;
+ }
+--
+2.16.4
+
diff --git a/patches.arch/ARM-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch b/patches.arch/ARM-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch
new file mode 100644
index 0000000000..6dd365306a
--- /dev/null
+++ b/patches.arch/ARM-pxa-ssp-unneeded-to-free-devm_-allocated-data.patch
@@ -0,0 +1,46 @@
+From ba16adeb346387eb2d1ada69003588be96f098fa Mon Sep 17 00:00:00 2001
+From: Peng Hao <peng.hao2@zte.com.cn>
+Date: Sat, 29 Dec 2018 13:10:06 +0800
+Subject: [PATCH] ARM: pxa: ssp: unneeded to free devm_ allocated data
+Git-commit: ba16adeb346387eb2d1ada69003588be96f098fa
+Patch-mainline: v5.0-rc6
+References: bsc#1051510
+
+devm_ allocated data will be automatically freed. The free
+of devm_ allocated data is invalid.
+
+Fixes: 1c459de1e645 ("ARM: pxa: ssp: use devm_ functions")
+Signed-off-by: Peng Hao <peng.hao2@zte.com.cn>
+[title's prefix changed]
+
+Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/plat-pxa/ssp.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/arch/arm/plat-pxa/ssp.c b/arch/arm/plat-pxa/ssp.c
+index ed36dcab80f1..f51919974183 100644
+--- a/arch/arm/plat-pxa/ssp.c
++++ b/arch/arm/plat-pxa/ssp.c
+@@ -190,8 +190,6 @@ static int pxa_ssp_remove(struct platform_device *pdev)
+ if (ssp == NULL)
+ return -ENODEV;
+
+- iounmap(ssp->mmio_base);
+-
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(res->start, resource_size(res));
+
+@@ -201,7 +199,6 @@ static int pxa_ssp_remove(struct platform_device *pdev)
+ list_del(&ssp->node);
+ mutex_unlock(&ssp_lock);
+
+- kfree(ssp);
+ return 0;
+ }
+
+--
+2.16.4
+
diff --git a/patches.arch/ARM-s3c24xx-Fix-boolean-expressions-in-osiris_dvs_no.patch b/patches.arch/ARM-s3c24xx-Fix-boolean-expressions-in-osiris_dvs_no.patch
new file mode 100644
index 0000000000..64795704fa
--- /dev/null
+++ b/patches.arch/ARM-s3c24xx-Fix-boolean-expressions-in-osiris_dvs_no.patch
@@ -0,0 +1,52 @@
+From e2477233145f2156434afb799583bccd878f3e9f Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Thu, 3 Jan 2019 14:14:08 -0600
+Subject: [PATCH] ARM: s3c24xx: Fix boolean expressions in osiris_dvs_notify
+Git-commit: e2477233145f2156434afb799583bccd878f3e9f
+Patch-mainline: v5.1-rc1
+References: bsc#1051510
+
+Fix boolean expressions by using logical AND operator '&&' instead of
+bitwise operator '&'.
+
+This issue was detected with the help of Coccinelle.
+
+Fixes: 4fa084af28ca ("ARM: OSIRIS: DVS (Dynamic Voltage Scaling) supoort.")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+[krzk: Fix -Wparentheses warning]
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/mach-s3c24xx/mach-osiris-dvs.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c
+index 058ce73137e8..5d819b6ea428 100644
+--- a/arch/arm/mach-s3c24xx/mach-osiris-dvs.c
++++ b/arch/arm/mach-s3c24xx/mach-osiris-dvs.c
+@@ -65,16 +65,16 @@ static int osiris_dvs_notify(struct notifier_block *nb,
+
+ switch (val) {
+ case CPUFREQ_PRECHANGE:
+- if (old_dvs & !new_dvs ||
+- cur_dvs & !new_dvs) {
++ if ((old_dvs && !new_dvs) ||
++ (cur_dvs && !new_dvs)) {
+ pr_debug("%s: exiting dvs\n", __func__);
+ cur_dvs = false;
+ gpio_set_value(OSIRIS_GPIO_DVS, 1);
+ }
+ break;
+ case CPUFREQ_POSTCHANGE:
+- if (!old_dvs & new_dvs ||
+- !cur_dvs & new_dvs) {
++ if ((!old_dvs && new_dvs) ||
++ (!cur_dvs && new_dvs)) {
+ pr_debug("entering dvs\n");
+ cur_dvs = true;
+ gpio_set_value(OSIRIS_GPIO_DVS, 0);
+--
+2.16.4
+
diff --git a/patches.arch/ARM-samsung-Limit-SAMSUNG_PM_CHECK-config-option-to-.patch b/patches.arch/ARM-samsung-Limit-SAMSUNG_PM_CHECK-config-option-to-.patch
new file mode 100644
index 0000000000..5329980ef9
--- /dev/null
+++ b/patches.arch/ARM-samsung-Limit-SAMSUNG_PM_CHECK-config-option-to-.patch
@@ -0,0 +1,60 @@
+From 6862fdf2201ab67cd962dbf0643d37db909f4860 Mon Sep 17 00:00:00 2001
+From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Date: Fri, 28 Sep 2018 15:32:46 +0200
+Subject: [PATCH] ARM: samsung: Limit SAMSUNG_PM_CHECK config option to non-Exynos platforms
+Git-commit: 6862fdf2201ab67cd962dbf0643d37db909f4860
+Patch-mainline: v4.20-rc1
+References: bsc#1051510
+
+"S3C2410 PM Suspend Memory CRC" feature (controlled by
+SAMSUNG_PM_CHECK config option) is incompatible with highmem
+(uses phys_to_virt() instead of proper mapping) which is used by
+the majority of Exynos boards. The issue manifests itself in OOPS
+on affected boards, i.e. on Odroid-U3 I got the following one:
+
+Unable to handle kernel paging request at virtual address f0000000
+pgd = 1c0f9bb4
+[f0000000] *pgd=00000000
+Internal error: Oops: 5 [#1] PREEMPT SMP ARM
+[<c0458034>] (crc32_le) from [<c0121f8c>] (s3c_pm_makecheck+0x34/0x54)
+[<c0121f8c>] (s3c_pm_makecheck) from [<c0121efc>] (s3c_pm_run_res+0x74/0x8c)
+[<c0121efc>] (s3c_pm_run_res) from [<c0121ecc>] (s3c_pm_run_res+0x44/0x8c)
+[<c0121ecc>] (s3c_pm_run_res) from [<c01210b8>] (exynos_suspend_enter+0x64/0x148)
+[<c01210b8>] (exynos_suspend_enter) from [<c018893c>] (suspend_devices_and_enter+0x9ec/0xe74)
+[<c018893c>] (suspend_devices_and_enter) from [<c0189534>] (pm_suspend+0x770/0xc04)
+[<c0189534>] (pm_suspend) from [<c0186ce8>] (state_store+0x6c/0xcc)
+[<c0186ce8>] (state_store) from [<c09db434>] (kobj_attr_store+0x14/0x20)
+[<c09db434>] (kobj_attr_store) from [<c02fa63c>] (sysfs_kf_write+0x4c/0x50)
+[<c02fa63c>] (sysfs_kf_write) from [<c02f97a4>] (kernfs_fop_write+0xfc/0x1e4)
+[<c02f97a4>] (kernfs_fop_write) from [<c027b198>] (__vfs_write+0x2c/0x140)
+[<c027b198>] (__vfs_write) from [<c027b418>] (vfs_write+0xa4/0x160)
+[<c027b418>] (vfs_write) from [<c027b5d8>] (ksys_write+0x40/0x8c)
+[<c027b5d8>] (ksys_write) from [<c0101000>] (ret_fast_syscall+0x0/0x28)
+
+Add PLAT_S3C24XX, ARCH_S3C64XX and ARCH_S5PV210 dependencies to
+SAMSUNG_PM_CHECK config option to hide it on Exynos platforms.
+
+Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ arch/arm/plat-samsung/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
+index b600e38364eb..377ff9cda667 100644
+--- a/arch/arm/plat-samsung/Kconfig
++++ b/arch/arm/plat-samsung/Kconfig
+@@ -256,7 +256,7 @@ config S3C_PM_DEBUG_LED_SMDK
+
+ config SAMSUNG_PM_CHECK
+ bool "S3C2410 PM Suspend Memory CRC"
+- depends on PM
++ depends on PM && (PLAT_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210)
+ select CRC32
+ help
+ Enable the PM code's memory area checksum over sleep. This option
+--
+2.16.4
+
diff --git a/patches.arch/acpi-add-hygon-dhyana-support.patch b/patches.arch/acpi-add-hygon-dhyana-support.patch
new file mode 100644
index 0000000000..63485b51f6
--- /dev/null
+++ b/patches.arch/acpi-add-hygon-dhyana-support.patch
@@ -0,0 +1,48 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:37:05 +0800
+Subject: ACPI: Add Hygon Dhyana support
+Git-commit: 7377ed4bd56e6cc1ddbb63f03626fc5b92d3d6fe
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The Hygon Dhyana CPU has NONSTOP TSC feature, so enable the ACPI driver
+support to it.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: rjw@rjwysocki.net
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Cc: lenb@kernel.org
+Cc: rafael@kernel.org
+Cc: linux-acpi@vger.kernel.org
+Link: https://lkml.kernel.org/r/cce6ee26f4e2ebbab493433264d89d7cea661284.1537533369.git.puwen@hygon.cn
+---
+ drivers/acpi/acpi_pad.c | 1 +
+ drivers/acpi/processor_idle.c | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/acpi/acpi_pad.c
++++ b/drivers/acpi/acpi_pad.c
+@@ -70,6 +70,7 @@ static void power_saving_mwait_init(void
+
+ #if defined(CONFIG_X86)
+ switch (boot_cpu_data.x86_vendor) {
++ case X86_VENDOR_HYGON:
+ case X86_VENDOR_AMD:
+ case X86_VENDOR_INTEL:
+ /*
+--- a/drivers/acpi/processor_idle.c
++++ b/drivers/acpi/processor_idle.c
+@@ -203,6 +203,7 @@ static void lapic_timer_state_broadcast(
+ static void tsc_check_state(int state)
+ {
+ switch (boot_cpu_data.x86_vendor) {
++ case X86_VENDOR_HYGON:
+ case X86_VENDOR_AMD:
+ case X86_VENDOR_INTEL:
+ /*
diff --git a/patches.arch/cpufreq-add-hygon-dhyana-support.patch b/patches.arch/cpufreq-add-hygon-dhyana-support.patch
new file mode 100644
index 0000000000..664f59219f
--- /dev/null
+++ b/patches.arch/cpufreq-add-hygon-dhyana-support.patch
@@ -0,0 +1,91 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:37:38 +0800
+Subject: cpufreq: Add Hygon Dhyana support
+Git-commit: cc9690cfc7a36873b219d569049e10f073dd22e4
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The Hygon Dhyana CPU supports ACPI P-States, and there is SMBus device
+(PCI device ID 0x790b) on the Hygon platform. Add Hygon Dhyana support
+to the cpufreq driver by using the code path of AMD family 17h.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Cc: rjw@rjwysocki.net
+Cc: viresh.kumar@linaro.org
+Cc: bp@alien8.de
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Cc: rafael@kernel.org
+Cc: linux-pm@vger.kernel.org
+Link: https://lkml.kernel.org/r/4db6f0f8537a93c172430c446a0297a6ab1c3c2d.1537533369.git.puwen@hygon.cn
+---
+ drivers/cpufreq/acpi-cpufreq.c | 5 +++++
+ drivers/cpufreq/amd_freq_sensitivity.c | 9 +++++++--
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
+index b61f4ec43e06..d62fd374d5c7 100644
+--- a/drivers/cpufreq/acpi-cpufreq.c
++++ b/drivers/cpufreq/acpi-cpufreq.c
+@@ -61,6 +61,7 @@ enum {
+
+ #define INTEL_MSR_RANGE (0xffff)
+ #define AMD_MSR_RANGE (0x7)
++#define HYGON_MSR_RANGE (0x7)
+
+ #define MSR_K7_HWCR_CPB_DIS (1ULL << 25)
+
+@@ -95,6 +96,7 @@ static bool boost_state(unsigned int cpu)
+ rdmsr_on_cpu(cpu, MSR_IA32_MISC_ENABLE, &lo, &hi);
+ msr = lo | ((u64)hi << 32);
+ return !(msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE);
++ case X86_VENDOR_HYGON:
+ case X86_VENDOR_AMD:
+ rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+ msr = lo | ((u64)hi << 32);
+@@ -113,6 +115,7 @@ static int boost_set_msr(bool enable)
+ msr_addr = MSR_IA32_MISC_ENABLE;
+ msr_mask = MSR_IA32_MISC_ENABLE_TURBO_DISABLE;
+ break;
++ case X86_VENDOR_HYGON:
+ case X86_VENDOR_AMD:
+ msr_addr = MSR_K7_HWCR;
+ msr_mask = MSR_K7_HWCR_CPB_DIS;
+@@ -225,6 +228,8 @@ static unsigned extract_msr(struct cpufreq_policy *policy, u32 msr)
+
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ msr &= AMD_MSR_RANGE;
++ else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
++ msr &= HYGON_MSR_RANGE;
+ else
+ msr &= INTEL_MSR_RANGE;
+
+diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
+index be926d9a66e5..4ac7c3cf34be 100644
+--- a/drivers/cpufreq/amd_freq_sensitivity.c
++++ b/drivers/cpufreq/amd_freq_sensitivity.c
+@@ -111,11 +111,16 @@ static int __init amd_freq_sensitivity_init(void)
+ {
+ u64 val;
+ struct pci_dev *pcidev;
++ unsigned int pci_vendor;
+
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
++ pci_vendor = PCI_VENDOR_ID_AMD;
++ else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
++ pci_vendor = PCI_VENDOR_ID_HYGON;
++ else
+ return -ENODEV;
+
+- pcidev = pci_get_device(PCI_VENDOR_ID_AMD,
++ pcidev = pci_get_device(pci_vendor,
+ PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, NULL);
+
+ if (!pcidev) {
+
diff --git a/patches.arch/cpufreq-amd-ignore-the-check-for-procfeedback-in-st-cz.patch b/patches.arch/cpufreq-amd-ignore-the-check-for-procfeedback-in-st-cz.patch
new file mode 100644
index 0000000000..57f06dc96c
--- /dev/null
+++ b/patches.arch/cpufreq-amd-ignore-the-check-for-procfeedback-in-st-cz.patch
@@ -0,0 +1,52 @@
+From: Akshu Agrawal <Akshu.Agrawal@amd.com>
+Date: Thu, 18 Jan 2018 15:51:30 +0530
+Subject: cpufreq: AMD: Ignore the check for ProcFeedback in ST/CZ
+Git-commit: 59a3b3a8db16621574cbac69f6f1eddb9c60e821
+Patch-mainline: v4.16-rc1
+References: fate#327735
+
+In ST/CZ CPUID 8000_0007_EDX[11, ProcFeedbackInterface] is 0,
+but the mechanism is still available and can be used.
+
+Signed-off-by: Akshu Agrawal <akshu.agrawal@amd.com>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Borislav Petkov <bp@suse.de>
+---
+ drivers/cpufreq/amd_freq_sensitivity.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/cpufreq/amd_freq_sensitivity.c b/drivers/cpufreq/amd_freq_sensitivity.c
+index 042023bbbf62..be926d9a66e5 100644
+--- a/drivers/cpufreq/amd_freq_sensitivity.c
++++ b/drivers/cpufreq/amd_freq_sensitivity.c
+@@ -14,6 +14,7 @@
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ #include <linux/types.h>
++#include <linux/pci.h>
+ #include <linux/percpu-defs.h>
+ #include <linux/init.h>
+ #include <linux/mod_devicetable.h>
+@@ -109,12 +110,18 @@ static unsigned int amd_powersave_bias_target(struct cpufreq_policy *policy,
+ static int __init amd_freq_sensitivity_init(void)
+ {
+ u64 val;
++ struct pci_dev *pcidev;
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
+ return -ENODEV;
+
+- if (!static_cpu_has(X86_FEATURE_PROC_FEEDBACK))
+- return -ENODEV;
++ pcidev = pci_get_device(PCI_VENDOR_ID_AMD,
++ PCI_DEVICE_ID_AMD_KERNCZ_SMBUS, NULL);
++
++ if (!pcidev) {
++ if (!static_cpu_has(X86_FEATURE_PROC_FEEDBACK))
++ return -ENODEV;
++ }
+
+ if (rdmsrl_safe(MSR_AMD64_FREQ_SENSITIVITY_ACTUAL, &val))
+ return -ENODEV;
+
diff --git a/patches.arch/edac-amd64-add-hygon-dhyana-support.patch b/patches.arch/edac-amd64-add-hygon-dhyana-support.patch
new file mode 100644
index 0000000000..71a84f2531
--- /dev/null
+++ b/patches.arch/edac-amd64-add-hygon-dhyana-support.patch
@@ -0,0 +1,92 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Thu, 27 Sep 2018 16:31:28 +0200
+Subject: EDAC, amd64: Add Hygon Dhyana support
+Git-commit: c4a3e94641449362ee970f521a2cdb0e8cd08690
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+Add support for Hygon Dhyana CPU to EDAC.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: mchehab@kernel.org
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: thomas.lendacky@amd.com
+Cc: linux-edac@vger.kernel.org
+Link: https://lkml.kernel.org/r/9d71061301177822bc55b3bfd44f91057458d886.1537533369.git.puwen@hygon.cn
+---
+ drivers/edac/amd64_edac.c | 10 +++++++++-
+ drivers/edac/mce_amd.c | 4 +++-
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/edac/amd64_edac.c
++++ b/drivers/edac/amd64_edac.c
+@@ -211,7 +211,7 @@ static int __set_scrub_rate(struct amd64
+
+ scrubval = scrubrates[i].scrubval;
+
+- if (pvt->fam == 0x17) {
++ if (pvt->fam == 0x17 || pvt->fam == 0x18) {
+ __f17h_set_scrubval(pvt, scrubval);
+ } else if (pvt->fam == 0x15 && pvt->model == 0x60) {
+ f15h_select_dct(pvt, 0);
+@@ -264,6 +264,7 @@ static int get_scrub_rate(struct mem_ctl
+ break;
+
+ case 0x17:
++ case 0x18:
+ amd64_read_pci_cfg(pvt->F6, F17H_SCR_BASE_ADDR, &scrubval);
+ if (scrubval & BIT(0)) {
+ amd64_read_pci_cfg(pvt->F6, F17H_SCR_LIMIT_ADDR, &scrubval);
+@@ -1044,6 +1045,7 @@ static void determine_memory_type(struct
+ goto ddr3;
+
+ case 0x17:
++ case 0x18:
+ if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(5))
+ pvt->dram_type = MEM_LRDDR4;
+ else if ((pvt->umc[0].dimm_cfg | pvt->umc[1].dimm_cfg) & BIT(4))
+@@ -3189,8 +3191,13 @@ static struct amd64_family_type *per_fam
+ break;
+
+ case 0x17:
++ /* fall through */
++ case 0x18:
+ fam_type = &family_types[F17_CPUS];
+ pvt->ops = &family_types[F17_CPUS].ops;
++
++ if (pvt->fam == 0x18)
++ family_types[F17_CPUS].ctl_name = "F18h";
+ break;
+
+ default:
+@@ -3429,6 +3436,7 @@ static const struct x86_cpu_id amd64_cpu
+ { X86_VENDOR_AMD, 0x15, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
+ { X86_VENDOR_AMD, 0x16, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
+ { X86_VENDOR_AMD, 0x17, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
++ { X86_VENDOR_HYGON, 0x18, X86_MODEL_ANY, X86_FEATURE_ANY, 0 },
+ { }
+ };
+ MODULE_DEVICE_TABLE(x86cpu, amd64_cpuids);
+--- a/drivers/edac/mce_amd.c
++++ b/drivers/edac/mce_amd.c
+@@ -1063,7 +1063,8 @@ static int __init mce_amd_init(void)
+ {
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+
+- if (c->x86_vendor != X86_VENDOR_AMD)
++ if (c->x86_vendor != X86_VENDOR_AMD &&
++ c->x86_vendor != X86_VENDOR_HYGON)
+ return -ENODEV;
+
+ fam_ops = kzalloc(sizeof(struct amd_decoder_ops), GFP_KERNEL);
+@@ -1117,6 +1118,7 @@ static int __init mce_amd_init(void)
+ break;
+
+ case 0x17:
++ case 0x18:
+ xec_mask = 0x3f;
+ if (!boot_cpu_has(X86_FEATURE_SMCA)) {
+ printk(KERN_WARNING "Decoding supported only on Scalable MCA processors.\n");
diff --git a/patches.arch/perf-tools-add-hygon-dhyana-support.patch b/patches.arch/perf-tools-add-hygon-dhyana-support.patch
new file mode 100644
index 0000000000..7234edbfe0
--- /dev/null
+++ b/patches.arch/perf-tools-add-hygon-dhyana-support.patch
@@ -0,0 +1,39 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Mon, 12 Nov 2018 15:40:51 +0800
+Subject: perf tools: Add Hygon Dhyana support
+Git-commit: 4787eff3fa88f62fede6ed7afa06477ae6bf984d
+Patch-mainline: v5.0-rc1
+References: fate#327735
+
+The tool perf is useful for the performance analysis on the Hygon Dhyana
+platform. But right now there is no Hygon support for it to analyze the
+KVM guest os data. So add Hygon Dhyana support to it by checking vendor
+string to share the code path of AMD.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Acked-by: Borislav Petkov <bp@suse.de>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/1542008451-31735-1-git-send-email-puwen@hygon.cn
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+---
+ tools/perf/arch/x86/util/kvm-stat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/arch/x86/util/kvm-stat.c
+index b32409a0e546..081353d7b095 100644
+--- a/tools/perf/arch/x86/util/kvm-stat.c
++++ b/tools/perf/arch/x86/util/kvm-stat.c
+@@ -156,7 +156,7 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
+ if (strstr(cpuid, "Intel")) {
+ kvm->exit_reasons = vmx_exit_reasons;
+ kvm->exit_reasons_isa = "VMX";
+- } else if (strstr(cpuid, "AMD")) {
++ } else if (strstr(cpuid, "AMD") || strstr(cpuid, "Hygon")) {
+ kvm->exit_reasons = svm_exit_reasons;
+ kvm->exit_reasons_isa = "SVM";
+ } else
+
diff --git a/patches.arch/s390-qdio-clear-intparm-during-shutdown b/patches.arch/s390-qdio-clear-intparm-during-shutdown
new file mode 100644
index 0000000000..85101f7cda
--- /dev/null
+++ b/patches.arch/s390-qdio-clear-intparm-during-shutdown
@@ -0,0 +1,44 @@
+From: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Date: Wed, 21 Mar 2018 17:14:00 +0100
+Subject: s390/qdio: clear intparm during shutdown
+Git-commit: 89286320a236d245834075fa13adb0bdd827ecaa
+Patch-mainline: v4.17-rc1
+References: bsc#1134597 bsc#1134600 LTC#177516 LTC#177517
+
+During shutdown, qdio returns its ccw device back to control by the
+upper-layer driver. But there is a remote chance that by the time where the
+IRQ handler gets switched back, the interrupt for the preceding
+ccw_device_{clear,halt} hasn't been presented yet.
+Upper-layer drivers would then need to handle this IRQ - and since the IO
+is issued with an intparm, it could very well be confused with whatever
+intparm mechanism the driver uses itself (eg intparm == request address).
+
+So when switching over the IRQ handler, also clear the intparm and have
+upper-layer drivers deal with any such delayed interrupt as if it was
+unsolicited.
+
+Suggested-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
+Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
+Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
+Acked-by: Petr Tesarik <ptesarik@suse.com>
+---
+ drivers/s390/cio/qdio_main.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
+index a337281337a7..f4ca72dd862f 100644
+--- a/drivers/s390/cio/qdio_main.c
++++ b/drivers/s390/cio/qdio_main.c
+@@ -1207,8 +1207,10 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
+ qdio_shutdown_thinint(irq_ptr);
+
+ /* restore interrupt handler */
+- if ((void *)cdev->handler == (void *)qdio_int_handler)
++ if ((void *)cdev->handler == (void *)qdio_int_handler) {
+ cdev->handler = irq_ptr->orig_handler;
++ cdev->private->intparm = 0;
++ }
+ spin_unlock_irq(get_ccwdev_lock(cdev));
+
+ qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
+
diff --git a/patches.arch/tools-cpupower-add-hygon-dhyana-support.patch b/patches.arch/tools-cpupower-add-hygon-dhyana-support.patch
new file mode 100644
index 0000000000..2509caa3f4
--- /dev/null
+++ b/patches.arch/tools-cpupower-add-hygon-dhyana-support.patch
@@ -0,0 +1,115 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Thu, 4 Oct 2018 09:21:43 +0800
+Subject: tools/cpupower: Add Hygon Dhyana support
+Git-commit: 995d5f64b62f20f05b8e0972f07ec4d6c23333c9
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The tool cpupower is useful to get CPU frequency information and monitor
+power stats on the Hygon Dhyana platform. So add Hygon Dhyana support to
+it by checking vendor and family to share the code path of AMD family
+17h.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
+CC: Prarit Bhargava <prarit@redhat.com>
+CC: Shuah Khan <shuah@kernel.org>
+CC: Thomas Gleixner <tglx@linutronix.de>
+CC: Thomas Renninger <trenn@suse.com>
+CC: linux-pm@vger.kernel.org
+Link: http://lkml.kernel.org/r/5ce86123a7b9dad925ac583d88d2f921040e859b.1538583282.git.puwen@hygon.cn
+---
+ tools/power/cpupower/utils/cpufreq-info.c | 6 ++++--
+ tools/power/cpupower/utils/helpers/amd.c | 1 -
+ tools/power/cpupower/utils/helpers/cpuid.c | 8 +++++---
+ tools/power/cpupower/utils/helpers/helpers.h | 2 +-
+ tools/power/cpupower/utils/idle_monitor/mperf_monitor.c | 3 ++-
+ 5 files changed, 12 insertions(+), 8 deletions(-)
+
+--- a/tools/power/cpupower/utils/cpufreq-info.c
++++ b/tools/power/cpupower/utils/cpufreq-info.c
+@@ -172,6 +172,7 @@ static int get_boost_mode(unsigned int c
+ unsigned long pstates[MAX_HW_PSTATES] = {0,};
+
+ if (cpupower_cpu_info.vendor != X86_VENDOR_AMD &&
++ cpupower_cpu_info.vendor != X86_VENDOR_HYGON &&
+ cpupower_cpu_info.vendor != X86_VENDOR_INTEL)
+ return 0;
+
+@@ -192,8 +193,9 @@ static int get_boost_mode(unsigned int c
+ printf(_(" Supported: %s\n"), support ? _("yes") : _("no"));
+ printf(_(" Active: %s\n"), active ? _("yes") : _("no"));
+
+- if (cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
+- cpupower_cpu_info.family >= 0x10) {
++ if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD &&
++ cpupower_cpu_info.family >= 0x10) ||
++ cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
+ ret = decode_pstates(cpu, cpupower_cpu_info.family, b_states,
+ pstates, &pstate_no);
+ if (ret)
+--- a/tools/power/cpupower/utils/helpers/amd.c
++++ b/tools/power/cpupower/utils/helpers/amd.c
+@@ -47,7 +47,6 @@ static int get_cof(int family, union msr
+ int fid, did;
+
+ did = get_did(family, pstate);
+-
+ t = 0x10;
+ fid = pstate.bits.fid;
+ if (family == 0x11)
+--- a/tools/power/cpupower/utils/helpers/cpuid.c
++++ b/tools/power/cpupower/utils/helpers/cpuid.c
+@@ -7,7 +7,7 @@
+ #include "helpers/helpers.h"
+
+ static const char *cpu_vendor_table[X86_VENDOR_MAX] = {
+- "Unknown", "GenuineIntel", "AuthenticAMD",
++ "Unknown", "GenuineIntel", "AuthenticAMD", "HygonGenuine",
+ };
+
+ #if defined(__i386__) || defined(__x86_64__)
+@@ -108,6 +108,7 @@ out:
+ fclose(fp);
+ /* Get some useful CPU capabilities from cpuid */
+ if (cpu_info->vendor != X86_VENDOR_AMD &&
++ cpu_info->vendor != X86_VENDOR_HYGON &&
+ cpu_info->vendor != X86_VENDOR_INTEL)
+ return ret;
+
+@@ -123,8 +124,9 @@ out:
+ if (cpuid_level >= 6 && (cpuid_ecx(6) & 0x1))
+ cpu_info->caps |= CPUPOWER_CAP_APERF;
+
+- /* AMD Boost state enable/disable register */
+- if (cpu_info->vendor == X86_VENDOR_AMD) {
++ /* AMD or Hygon Boost state enable/disable register */
++ if (cpu_info->vendor == X86_VENDOR_AMD ||
++ cpu_info->vendor == X86_VENDOR_HYGON) {
+ if (ext_cpuid_level >= 0x80000007 &&
+ (cpuid_edx(0x80000007) & (1 << 9)))
+ cpu_info->caps |= CPUPOWER_CAP_AMD_CBP;
+--- a/tools/power/cpupower/utils/helpers/helpers.h
++++ b/tools/power/cpupower/utils/helpers/helpers.h
+@@ -60,7 +60,7 @@ extern int be_verbose;
+
+ /* cpuid and cpuinfo helpers **************************/
+ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
+- X86_VENDOR_AMD, X86_VENDOR_MAX};
++ X86_VENDOR_AMD, X86_VENDOR_HYGON, X86_VENDOR_MAX};
+
+ #define CPUPOWER_CAP_INV_TSC 0x00000001
+ #define CPUPOWER_CAP_APERF 0x00000002
+--- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
++++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c
+@@ -240,7 +240,8 @@ static int init_maxfreq_mode(void)
+ if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC))
+ goto use_sysfs;
+
+- if (cpupower_cpu_info.vendor == X86_VENDOR_AMD) {
++ if (cpupower_cpu_info.vendor == X86_VENDOR_AMD ||
++ cpupower_cpu_info.vendor == X86_VENDOR_HYGON) {
+ /* MSR_AMD_HWCR tells us whether TSC runs at P0/mperf
+ * freq.
+ * A test whether hwcr is accessable/available would be:
diff --git a/patches.arch/x86-alternative-init-ideal_nops-for-hygon-dhyana.patch b/patches.arch/x86-alternative-init-ideal_nops-for-hygon-dhyana.patch
new file mode 100644
index 0000000000..8fb352f8b7
--- /dev/null
+++ b/patches.arch/x86-alternative-init-ideal_nops-for-hygon-dhyana.patch
@@ -0,0 +1,38 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:35:01 +0800
+Subject: x86/alternative: Init ideal_nops for Hygon Dhyana
+Git-commit: c3fecca457c1aa1c1a2f81bfe68393af244a263e
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The ideal_nops for Hygon Dhyana CPU should be p6_nops.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/79e76c3173716984fe5fdd4a8e2c798bf4193205.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/kernel/alternative.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
+index b9d5e7c9ef43..184e9a06b0ff 100644
+--- a/arch/x86/kernel/alternative.c
++++ b/arch/x86/kernel/alternative.c
+@@ -222,6 +222,10 @@ void __init arch_init_ideal_nops(void)
+ }
+ break;
+
++ case X86_VENDOR_HYGON:
++ ideal_nops = p6_nops;
++ return;
++
+ case X86_VENDOR_AMD:
+ if (boot_cpu_data.x86 > 0xf) {
+ ideal_nops = p6_nops;
+
diff --git a/patches.arch/x86-amd_nb-add-support-for-newer-pci-topologies.patch b/patches.arch/x86-amd_nb-add-support-for-newer-pci-topologies.patch
index b0284bd6db..400d7c2819 100644
--- a/patches.arch/x86-amd_nb-add-support-for-newer-pci-topologies.patch
+++ b/patches.arch/x86-amd_nb-add-support-for-newer-pci-topologies.patch
@@ -46,13 +46,11 @@ Link: http://lkml.kernel.org/r/20181106200754.60722-3-brian.woods@amd.com
--- a/arch/x86/kernel/amd_nb.c
+++ b/arch/x86/kernel/amd_nb.c
-@@ -188,35 +188,67 @@ EXPORT_SYMBOL_GPL(amd_df_indirect_read);
-
- int amd_cache_northbridges(void)
- {
-- u16 i = 0;
- struct amd_northbridge *nb;
+@@ -208,7 +208,10 @@ int amd_cache_northbridges(void)
+ const struct pci_device_id *root_ids = amd_root_ids;
struct pci_dev *root, *misc, *link;
+ struct amd_northbridge *nb;
+- u16 i = 0;
+ u16 roots_per_misc = 0;
+ u16 misc_count = 0;
+ u16 root_count = 0;
@@ -60,9 +58,10 @@ Link: http://lkml.kernel.org/r/20181106200754.60722-3-brian.woods@amd.com
if (amd_northbridges.num)
return 0;
+@@ -221,26 +224,55 @@ int amd_cache_northbridges(void)
misc = NULL;
- while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
+ while ((misc = next_northbridge(misc, misc_ids)) != NULL)
- i++;
+ misc_count++;
@@ -100,11 +99,11 @@ Link: http://lkml.kernel.org/r/20181106200754.60722-3-brian.woods@amd.com
- for (i = 0; i != amd_northbridges.num; i++) {
+ for (i = 0; i < amd_northbridges.num; i++) {
node_to_amd_nb(i)->root = root =
- next_northbridge(root, amd_root_ids);
+ next_northbridge(root, root_ids);
node_to_amd_nb(i)->misc = misc =
- next_northbridge(misc, amd_nb_misc_ids);
+ next_northbridge(misc, misc_ids);
node_to_amd_nb(i)->link = link =
- next_northbridge(link, amd_nb_link_ids);
+ next_northbridge(link, link_ids);
+
+ /*
+ * If there are more PCI root devices than data fabric/
diff --git a/patches.arch/x86-amd_nb-check-vendor-in-amd-only-functions.patch b/patches.arch/x86-amd_nb-check-vendor-in-amd-only-functions.patch
new file mode 100644
index 0000000000..da871463ab
--- /dev/null
+++ b/patches.arch/x86-amd_nb-check-vendor-in-amd-only-functions.patch
@@ -0,0 +1,57 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Tue, 25 Sep 2018 22:45:01 +0800
+Subject: x86/amd_nb: Check vendor in AMD-only functions
+Git-commit: b7a5cb4f220e78490735b2b984ad29b7d8e612a9
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+Exit early in functions which are meant to run on AMD only but which get
+run on different vendor (VMs, etc).
+
+ [ bp: rewrite commit message. ]
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: bhelgaas@google.com
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Cc: helgaas@kernel.org
+Link: https://lkml.kernel.org/r/487d8078708baedaf63eb00a82251e228b58f1c2.1537885177.git.puwen@hygon.cn
+---
+ arch/x86/include/asm/amd_nb.h | 3 +++
+ arch/x86/kernel/amd_nb.c | 4 ++++
+ 2 files changed, 7 insertions(+)
+
+diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h
+index fddb6d26239f..1ae4e5791afa 100644
+--- a/arch/x86/include/asm/amd_nb.h
++++ b/arch/x86/include/asm/amd_nb.h
+@@ -103,6 +103,9 @@ static inline u16 amd_pci_dev_to_node_id(struct pci_dev *pdev)
+
+ static inline bool amd_gart_present(void)
+ {
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
++ return false;
++
+ /* GART present only on Fam15h, upto model 0fh */
+ if (boot_cpu_data.x86 == 0xf || boot_cpu_data.x86 == 0x10 ||
+ (boot_cpu_data.x86 == 0x15 && boot_cpu_data.x86_model < 0x10))
+diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
+index b481b95bd8f6..b51c6b183a35 100644
+--- a/arch/x86/kernel/amd_nb.c
++++ b/arch/x86/kernel/amd_nb.c
+@@ -264,6 +264,10 @@ bool __init early_is_amd_nb(u32 device)
+ const struct pci_device_id *id;
+ u32 vendor = device & 0xffff;
+
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
++ return false;
++
+ device >>= 16;
+ for (id = amd_nb_misc_ids; id->vendor; id++)
+ if (vendor == id->vendor && device == id->device)
+
diff --git a/patches.arch/x86-apic-add-hygon-dhyana-support.patch b/patches.arch/x86-apic-add-hygon-dhyana-support.patch
new file mode 100644
index 0000000000..2941f5619c
--- /dev/null
+++ b/patches.arch/x86-apic-add-hygon-dhyana-support.patch
@@ -0,0 +1,62 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:35:28 +0800
+Subject: x86/apic: Add Hygon Dhyana support
+Git-commit: da33dfef404174b0b452f4d2a9a9e00801794f3a
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+Add Hygon Dhyana support to the APIC subsystem. When running in 32 bit
+mode, bigsmp should be enabled if there are more than 8 cores online.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/7a557265a8c7c9e842fe60f9d8e064458801aef3.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/kernel/apic/apic.c | 7 +++++++
+ arch/x86/kernel/apic/probe_32.c | 1 +
+ 2 files changed, 8 insertions(+)
+
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index 84132eddb5a8..ab731ab09f06 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -224,6 +224,11 @@ static int modern_apic(void)
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+ boot_cpu_data.x86 >= 0xf)
+ return 1;
++
++ /* Hygon systems use modern APIC */
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
++ return 1;
++
+ return lapic_get_version() >= 0x14;
+ }
+
+@@ -1912,6 +1917,8 @@ static int __init detect_init_APIC(void)
+ (boot_cpu_data.x86 >= 15))
+ break;
+ goto no_apic;
++ case X86_VENDOR_HYGON:
++ break;
+ case X86_VENDOR_INTEL:
+ if (boot_cpu_data.x86 == 6 || boot_cpu_data.x86 == 15 ||
+ (boot_cpu_data.x86 == 5 && boot_cpu_has(X86_FEATURE_APIC)))
+diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
+index 02e8acb134f8..47ff2976c292 100644
+--- a/arch/x86/kernel/apic/probe_32.c
++++ b/arch/x86/kernel/apic/probe_32.c
+@@ -185,6 +185,7 @@ void __init default_setup_apic_routing(void)
+ break;
+ }
+ /* If P4 and above fall through */
++ case X86_VENDOR_HYGON:
+ case X86_VENDOR_AMD:
+ def_to_bigsmp = 1;
+ }
+
diff --git a/patches.arch/x86-bugs-add-hygon-dhyana-to-the-respective-mitigation-machinery.patch b/patches.arch/x86-bugs-add-hygon-dhyana-to-the-respective-mitigation-machinery.patch
new file mode 100644
index 0000000000..ffe46a05c0
--- /dev/null
+++ b/patches.arch/x86-bugs-add-hygon-dhyana-to-the-respective-mitigation-machinery.patch
@@ -0,0 +1,60 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:35:50 +0800
+Subject: x86/bugs: Add Hygon Dhyana to the respective mitigation machinery
+Git-commit: 1a576b23d63794f39a247fb31056eecccbf9a287
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The Hygon Dhyana CPU has the same speculative execution as AMD family
+17h, so share AMD spectre mitigation code with Hygon Dhyana.
+
+Also Hygon Dhyana is not affected by meltdown, so add exception for it.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/0861d39c8a103fc0deca15bafbc85d403666d9ef.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/kernel/cpu/bugs.c | 4 +++-
+ arch/x86/kernel/cpu/common.c | 1 +
+ 2 files changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
+index 40bdaea97fe7..b810cc239375 100644
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -312,6 +312,7 @@ static enum spectre_v2_mitigation_cmd __init spectre_v2_parse_cmdline(void)
+ }
+
+ if (cmd == SPECTRE_V2_CMD_RETPOLINE_AMD &&
++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON &&
+ boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
+ pr_err("retpoline,amd selected but CPU is not AMD. Switching to AUTO select\n");
+ return SPECTRE_V2_CMD_AUTO;
+@@ -371,7 +372,8 @@ static void __init spectre_v2_select_mitigation(void)
+ return;
+
+ retpoline_auto:
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
+ retpoline_amd:
+ if (!boot_cpu_has(X86_FEATURE_LFENCE_RDTSC)) {
+ pr_err("Spectre mitigation: LFENCE not serializing, switching to generic retpoline\n");
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 658c85d16a9b..d14c879ba7ba 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -963,6 +963,7 @@ static const __initconst struct x86_cpu_id cpu_no_speculation[] = {
+
+ static const __initconst struct x86_cpu_id cpu_no_meltdown[] = {
+ { X86_VENDOR_AMD },
++ { X86_VENDOR_HYGON },
+ {}
+ };
+
+
diff --git a/patches.arch/x86-cpu-create-hygon-dhyana-architecture-support-file.patch b/patches.arch/x86-cpu-create-hygon-dhyana-architecture-support-file.patch
new file mode 100644
index 0000000000..d2a3254200
--- /dev/null
+++ b/patches.arch/x86-cpu-create-hygon-dhyana-architecture-support-file.patch
@@ -0,0 +1,503 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:33:12 +0800
+Subject: x86/cpu: Create Hygon Dhyana architecture support file
+Git-commit: c9661c1e80b609cd038db7c908e061f0535804ef
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+Add x86 architecture support for a new processor: Hygon Dhyana Family
+18h. Carve out initialization code needed by Dhyana into a separate
+compilation unit.
+
+To identify Hygon Dhyana CPU, add a new vendor type X86_VENDOR_HYGON.
+
+Since Dhyana uses AMD functionality to a large degree, select
+CPU_SUP_AMD which provides that functionality.
+
+ [ bp: drop explicit license statement as it has an SPDX tag already. ]
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/1a882065223bacbde5726f3beaa70cebd8dcd814.1537533369.git.puwen@hygon.cn
+---
+ MAINTAINERS | 6
+ arch/x86/Kconfig.cpu | 14 +
+ arch/x86/include/asm/processor.h | 3
+ arch/x86/kernel/cpu/Makefile | 1
+ arch/x86/kernel/cpu/hygon.c | 405 +++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 428 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -157,7 +157,8 @@ enum cpuid_regs_idx {
+ #define X86_VENDOR_CENTAUR 5
+ #define X86_VENDOR_TRANSMETA 7
+ #define X86_VENDOR_NSC 8
+-#define X86_VENDOR_NUM 9
++#define X86_VENDOR_HYGON 9
++#define X86_VENDOR_NUM 10
+
+ #define X86_VENDOR_UNKNOWN 0xff
+
+--- a/arch/x86/Kconfig.cpu
++++ b/arch/x86/Kconfig.cpu
+@@ -438,6 +438,20 @@ config CPU_SUP_AMD
+
+ If unsure, say N.
+
++config CPU_SUP_HYGON
++ default y
++ bool "Support Hygon processors" if PROCESSOR_SELECT
++ select CPU_SUP_AMD
++ help
++ This enables detection, tunings and quirks for Hygon processors
++
++ You need this enabled if you want your kernel to run on an
++ Hygon CPU. Disabling this option on other types of CPUs
++ makes the kernel a tiny bit smaller. Disabling it on an Hygon
++ CPU might render the kernel unbootable.
++
++ If unsure, say N.
++
+ config CPU_SUP_CENTAUR
+ default y
+ bool "Support Centaur processors" if PROCESSOR_SELECT
+--- /dev/null
++++ b/arch/x86/kernel/cpu/hygon.c
+@@ -0,0 +1,405 @@
++// SPDX-License-Identifier: GPL-2.0+
++/*
++ * Hygon Processor Support for Linux
++ *
++ * Copyright (C) 2018 Chengdu Haiguang IC Design Co., Ltd.
++ *
++ * Author: Pu Wen <puwen@hygon.cn>
++ */
++#include <linux/io.h>
++
++#include <asm/cpu.h>
++#include <asm/smp.h>
++#include <asm/cacheinfo.h>
++#include <asm/spec-ctrl.h>
++#include <asm/delay.h>
++#ifdef CONFIG_X86_64
++# include <asm/set_memory.h>
++#endif
++
++#include "cpu.h"
++
++/*
++ * nodes_per_socket: Stores the number of nodes per socket.
++ * Refer to CPUID Fn8000_001E_ECX Node Identifiers[10:8]
++ */
++static u32 nodes_per_socket = 1;
++
++#ifdef CONFIG_NUMA
++/*
++ * To workaround broken NUMA config. Read the comment in
++ * srat_detect_node().
++ */
++static int nearby_node(int apicid)
++{
++ int i, node;
++
++ for (i = apicid - 1; i >= 0; i--) {
++ node = __apicid_to_node[i];
++ if (node != NUMA_NO_NODE && node_online(node))
++ return node;
++ }
++ for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
++ node = __apicid_to_node[i];
++ if (node != NUMA_NO_NODE && node_online(node))
++ return node;
++ }
++ return first_node(node_online_map); /* Shouldn't happen */
++}
++#endif
++
++static void hygon_get_topology_early(struct cpuinfo_x86 *c)
++{
++ if (cpu_has(c, X86_FEATURE_TOPOEXT))
++ smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1;
++}
++
++/*
++ * Fixup core topology information for
++ * (1) Hygon multi-node processors
++ * Assumption: Number of cores in each internal node is the same.
++ * (2) Hygon processors supporting compute units
++ */
++static void hygon_get_topology(struct cpuinfo_x86 *c)
++{
++ u8 node_id;
++ int cpu = smp_processor_id();
++
++ /* get information required for multi-node processors */
++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
++ int err;
++ u32 eax, ebx, ecx, edx;
++
++ cpuid(0x8000001e, &eax, &ebx, &ecx, &edx);
++
++ node_id = ecx & 0xff;
++
++ c->cpu_core_id = ebx & 0xff;
++
++ if (smp_num_siblings > 1)
++ c->x86_max_cores /= smp_num_siblings;
++
++ /*
++ * In case leaf B is available, use it to derive
++ * topology information.
++ */
++ err = detect_extended_topology(c);
++ if (!err)
++ c->x86_coreid_bits = get_count_order(c->x86_max_cores);
++
++ } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
++ u64 value;
++
++ rdmsrl(MSR_FAM10H_NODE_ID, value);
++ node_id = value & 7;
++
++ per_cpu(cpu_llc_id, cpu) = node_id;
++ } else
++ return;
++
++ if (nodes_per_socket > 1)
++ set_cpu_cap(c, X86_FEATURE_AMD_DCM);
++}
++
++/*
++ * On Hygon setup the lower bits of the APIC id distinguish the cores.
++ * Assumes number of cores is a power of two.
++ */
++static void hygon_detect_cmp(struct cpuinfo_x86 *c)
++{
++ unsigned int bits;
++ int cpu = smp_processor_id();
++
++ bits = c->x86_coreid_bits;
++ /* Low order bits define the core id (index of core in socket) */
++ c->cpu_core_id = c->initial_apicid & ((1 << bits)-1);
++ /* Convert the initial APIC ID into the socket ID */
++ c->phys_proc_id = c->initial_apicid >> bits;
++ /* use socket ID also for last level cache */
++ per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
++}
++
++static void srat_detect_node(struct cpuinfo_x86 *c)
++{
++#ifdef CONFIG_NUMA
++ int cpu = smp_processor_id();
++ int node;
++ unsigned int apicid = c->apicid;
++
++ node = numa_cpu_node(cpu);
++ if (node == NUMA_NO_NODE)
++ node = per_cpu(cpu_llc_id, cpu);
++
++ /*
++ * On multi-fabric platform (e.g. Numascale NumaChip) a
++ * platform-specific handler needs to be called to fixup some
++ * IDs of the CPU.
++ */
++ if (x86_cpuinit.fixup_cpu_id)
++ x86_cpuinit.fixup_cpu_id(c, node);
++
++ if (!node_online(node)) {
++ /*
++ * Two possibilities here:
++ *
++ * - The CPU is missing memory and no node was created. In
++ * that case try picking one from a nearby CPU.
++ *
++ * - The APIC IDs differ from the HyperTransport node IDs.
++ * Assume they are all increased by a constant offset, but
++ * in the same order as the HT nodeids. If that doesn't
++ * result in a usable node fall back to the path for the
++ * previous case.
++ *
++ * This workaround operates directly on the mapping between
++ * APIC ID and NUMA node, assuming certain relationship
++ * between APIC ID, HT node ID and NUMA topology. As going
++ * through CPU mapping may alter the outcome, directly
++ * access __apicid_to_node[].
++ */
++ int ht_nodeid = c->initial_apicid;
++
++ if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
++ node = __apicid_to_node[ht_nodeid];
++ /* Pick a nearby node */
++ if (!node_online(node))
++ node = nearby_node(apicid);
++ }
++ numa_set_node(cpu, node);
++#endif
++}
++
++static void early_init_hygon_mc(struct cpuinfo_x86 *c)
++{
++#ifdef CONFIG_SMP
++ unsigned int bits, ecx;
++
++ /* Multi core CPU? */
++ if (c->extended_cpuid_level < 0x80000008)
++ return;
++
++ ecx = cpuid_ecx(0x80000008);
++
++ c->x86_max_cores = (ecx & 0xff) + 1;
++
++ /* CPU telling us the core id bits shift? */
++ bits = (ecx >> 12) & 0xF;
++
++ /* Otherwise recompute */
++ if (bits == 0) {
++ while ((1 << bits) < c->x86_max_cores)
++ bits++;
++ }
++
++ c->x86_coreid_bits = bits;
++#endif
++}
++
++static void bsp_init_hygon(struct cpuinfo_x86 *c)
++{
++#ifdef CONFIG_X86_64
++ unsigned long long tseg;
++
++ /*
++ * Split up direct mapping around the TSEG SMM area.
++ * Don't do it for gbpages because there seems very little
++ * benefit in doing so.
++ */
++ if (!rdmsrl_safe(MSR_K8_TSEG_ADDR, &tseg)) {
++ unsigned long pfn = tseg >> PAGE_SHIFT;
++
++ pr_debug("tseg: %010llx\n", tseg);
++ if (pfn_range_is_mapped(pfn, pfn + 1))
++ set_memory_4k((unsigned long)__va(tseg), 1);
++ }
++#endif
++
++ if (cpu_has(c, X86_FEATURE_CONSTANT_TSC)) {
++ u64 val;
++
++ rdmsrl(MSR_K7_HWCR, val);
++ if (!(val & BIT(24)))
++ pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n");
++ }
++
++ if (cpu_has(c, X86_FEATURE_MWAITX))
++ use_mwaitx_delay();
++
++ if (boot_cpu_has(X86_FEATURE_TOPOEXT)) {
++ u32 ecx;
++
++ ecx = cpuid_ecx(0x8000001e);
++ nodes_per_socket = ((ecx >> 8) & 7) + 1;
++ } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) {
++ u64 value;
++
++ rdmsrl(MSR_FAM10H_NODE_ID, value);
++ nodes_per_socket = ((value >> 3) & 7) + 1;
++ }
++
++ if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
++ !boot_cpu_has(X86_FEATURE_VIRT_SSBD)) {
++ /*
++ * Try to cache the base value so further operations can
++ * avoid RMW. If that faults, do not enable SSBD.
++ */
++ if (!rdmsrl_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) {
++ setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD);
++ setup_force_cpu_cap(X86_FEATURE_SSBD);
++ x86_amd_ls_cfg_ssbd_mask = 1ULL << 10;
++ }
++ }
++}
++
++static void early_init_hygon(struct cpuinfo_x86 *c)
++{
++ u32 dummy;
++
++ early_init_hygon_mc(c);
++
++ set_cpu_cap(c, X86_FEATURE_K8);
++
++ rdmsr_safe(MSR_AMD64_PATCH_LEVEL, &c->microcode, &dummy);
++
++ /*
++ * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate
++ * with P/T states and does not stop in deep C-states
++ */
++ if (c->x86_power & (1 << 8)) {
++ set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
++ set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
++ }
++
++ /* Bit 12 of 8000_0007 edx is accumulated power mechanism. */
++ if (c->x86_power & BIT(12))
++ set_cpu_cap(c, X86_FEATURE_ACC_POWER);
++
++#ifdef CONFIG_X86_64
++ set_cpu_cap(c, X86_FEATURE_SYSCALL32);
++#endif
++
++#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI)
++ /*
++ * ApicID can always be treated as an 8-bit value for Hygon APIC So, we
++ * can safely set X86_FEATURE_EXTD_APICID unconditionally.
++ */
++ if (boot_cpu_has(X86_FEATURE_APIC))
++ set_cpu_cap(c, X86_FEATURE_EXTD_APICID);
++#endif
++
++ /*
++ * This is only needed to tell the kernel whether to use VMCALL
++ * and VMMCALL. VMMCALL is never executed except under virt, so
++ * we can set it unconditionally.
++ */
++ set_cpu_cap(c, X86_FEATURE_VMMCALL);
++
++ hygon_get_topology_early(c);
++}
++
++static void init_hygon(struct cpuinfo_x86 *c)
++{
++ early_init_hygon(c);
++
++ /*
++ * Bit 31 in normal CPUID used for nonstandard 3DNow ID;
++ * 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway
++ */
++ clear_cpu_cap(c, 0*32+31);
++
++ set_cpu_cap(c, X86_FEATURE_REP_GOOD);
++
++ /* get apicid instead of initial apic id from cpuid */
++ c->apicid = hard_smp_processor_id();
++
++ set_cpu_cap(c, X86_FEATURE_ZEN);
++ set_cpu_cap(c, X86_FEATURE_CPB);
++
++ cpu_detect_cache_sizes(c);
++
++ hygon_detect_cmp(c);
++ hygon_get_topology(c);
++ srat_detect_node(c);
++
++ if (cpu_has(c, X86_FEATURE_XMM2)) {
++ unsigned long long val;
++ int ret;
++
++ /*
++ * A serializing LFENCE has less overhead than MFENCE, so
++ * use it for execution serialization. On families which
++ * don't have that MSR, LFENCE is already serializing.
++ * msr_set_bit() uses the safe accessors, too, even if the MSR
++ * is not present.
++ */
++ msr_set_bit(MSR_F10H_DECFG,
++ MSR_F10H_DECFG_LFENCE_SERIALIZE_BIT);
++
++ /*
++ * Verify that the MSR write was successful (could be running
++ * under a hypervisor) and only then assume that LFENCE is
++ * serializing.
++ */
++ ret = rdmsrl_safe(MSR_F10H_DECFG, &val);
++ if (!ret && (val & MSR_F10H_DECFG_LFENCE_SERIALIZE)) {
++ /* A serializing LFENCE stops RDTSC speculation */
++ set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
++ } else {
++ /* MFENCE stops RDTSC speculation */
++ set_cpu_cap(c, X86_FEATURE_MFENCE_RDTSC);
++ }
++ }
++
++ /*
++ * Hygon processors have APIC timer running in deep C states.
++ */
++ set_cpu_cap(c, X86_FEATURE_ARAT);
++
++ /* Hygon CPUs don't reset SS attributes on SYSRET, Xen does. */
++ if (!cpu_has(c, X86_FEATURE_XENPV))
++ set_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
++}
++
++static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c)
++{
++ u32 ebx, eax, ecx, edx;
++ u16 mask = 0xfff;
++
++ if (c->extended_cpuid_level < 0x80000006)
++ return;
++
++ cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
++
++ tlb_lld_4k[ENTRIES] = (ebx >> 16) & mask;
++ tlb_lli_4k[ENTRIES] = ebx & mask;
++
++ /* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
++ if (!((eax >> 16) & mask))
++ tlb_lld_2m[ENTRIES] = (cpuid_eax(0x80000005) >> 16) & 0xff;
++ else
++ tlb_lld_2m[ENTRIES] = (eax >> 16) & mask;
++
++ /* a 4M entry uses two 2M entries */
++ tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1;
++
++ /* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
++ if (!(eax & mask)) {
++ cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
++ tlb_lli_2m[ENTRIES] = eax & 0xff;
++ } else
++ tlb_lli_2m[ENTRIES] = eax & mask;
++
++ tlb_lli_4m[ENTRIES] = tlb_lli_2m[ENTRIES] >> 1;
++}
++
++static const struct cpu_dev hygon_cpu_dev = {
++ .c_vendor = "Hygon",
++ .c_ident = { "HygonGenuine" },
++ .c_early_init = early_init_hygon,
++ .c_detect_tlb = cpu_detect_tlb_hygon,
++ .c_bsp_init = bsp_init_hygon,
++ .c_init = init_hygon,
++ .c_x86_vendor = X86_VENDOR_HYGON,
++};
++
++cpu_dev_register(hygon_cpu_dev);
+--- a/arch/x86/kernel/cpu/Makefile
++++ b/arch/x86/kernel/cpu/Makefile
+@@ -29,6 +29,7 @@ obj-$(CONFIG_X86_FEATURE_NAMES) += capfl
+
+ obj-$(CONFIG_CPU_SUP_INTEL) += intel.o
+ obj-$(CONFIG_CPU_SUP_AMD) += amd.o
++obj-$(CONFIG_CPU_SUP_HYGON) += hygon.o
+ obj-$(CONFIG_CPU_SUP_CYRIX_32) += cyrix.o
+ obj-$(CONFIG_CPU_SUP_CENTAUR) += centaur.o
+ obj-$(CONFIG_CPU_SUP_TRANSMETA_32) += transmeta.o
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -6267,6 +6267,12 @@ W: https://linuxtv.org
+ S: Supported
+ F: drivers/media/platform/sti/hva
+
++HYGON PROCESSOR SUPPORT
++M: Pu Wen <puwen@hygon.cn>
++L: linux-kernel@vger.kernel.org
++S: Maintained
++F: arch/x86/kernel/cpu/hygon.c
++
+ Hyper-V CORE AND DRIVERS
+ M: "K. Y. Srinivasan" <kys@microsoft.com>
+ M: Haiyang Zhang <haiyangz@microsoft.com>
diff --git a/patches.arch/x86-cpu-get-cache-info-and-setup-cache-cpumap-for-hygon-dhyana.patch b/patches.arch/x86-cpu-get-cache-info-and-setup-cache-cpumap-for-hygon-dhyana.patch
new file mode 100644
index 0000000000..fa08958b4a
--- /dev/null
+++ b/patches.arch/x86-cpu-get-cache-info-and-setup-cache-cpumap-for-hygon-dhyana.patch
@@ -0,0 +1,141 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:33:44 +0800
+Subject: x86/cpu: Get cache info and setup cache cpumap for Hygon Dhyana
+Git-commit: d4f7423efdd1419b17524d090ff9ff4024bcf09b
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The Hygon Dhyana CPU has a topology extensions bit in CPUID. With
+this bit, the kernel can get the cache information. So add support in
+cpuid4_cache_lookup_regs() to get the correct cache size.
+
+The Hygon Dhyana CPU also discovers num_cache_leaves via CPUID leaf
+0x8000001d, so add support to it in find_num_cache_leaves().
+
+Also add cacheinfo_hygon_init_llc_id() and init_hygon_cacheinfo()
+functions to initialize Dhyana cache info. Setup cache cpumap in the
+same way as AMD does.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: bp@alien8.de
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/2a686b2ac0e2f5a1f2f5f101124d9dd44f949731.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/include/asm/cacheinfo.h | 1 +
+ arch/x86/kernel/cpu/cacheinfo.c | 31 +++++++++++++++++++++++++++++--
+ arch/x86/kernel/cpu/cpu.h | 1 +
+ arch/x86/kernel/cpu/hygon.c | 3 +++
+ 4 files changed, 34 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/cacheinfo.h
++++ b/arch/x86/include/asm/cacheinfo.h
+@@ -3,5 +3,6 @@
+ #define _ASM_X86_CACHEINFO_H
+
+ void cacheinfo_amd_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id);
++void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id);
+
+ #endif /* _ASM_X86_CACHEINFO_H */
+--- a/arch/x86/kernel/cpu/cacheinfo.c
++++ b/arch/x86/kernel/cpu/cacheinfo.c
+@@ -599,6 +599,10 @@ cpuid4_cache_lookup_regs(int index, stru
+ else
+ amd_cpuid4(index, &eax, &ebx, &ecx);
+ amd_init_l3_cache(this_leaf, index);
++ } else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
++ cpuid_count(0x8000001d, index, &eax.full,
++ &ebx.full, &ecx.full, &edx);
++ amd_init_l3_cache(this_leaf, index);
+ } else {
+ cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx);
+ }
+@@ -622,7 +626,8 @@ static int find_num_cache_leaves(struct
+ union _cpuid4_leaf_eax cache_eax;
+ int i = -1;
+
+- if (c->x86_vendor == X86_VENDOR_AMD)
++ if (c->x86_vendor == X86_VENDOR_AMD ||
++ c->x86_vendor == X86_VENDOR_HYGON)
+ op = 0x8000001d;
+ else
+ op = 4;
+@@ -675,6 +680,22 @@ void cacheinfo_amd_init_llc_id(struct cp
+ }
+ }
+
++void cacheinfo_hygon_init_llc_id(struct cpuinfo_x86 *c, int cpu, u8 node_id)
++{
++ /*
++ * We may have multiple LLCs if L3 caches exist, so check if we
++ * have an L3 cache by looking at the L3 cache CPUID leaf.
++ */
++ if (!cpuid_edx(0x80000006))
++ return;
++
++ /*
++ * LLC is at the core complex level.
++ * Core complex ID is ApicId[3] for these processors.
++ */
++ per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
++}
++
+ void init_amd_cacheinfo(struct cpuinfo_x86 *c)
+ {
+
+@@ -688,6 +709,11 @@ void init_amd_cacheinfo(struct cpuinfo_x
+ }
+ }
+
++void init_hygon_cacheinfo(struct cpuinfo_x86 *c)
++{
++ num_cache_leaves = find_num_cache_leaves(c);
++}
++
+ unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c)
+ {
+ /* Cache sizes */
+@@ -910,7 +936,8 @@ static void __cache_cpumap_setup(unsigne
+ int index_msb, i;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+- if (c->x86_vendor == X86_VENDOR_AMD) {
++ if (c->x86_vendor == X86_VENDOR_AMD ||
++ c->x86_vendor == X86_VENDOR_HYGON) {
+ if (__cache_amd_cpumap_setup(cpu, index, base))
+ return;
+ }
+--- a/arch/x86/kernel/cpu/cpu.h
++++ b/arch/x86/kernel/cpu/cpu.h
+@@ -27,6 +27,7 @@ struct cpu_dev {
+ } legacy_models[5];
+ #endif
+ };
++extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
+
+ struct _tlb_table {
+ unsigned char descriptor;
+--- a/arch/x86/kernel/cpu/hygon.c
++++ b/arch/x86/kernel/cpu/hygon.c
+@@ -87,6 +87,7 @@ static void hygon_get_topology(struct cp
+ if (!err)
+ c->x86_coreid_bits = get_count_order(c->x86_max_cores);
+
++ cacheinfo_hygon_init_llc_id(c, cpu, node_id);
+ } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
+ u64 value;
+
+@@ -321,6 +322,8 @@ static void init_hygon(struct cpuinfo_x8
+ hygon_get_topology(c);
+ srat_detect_node(c);
+
++ init_hygon_cacheinfo(c);
++
+ if (cpu_has(c, X86_FEATURE_XMM2)) {
+ unsigned long long val;
+ int ret;
diff --git a/patches.arch/x86-cpu-mtrr-support-top_mem2-and-get-mtrr-number.patch b/patches.arch/x86-cpu-mtrr-support-top_mem2-and-get-mtrr-number.patch
new file mode 100644
index 0000000000..eda9ef26e6
--- /dev/null
+++ b/patches.arch/x86-cpu-mtrr-support-top_mem2-and-get-mtrr-number.patch
@@ -0,0 +1,55 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:34:16 +0800
+Subject: x86/cpu/mtrr: Support TOP_MEM2 and get MTRR number
+Git-commit: 39dc6f154dac134e4612827cb5283934c1862cb8
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The Hygon Dhyana CPU has a special MSR way to force WB for memory >4GB,
+and support TOP_MEM2. Therefore, it is necessary to add Hygon Dhyana
+support in amd_special_default_mtrr().
+
+The number of variable MTRRs for Hygon is 2 as AMD's.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/8246f81648d014601de3812ade40e85d9c50d9b3.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/kernel/cpu/mtrr/cleanup.c | 3 ++-
+ arch/x86/kernel/cpu/mtrr/main.c | 2 +-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/mtrr/cleanup.c b/arch/x86/kernel/cpu/mtrr/cleanup.c
+index 765afd599039..3668c5df90c6 100644
+--- a/arch/x86/kernel/cpu/mtrr/cleanup.c
++++ b/arch/x86/kernel/cpu/mtrr/cleanup.c
+@@ -831,7 +831,8 @@ int __init amd_special_default_mtrr(void)
+ {
+ u32 l, h;
+
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+ return 0;
+ if (boot_cpu_data.x86 < 0xf)
+ return 0;
+diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
+index 9a19c800fe40..507039c20128 100644
+--- a/arch/x86/kernel/cpu/mtrr/main.c
++++ b/arch/x86/kernel/cpu/mtrr/main.c
+@@ -127,7 +127,7 @@ static void __init set_num_var_ranges(void)
+
+ if (use_intel())
+ rdmsr(MSR_MTRRcap, config, dummy);
+- else if (is_cpu(AMD))
++ else if (is_cpu(AMD) || is_cpu(HYGON))
+ config = 2;
+ else if (is_cpu(CYRIX) || is_cpu(CENTAUR))
+ config = 8;
+
diff --git a/patches.arch/x86-events-add-hygon-dhyana-support-to-pmu-infrastructure.patch b/patches.arch/x86-events-add-hygon-dhyana-support-to-pmu-infrastructure.patch
new file mode 100644
index 0000000000..3015ea2ff2
--- /dev/null
+++ b/patches.arch/x86-events-add-hygon-dhyana-support-to-pmu-infrastructure.patch
@@ -0,0 +1,133 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:34:47 +0800
+Subject: x86/events: Add Hygon Dhyana support to PMU infrastructure
+Git-commit: 6d0ef316b9f8ea03fa867debda70b2f11a0b9736
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The PMU architecture for the Hygon Dhyana CPU is similar to the AMD
+Family 17h one. To support it, call amd_pmu_init() to share the AMD PMU
+initialization flow, and change the PMU name to "HYGON".
+
+The Hygon Dhyana CPU supports both legacy and extension PMC MSRs (perf
+counter registers and event selection registers), so add Hygon Dhyana
+support in the similar way as AMD does.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/9d93ed54a975f33ef7247e0967960f4ce5d3d990.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/events/amd/core.c | 4 ++++
+ arch/x86/events/amd/uncore.c | 20 +++++++++++++-------
+ arch/x86/events/core.c | 4 ++++
+ arch/x86/kernel/cpu/perfctr-watchdog.c | 2 ++
+ 4 files changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/arch/x86/events/amd/core.c b/arch/x86/events/amd/core.c
+index c84584bb9402..7d2d7c801dba 100644
+--- a/arch/x86/events/amd/core.c
++++ b/arch/x86/events/amd/core.c
+@@ -669,6 +669,10 @@ static int __init amd_core_pmu_init(void)
+ * We fallback to using default amd_get_event_constraints.
+ */
+ break;
++ case 0x18:
++ pr_cont("Fam18h ");
++ /* Using default amd_get_event_constraints. */
++ break;
+ default:
+ pr_err("core perfctr but no constraints; unknown hardware!\n");
+ return -ENODEV;
+diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
+index 981ba5e8241b..c7d745bc4136 100644
+--- a/arch/x86/events/amd/uncore.c
++++ b/arch/x86/events/amd/uncore.c
+@@ -507,17 +507,19 @@ static int __init amd_uncore_init(void)
+ {
+ int ret = -ENODEV;
+
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+ return -ENODEV;
+
+ if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
+ return -ENODEV;
+
+- if (boot_cpu_data.x86 == 0x17) {
++ if (boot_cpu_data.x86 == 0x17 || boot_cpu_data.x86 == 0x18) {
+ /*
+- * For F17h, the Northbridge counters are repurposed as Data
+- * Fabric counters. Also, L3 counters are supported too. The PMUs
+- * are exported based on family as either L2 or L3 and NB or DF.
++ * For F17h or F18h, the Northbridge counters are
++ * repurposed as Data Fabric counters. Also, L3
++ * counters are supported too. The PMUs are exported
++ * based on family as either L2 or L3 and NB or DF.
+ */
+ num_counters_nb = NUM_COUNTERS_NB;
+ num_counters_llc = NUM_COUNTERS_L3;
+@@ -547,7 +549,9 @@ static int __init amd_uncore_init(void)
+ if (ret)
+ goto fail_nb;
+
+- pr_info("AMD NB counters detected\n");
++ pr_info("%s NB counters detected\n",
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ?
++ "HYGON" : "AMD");
+ ret = 0;
+ }
+
+@@ -561,7 +565,9 @@ static int __init amd_uncore_init(void)
+ if (ret)
+ goto fail_llc;
+
+- pr_info("AMD LLC counters detected\n");
++ pr_info("%s LLC counters detected\n",
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ?
++ "HYGON" : "AMD");
+ ret = 0;
+ }
+
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index dfb2f7c0d019..9c562f5fbde0 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -1776,6 +1776,10 @@ static int __init init_hw_perf_events(void)
+ case X86_VENDOR_AMD:
+ err = amd_pmu_init();
+ break;
++ case X86_VENDOR_HYGON:
++ err = amd_pmu_init();
++ x86_pmu.name = "HYGON";
++ break;
+ default:
+ err = -ENOTSUPP;
+ }
+diff --git a/arch/x86/kernel/cpu/perfctr-watchdog.c b/arch/x86/kernel/cpu/perfctr-watchdog.c
+index d389083330c5..9556930cd8c1 100644
+--- a/arch/x86/kernel/cpu/perfctr-watchdog.c
++++ b/arch/x86/kernel/cpu/perfctr-watchdog.c
+@@ -46,6 +46,7 @@ static inline unsigned int nmi_perfctr_msr_to_bit(unsigned int msr)
+ {
+ /* returns the bit offset of the performance counter register */
+ switch (boot_cpu_data.x86_vendor) {
++ case X86_VENDOR_HYGON:
+ case X86_VENDOR_AMD:
+ if (msr >= MSR_F15H_PERF_CTR)
+ return (msr - MSR_F15H_PERF_CTR) >> 1;
+@@ -74,6 +75,7 @@ static inline unsigned int nmi_evntsel_msr_to_bit(unsigned int msr)
+ {
+ /* returns the bit offset of the event selection register */
+ switch (boot_cpu_data.x86_vendor) {
++ case X86_VENDOR_HYGON:
+ case X86_VENDOR_AMD:
+ if (msr >= MSR_F15H_PERF_CTL)
+ return (msr - MSR_F15H_PERF_CTL) >> 1;
+
diff --git a/patches.arch/x86-kvm-add-hygon-dhyana-support-to-kvm.patch b/patches.arch/x86-kvm-add-hygon-dhyana-support-to-kvm.patch
new file mode 100644
index 0000000000..e5d2085c8f
--- /dev/null
+++ b/patches.arch/x86-kvm-add-hygon-dhyana-support-to-kvm.patch
@@ -0,0 +1,83 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:36:31 +0800
+Subject: x86/kvm: Add Hygon Dhyana support to KVM
+Git-commit: b8f4abb652146ddde04ab6e2a80e8cde27ff4470
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The Hygon Dhyana CPU has the SVM feature as AMD family 17h does.
+So enable the KVM infrastructure support to it.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: pbonzini@redhat.com
+Cc: rkrcmar@redhat.com
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Cc: kvm@vger.kernel.org
+Link: https://lkml.kernel.org/r/654dd12876149fba9561698eaf9fc15d030301f8.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/include/asm/kvm_emulate.h | 4 ++++
+ arch/x86/include/asm/virtext.h | 5 +++--
+ arch/x86/kvm/emulate.c | 11 ++++++++++-
+ 3 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
+index 0f82cd91cd3c..93c4bf598fb0 100644
+--- a/arch/x86/include/asm/kvm_emulate.h
++++ b/arch/x86/include/asm/kvm_emulate.h
+@@ -364,6 +364,10 @@ struct x86_emulate_ctxt {
+ #define X86EMUL_CPUID_VENDOR_AMDisbetterI_ecx 0x21726574
+ #define X86EMUL_CPUID_VENDOR_AMDisbetterI_edx 0x74656273
+
++#define X86EMUL_CPUID_VENDOR_HygonGenuine_ebx 0x6f677948
++#define X86EMUL_CPUID_VENDOR_HygonGenuine_ecx 0x656e6975
++#define X86EMUL_CPUID_VENDOR_HygonGenuine_edx 0x6e65476e
++
+ #define X86EMUL_CPUID_VENDOR_GenuineIntel_ebx 0x756e6547
+ #define X86EMUL_CPUID_VENDOR_GenuineIntel_ecx 0x6c65746e
+ #define X86EMUL_CPUID_VENDOR_GenuineIntel_edx 0x49656e69
+diff --git a/arch/x86/include/asm/virtext.h b/arch/x86/include/asm/virtext.h
+index 0116b2ee9e64..e05e0d309244 100644
+--- a/arch/x86/include/asm/virtext.h
++++ b/arch/x86/include/asm/virtext.h
+@@ -83,9 +83,10 @@ static inline void cpu_emergency_vmxoff(void)
+ */
+ static inline int cpu_has_svm(const char **msg)
+ {
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) {
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON) {
+ if (msg)
+- *msg = "not amd";
++ *msg = "not amd or hygon";
+ return 0;
+ }
+
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index 106482da6388..34edf198708f 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -2711,7 +2711,16 @@ static bool em_syscall_is_enabled(struct x86_emulate_ctxt *ctxt)
+ edx == X86EMUL_CPUID_VENDOR_AMDisbetterI_edx)
+ return true;
+
+- /* default: (not Intel, not AMD), apply Intel's stricter rules... */
++ /* Hygon ("HygonGenuine") */
++ if (ebx == X86EMUL_CPUID_VENDOR_HygonGenuine_ebx &&
++ ecx == X86EMUL_CPUID_VENDOR_HygonGenuine_ecx &&
++ edx == X86EMUL_CPUID_VENDOR_HygonGenuine_edx)
++ return true;
++
++ /*
++ * default: (not Intel, not AMD, not Hygon), apply Intel's
++ * stricter rules...
++ */
+ return false;
+ }
+
+
diff --git a/patches.arch/x86-mce-add-hygon-dhyana-support-to-the-mca-infrastructure.patch b/patches.arch/x86-mce-add-hygon-dhyana-support-to-the-mca-infrastructure.patch
new file mode 100644
index 0000000000..479ebdd24c
--- /dev/null
+++ b/patches.arch/x86-mce-add-hygon-dhyana-support-to-the-mca-infrastructure.patch
@@ -0,0 +1,111 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:36:04 +0800
+Subject: x86/mce: Add Hygon Dhyana support to the MCA infrastructure
+Git-commit: ac78bd72355d0da64c073c12927264d4ff19b886
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The machine check architecture for Hygon Dhyana CPU is similar to the
+AMD family 17h one. Add vendor checking for Hygon Dhyana to share the
+code path of AMD family 17h.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: tony.luck@intel.com
+Cc: thomas.lendacky@amd.com
+Cc: linux-edac@vger.kernel.org
+Link: https://lkml.kernel.org/r/87d8a4f16bdea0bfe0c0cf2e4a8d2c2a99b1055c.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/include/asm/mce.h | 2 ++
+ arch/x86/kernel/cpu/mcheck/mce-severity.c | 3 ++-
+ arch/x86/kernel/cpu/mcheck/mce.c | 18 ++++++++++++++----
+ 3 files changed, 18 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/include/asm/mce.h
++++ b/arch/x86/include/asm/mce.h
+@@ -269,6 +269,8 @@ static inline void mce_amd_feature_init(
+ static inline int umc_normaddr_to_sysaddr(u64 norm_addr, u16 nid, u8 umc, u64 *sys_addr) { return -EINVAL; };
+ #endif
+
++static inline void mce_hygon_feature_init(struct cpuinfo_x86 *c) { return mce_amd_feature_init(c); }
++
+ int mce_available(struct cpuinfo_x86 *c);
+ bool mce_is_memory_error(struct mce *m);
+
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -507,9 +507,9 @@ static int mce_usable_address(struct mce
+
+ bool mce_is_memory_error(struct mce *m)
+ {
+- if (m->cpuvendor == X86_VENDOR_AMD) {
++ if (m->cpuvendor == X86_VENDOR_AMD ||
++ m->cpuvendor == X86_VENDOR_HYGON) {
+ return amd_mce_is_memory_error(m);
+-
+ } else if (m->cpuvendor == X86_VENDOR_INTEL) {
+ /*
+ * Intel SDM Volume 3B - 15.9.2 Compound Error Codes
+@@ -538,6 +538,9 @@ static bool mce_is_correctable(struct mc
+ if (m->cpuvendor == X86_VENDOR_AMD && m->status & MCI_STATUS_DEFERRED)
+ return false;
+
++ if (m->cpuvendor == X86_VENDOR_HYGON && m->status & MCI_STATUS_DEFERRED)
++ return false;
++
+ if (m->status & MCI_STATUS_UC)
+ return false;
+
+@@ -1698,7 +1701,7 @@ static int __mcheck_cpu_ancient_init(str
+ */
+ static void __mcheck_cpu_init_early(struct cpuinfo_x86 *c)
+ {
+- if (c->x86_vendor == X86_VENDOR_AMD) {
++ if (c->x86_vendor == X86_VENDOR_AMD || c->x86_vendor == X86_VENDOR_HYGON) {
+ mce_flags.overflow_recov = !!cpu_has(c, X86_FEATURE_OVERFLOW_RECOV);
+ mce_flags.succor = !!cpu_has(c, X86_FEATURE_SUCCOR);
+ mce_flags.smca = !!cpu_has(c, X86_FEATURE_SMCA);
+@@ -1725,6 +1728,11 @@ static void __mcheck_cpu_init_vendor(str
+ break;
+ }
+
++ case X86_VENDOR_HYGON:
++ mce_hygon_feature_init(c);
++ break;
++
++
+ default:
+ break;
+ }
+@@ -1947,12 +1955,14 @@ static void mce_disable_error_reporting(
+ static void vendor_disable_error_reporting(void)
+ {
+ /*
+- * Don't clear on Intel or AMD CPUs. Some of these MSRs are socket-wide.
++ * Don't clear on Intel or AMD or Hygon CPUs. Some of these MSRs
++ * are socket-wide.
+ * Disabling them for just a single offlined CPU is bad, since it will
+ * inhibit reporting for all shared resources on the socket like the
+ * last level cache (LLC), the integrated memory controller (iMC), etc.
+ */
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ||
+ boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ return;
+
+--- a/arch/x86/kernel/cpu/mcheck/mce-severity.c
++++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c
+@@ -328,7 +328,8 @@ int (*mce_severity)(struct mce *m, int t
+
+ void __init mcheck_vendor_init_severity(void)
+ {
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
+ mce_severity = mce_severity_amd;
+ }
+
diff --git a/patches.arch/x86-mce-don-t-disable-mca-banks-when-offlining-a-cpu-on-amd.patch b/patches.arch/x86-mce-don-t-disable-mca-banks-when-offlining-a-cpu-on-amd.patch
new file mode 100644
index 0000000000..a127df8082
--- /dev/null
+++ b/patches.arch/x86-mce-don-t-disable-mca-banks-when-offlining-a-cpu-on-amd.patch
@@ -0,0 +1,53 @@
+From: Yazen Ghannam <yazen.ghannam@amd.com>
+Date: Tue, 13 Jun 2017 18:28:34 +0200
+Subject: x86/mce: Don't disable MCA banks when offlining a CPU on AMD
+Git-commit: ec33838244c8535b23b8d24b167996fd1318bb68
+Patch-mainline: v4.13-rc1
+References: fate#327735
+
+AMD systems have non-core, shared MCA banks within a die. These banks
+are controlled by a master CPU per die. If this CPU is offlined then all
+the shared banks are disabled in addition to the CPU's core banks.
+
+Also, Fam17h systems may have SMT enabled. The MCA_CTL register is shared
+between SMT thread siblings. If a CPU is offlined then all its sibling's
+MCA banks are also disabled.
+
+Extend the existing vendor check to AMD too.
+
+Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
+[ Fix up comment. ]
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Tony Luck <tony.luck@intel.com>
+Cc: linux-edac <linux-edac@vger.kernel.org>
+Link: http://lkml.kernel.org/r/20170613162835.30750-8-bp@alien8.de
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+---
+ arch/x86/kernel/cpu/mcheck/mce.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
+index 5cfbaeb6529a..3c54c2b9efc2 100644
+--- a/arch/x86/kernel/cpu/mcheck/mce.c
++++ b/arch/x86/kernel/cpu/mcheck/mce.c
+@@ -1912,12 +1912,13 @@ static void mce_disable_error_reporting(void)
+ static void vendor_disable_error_reporting(void)
+ {
+ /*
+- * Don't clear on Intel CPUs. Some of these MSRs are socket-wide.
++ * Don't clear on Intel or AMD CPUs. Some of these MSRs are socket-wide.
+ * Disabling them for just a single offlined CPU is bad, since it will
+ * inhibit reporting for all shared resources on the socket like the
+ * last level cache (LLC), the integrated memory controller (iMC), etc.
+ */
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL ||
++ boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
+ return;
+
+ mce_disable_error_reporting();
+
diff --git a/patches.arch/x86-pci-x86-amd_nb-add-hygon-dhyana-support-to-pci-and-northbridge.patch b/patches.arch/x86-pci-x86-amd_nb-add-hygon-dhyana-support-to-pci-and-northbridge.patch
new file mode 100644
index 0000000000..a5c4a9af50
--- /dev/null
+++ b/patches.arch/x86-pci-x86-amd_nb-add-hygon-dhyana-support-to-pci-and-northbridge.patch
@@ -0,0 +1,163 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Tue, 25 Sep 2018 22:46:11 +0800
+Subject: x86/pci, x86/amd_nb: Add Hygon Dhyana support to PCI and northbridge
+Git-commit: c6babb5806b77c6ca7078c3487bb0a29704a4e38
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+Hygon's PCI vendor ID is 0x1d94, and there are PCI devices
+0x1450/0x1463/0x1464 for the host bridge on the Hygon Dhyana platform.
+Add Hygon Dhyana support to the PCI and northbridge subsystems by using
+the code path of AMD family 17h.
+
+ [ bp: Massage commit message, sort local vars into reverse xmas tree
+ order and move the amd_northbridges.num check up. ]
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com> # pci_ids.h
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Cc: helgaas@kernel.org
+Cc: linux-pci@vger.kernel.org
+Link: https://lkml.kernel.org/r/5f8877bd413f2ea0833378dd5454df0720e1c0df.1537885177.git.puwen@hygon.cn
+---
+ arch/x86/kernel/amd_nb.c | 45 +++++++++++++++++++++++++++++++++++++--------
+ arch/x86/pci/amd_bus.c | 6 ++++--
+ include/linux/pci_ids.h | 2 ++
+ 3 files changed, 43 insertions(+), 10 deletions(-)
+
+--- a/arch/x86/kernel/amd_nb.c
++++ b/arch/x86/kernel/amd_nb.c
+@@ -55,6 +55,21 @@ static const struct pci_device_id amd_nb
+ {}
+ };
+
++static const struct pci_device_id hygon_root_ids[] = {
++ { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_ROOT) },
++ {}
++};
++
++const struct pci_device_id hygon_nb_misc_ids[] = {
++ { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
++ {}
++};
++
++static const struct pci_device_id hygon_nb_link_ids[] = {
++ { PCI_DEVICE(PCI_VENDOR_ID_HYGON, PCI_DEVICE_ID_AMD_17H_DF_F4) },
++ {}
++};
++
+ const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[] __initconst = {
+ { 0x00, 0x18, 0x20 },
+ { 0xff, 0x00, 0x20 },
+@@ -188,15 +203,24 @@ EXPORT_SYMBOL_GPL(amd_df_indirect_read);
+
+ int amd_cache_northbridges(void)
+ {
+- u16 i = 0;
+- struct amd_northbridge *nb;
++ const struct pci_device_id *misc_ids = amd_nb_misc_ids;
++ const struct pci_device_id *link_ids = amd_nb_link_ids;
++ const struct pci_device_id *root_ids = amd_root_ids;
+ struct pci_dev *root, *misc, *link;
++ struct amd_northbridge *nb;
++ u16 i = 0;
+
+ if (amd_northbridges.num)
+ return 0;
+
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
++ root_ids = hygon_root_ids;
++ misc_ids = hygon_nb_misc_ids;
++ link_ids = hygon_nb_link_ids;
++ }
++
+ misc = NULL;
+- while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
++ while ((misc = next_northbridge(misc, misc_ids)) != NULL)
+ i++;
+
+ if (!i)
+@@ -212,11 +236,11 @@ int amd_cache_northbridges(void)
+ link = misc = root = NULL;
+ for (i = 0; i != amd_northbridges.num; i++) {
+ node_to_amd_nb(i)->root = root =
+- next_northbridge(root, amd_root_ids);
++ next_northbridge(root, root_ids);
+ node_to_amd_nb(i)->misc = misc =
+- next_northbridge(misc, amd_nb_misc_ids);
++ next_northbridge(misc, misc_ids);
+ node_to_amd_nb(i)->link = link =
+- next_northbridge(link, amd_nb_link_ids);
++ next_northbridge(link, link_ids);
+ }
+
+ if (amd_gart_present())
+@@ -255,6 +279,7 @@ EXPORT_SYMBOL_GPL(amd_cache_northbridges
+ */
+ bool __init early_is_amd_nb(u32 device)
+ {
++ const struct pci_device_id *misc_ids = amd_nb_misc_ids;
+ const struct pci_device_id *id;
+ u32 vendor = device & 0xffff;
+
+@@ -262,8 +287,11 @@ bool __init early_is_amd_nb(u32 device)
+ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+ return false;
+
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
++ misc_ids = hygon_nb_misc_ids;
++
+ device >>= 16;
+- for (id = amd_nb_misc_ids; id->vendor; id++)
++ for (id = misc_ids; id->vendor; id++)
+ if (vendor == id->vendor && device == id->device)
+ return true;
+ return false;
+@@ -275,7 +303,8 @@ struct resource *amd_get_mmconfig_range(
+ u64 base, msr;
+ unsigned int segn_busn_bits;
+
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+ return NULL;
+
+ /* assume all cpus from fam10h have mmconfig */
+--- a/arch/x86/pci/amd_bus.c
++++ b/arch/x86/pci/amd_bus.c
+@@ -92,7 +92,8 @@ static int __init early_root_info_init(v
+ vendor = id & 0xffff;
+ device = (id>>16) & 0xffff;
+
+- if (vendor != PCI_VENDOR_ID_AMD)
++ if (vendor != PCI_VENDOR_ID_AMD &&
++ vendor != PCI_VENDOR_ID_HYGON)
+ continue;
+
+ if (hb_probes[i].device == device) {
+@@ -389,7 +390,8 @@ static int __init pci_io_ecs_init(void)
+
+ static int __init amd_postcore_init(void)
+ {
+- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
++ boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+ return 0;
+
+ early_root_info_init();
+--- a/include/linux/pci_ids.h
++++ b/include/linux/pci_ids.h
+@@ -2549,6 +2549,8 @@
+ #define PCI_VENDOR_ID_CIRCUITCO 0x1cc8
+ #define PCI_SUBSYSTEM_ID_CIRCUITCO_MINNOWBOARD 0x0001
+
++#define PCI_VENDOR_ID_HYGON 0x1d94
++
+ #define PCI_VENDOR_ID_TEKRAM 0x1de1
+ #define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29
+
diff --git a/patches.arch/x86-smpboot-do-not-use-bsp-init-delay-and-mwait-to-idle-on-dhyana.patch b/patches.arch/x86-smpboot-do-not-use-bsp-init-delay-and-mwait-to-idle-on-dhyana.patch
new file mode 100644
index 0000000000..e176cb8ba0
--- /dev/null
+++ b/patches.arch/x86-smpboot-do-not-use-bsp-init-delay-and-mwait-to-idle-on-dhyana.patch
@@ -0,0 +1,47 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:34:32 +0800
+Subject: x86/smpboot: Do not use BSP INIT delay and MWAIT to idle on Dhyana
+Git-commit: 0b13bec787dccca96f8c431da732657ae01baf9a
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+The Hygon Dhyana CPU uses no delay in smp_quirk_init_udelay(), and does
+HLT on idle just like AMD does.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: bp@alien8.de
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Link: https://lkml.kernel.org/r/87000fa82e273f5967c908448414228faf61e077.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/kernel/smpboot.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index f02ecaf97904..5369d7fac797 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -676,6 +676,7 @@ static void __init smp_quirk_init_udelay(void)
+
+ /* if modern processor, use no delay */
+ if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) ||
++ ((boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) && (boot_cpu_data.x86 >= 0x18)) ||
+ ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF))) {
+ init_udelay = 0;
+ return;
+@@ -1592,7 +1593,8 @@ static inline void mwait_play_dead(void)
+ void *mwait_ptr;
+ int i;
+
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
++ boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
+ return;
+ if (!this_cpu_has(X86_FEATURE_MWAIT))
+ return;
+
diff --git a/patches.arch/x86-speculation-consolidate-cpu-whitelists.patch b/patches.arch/x86-speculation-consolidate-cpu-whitelists.patch
index 86279e374c..a168a35edb 100644
--- a/patches.arch/x86-speculation-consolidate-cpu-whitelists.patch
+++ b/patches.arch/x86-speculation-consolidate-cpu-whitelists.patch
@@ -20,12 +20,12 @@ Reviewed-by: Jon Masters <jcm@redhat.com>
Tested-by: Jon Masters <jcm@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
- arch/x86/kernel/cpu/common.c | 109 +++++++++++++++++++++----------------------
- 1 file changed, 55 insertions(+), 54 deletions(-)
+ arch/x86/kernel/cpu/common.c | 115 ++++++++++++++++++++++---------------------
+ 1 file changed, 60 insertions(+), 55 deletions(-)
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
-@@ -922,65 +922,67 @@ static void identify_cpu_without_cpuid(s
+@@ -922,66 +922,72 @@ static void identify_cpu_without_cpuid(s
#endif
}
@@ -53,6 +53,9 @@ Acked-by: Borislav Petkov <bp@suse.de>
+#define VULNWL_AMD(family, whitelist) \
+ VULNWL(AMD, family, X86_MODEL_ANY, whitelist)
+
++#define VULNWL_HYGON(family, whitelist) \
++ VULNWL(HYGON, family, X86_MODEL_ANY, whitelist)
++
+static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
+ VULNWL(ANY, 4, X86_MODEL_ANY, NO_SPECULATION),
+ VULNWL(CENTAUR, 5, X86_MODEL_ANY, NO_SPECULATION),
@@ -83,13 +86,16 @@ Acked-by: Borislav Petkov <bp@suse.de>
+ VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF),
+ VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF),
+ VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF),
++
+ /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
+ VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF),
++ VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF),
{}
};
-static const __initconst struct x86_cpu_id cpu_no_meltdown[] = {
- { X86_VENDOR_AMD },
+- { X86_VENDOR_HYGON },
- {}
-};
-
@@ -143,7 +149,7 @@ Acked-by: Borislav Petkov <bp@suse.de>
return;
setup_force_cpu_bug(X86_BUG_SPECTRE_V1);
-@@ -989,15 +991,14 @@ static void __init cpu_set_bug_bits(stru
+@@ -990,15 +996,14 @@ static void __init cpu_set_bug_bits(stru
if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES))
rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap);
@@ -161,7 +167,7 @@ Acked-by: Borislav Petkov <bp@suse.de>
return;
/* Rogue Data Cache Load? No! */
-@@ -1006,7 +1007,7 @@ static void __init cpu_set_bug_bits(stru
+@@ -1007,7 +1012,7 @@ static void __init cpu_set_bug_bits(stru
setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN);
diff --git a/patches.arch/x86-speculation-mds-add-basic-bug-infrastructure-for-mds.patch b/patches.arch/x86-speculation-mds-add-basic-bug-infrastructure-for-mds.patch
index c6e0023444..da134cfbc7 100644
--- a/patches.arch/x86-speculation-mds-add-basic-bug-infrastructure-for-mds.patch
+++ b/patches.arch/x86-speculation-mds-add-basic-bug-infrastructure-for-mds.patch
@@ -56,19 +56,19 @@ Acked-by: Borislav Petkov <bp@suse.de>
---
arch/x86/include/asm/cpufeatures.h | 2 ++
arch/x86/include/asm/msr-index.h | 5 +++++
- arch/x86/kernel/cpu/common.c | 25 ++++++++++++++++---------
- 3 files changed, 23 insertions(+), 9 deletions(-)
+ arch/x86/kernel/cpu/common.c | 27 +++++++++++++++++----------
+ 3 files changed, 24 insertions(+), 10 deletions(-)
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
-@@ -344,6 +344,7 @@
+@@ -343,6 +343,7 @@
+ /* Intel-defined CPU features, CPUID level 0x00000007:0 (EDX), word 18 */
#define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */
#define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */
- #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
+#define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */
+ #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */
#define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */
#define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */
- #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */
@@ -381,4 +382,5 @@
#define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */
#define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */
@@ -99,7 +99,7 @@ Acked-by: Borislav Petkov <bp@suse.de>
#define VULNWL(_vendor, _family, _model, _whitelist) \
{ X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
-@@ -942,6 +943,7 @@ static const __initconst struct x86_cpu_
+@@ -945,6 +946,7 @@ static const __initconst struct x86_cpu_
VULNWL(INTEL, 5, X86_MODEL_ANY, NO_SPECULATION),
VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION),
@@ -107,7 +107,7 @@ Acked-by: Borislav Petkov <bp@suse.de>
VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION),
VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION),
VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION),
-@@ -958,16 +960,18 @@ static const __initconst struct x86_cpu_
+@@ -961,18 +963,20 @@ static const __initconst struct x86_cpu_
VULNWL_INTEL(CORE_YONAH, NO_SSB),
VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF),
@@ -119,6 +119,7 @@ Acked-by: Borislav Petkov <bp@suse.de>
- VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF),
- VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF),
- VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF),
++
+ VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
+ VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
+ VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
@@ -128,14 +129,16 @@ Acked-by: Borislav Petkov <bp@suse.de>
+ VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
+ VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
+ VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
-+
+
/* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
- VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF),
+- VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF),
+ VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
++ VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
{}
};
-@@ -998,6 +1002,9 @@ static void __init cpu_set_bug_bits(stru
+@@ -1003,6 +1007,9 @@ static void __init cpu_set_bug_bits(stru
if (ia32_cap & ARCH_CAP_IBRS_ALL)
setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
diff --git a/patches.arch/x86-speculation-mds-add-bug_msbds_only.patch b/patches.arch/x86-speculation-mds-add-bug_msbds_only.patch
index 60dc73ace2..ccb20744c4 100644
--- a/patches.arch/x86-speculation-mds-add-bug_msbds_only.patch
+++ b/patches.arch/x86-speculation-mds-add-bug_msbds_only.patch
@@ -26,8 +26,8 @@ Tested-by: Jon Masters <jcm@redhat.com>
Acked-by: Borislav Petkov <bp@suse.de>
---
arch/x86/include/asm/cpufeatures.h | 1 +
- arch/x86/kernel/cpu/common.c | 21 +++++++++++++--------
- 2 files changed, 14 insertions(+), 8 deletions(-)
+ arch/x86/kernel/cpu/common.c | 20 ++++++++++++--------
+ 2 files changed, 13 insertions(+), 8 deletions(-)
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -47,7 +47,7 @@ Acked-by: Borislav Petkov <bp@suse.de>
#define VULNWL(_vendor, _family, _model, _whitelist) \
{ X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
-@@ -950,16 +951,17 @@ static const __initconst struct x86_cpu_
+@@ -953,16 +954,16 @@ static const __initconst struct x86_cpu_
VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION),
VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION),
@@ -68,11 +68,10 @@ Acked-by: Borislav Petkov <bp@suse.de>
- VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF),
+ VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY),
-+
+
VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
- VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
-@@ -1002,8 +1004,11 @@ static void __init cpu_set_bug_bits(stru
+@@ -1007,8 +1008,11 @@ static void __init cpu_set_bug_bits(stru
if (ia32_cap & ARCH_CAP_IBRS_ALL)
setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED);
diff --git a/patches.arch/x86-xen-add-hygon-dhyana-support-to-xen.patch b/patches.arch/x86-xen-add-hygon-dhyana-support-to-xen.patch
new file mode 100644
index 0000000000..773d267acf
--- /dev/null
+++ b/patches.arch/x86-xen-add-hygon-dhyana-support-to-xen.patch
@@ -0,0 +1,78 @@
+From: Pu Wen <puwen@hygon.cn>
+Date: Sun, 23 Sep 2018 17:36:46 +0800
+Subject: x86/xen: Add Hygon Dhyana support to Xen
+Git-commit: 4044240365e85ef7ae43a6dc454669b57853124c
+Patch-mainline: v4.20-rc1
+References: fate#327735
+
+To make Xen work on the Hygon platform, reuse AMD's Xen support code
+path for Hygon Dhyana CPU.
+
+There are six core performance events counters per thread, so there are
+six MSRs for these counters. Also there are four legacy PMC MSRs, they
+are aliases of the counters.
+
+In this version, use the legacy and safe version of MSR access. Tested
+successfully with VPMU enabled in Xen on Hygon platform by testing with
+perf.
+
+Signed-off-by: Pu Wen <puwen@hygon.cn>
+Signed-off-by: Borislav Petkov <bp@suse.de>
+Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
+Cc: jgross@suse.com
+Cc: tglx@linutronix.de
+Cc: mingo@redhat.com
+Cc: hpa@zytor.com
+Cc: x86@kernel.org
+Cc: thomas.lendacky@amd.com
+Cc: xen-devel@lists.xenproject.org
+Link: https://lkml.kernel.org/r/311bf41f08f24550aa6c5da3f1e03a68d3b89dac.1537533369.git.puwen@hygon.cn
+---
+ arch/x86/xen/pmu.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/xen/pmu.c b/arch/x86/xen/pmu.c
+index 7d00d4ad44d4..9403854cde31 100644
+--- a/arch/x86/xen/pmu.c
++++ b/arch/x86/xen/pmu.c
+@@ -90,6 +90,12 @@ static void xen_pmu_arch_init(void)
+ k7_counters_mirrored = 0;
+ break;
+ }
++ } else if (boot_cpu_data.x86_vendor == X86_VENDOR_HYGON) {
++ amd_num_counters = F10H_NUM_COUNTERS;
++ amd_counters_base = MSR_K7_PERFCTR0;
++ amd_ctrls_base = MSR_K7_EVNTSEL0;
++ amd_msr_step = 1;
++ k7_counters_mirrored = 0;
+ } else {
+ uint32_t eax, ebx, ecx, edx;
+
+@@ -285,7 +291,7 @@ static bool xen_amd_pmu_emulate(unsigned int msr, u64 *val, bool is_read)
+
+ bool pmu_msr_read(unsigned int msr, uint64_t *val, int *err)
+ {
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
+ if (is_amd_pmu_msr(msr)) {
+ if (!xen_amd_pmu_emulate(msr, val, 1))
+ *val = native_read_msr_safe(msr, err);
+@@ -308,7 +314,7 @@ bool pmu_msr_write(unsigned int msr, uint32_t low, uint32_t high, int *err)
+ {
+ uint64_t val = ((uint64_t)high << 32) | low;
+
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) {
+ if (is_amd_pmu_msr(msr)) {
+ if (!xen_amd_pmu_emulate(msr, &val, 0))
+ *err = native_write_msr_safe(msr, low, high);
+@@ -379,7 +385,7 @@ static unsigned long long xen_intel_read_pmc(int counter)
+
+ unsigned long long xen_read_pmc(int counter)
+ {
+- if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
++ if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+ return xen_amd_read_pmc(counter);
+ else
+ return xen_intel_read_pmc(counter);
+
diff --git a/patches.drivers/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch b/patches.drivers/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch
index da3199c891..ab3d68d742 100644
--- a/patches.drivers/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch
+++ b/patches.drivers/0001-PCI-pciehp-Unify-controller-and-slot-structs.patch
@@ -30,12 +30,12 @@ Signed-off-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Oliver Neukum <oneukum@suse.com>
---
- drivers/pci/hotplug/pciehp.h | 70 +++-------
- drivers/pci/hotplug/pciehp_core.c | 55 +++-----
- drivers/pci/hotplug/pciehp_ctrl.c | 254 ++++++++++++++++++--------------------
- drivers/pci/hotplug/pciehp_hpc.c | 128 +++++--------------
+ drivers/pci/hotplug/pciehp.h | 68 +++-------
+ drivers/pci/hotplug/pciehp_core.c | 53 +++-----
+ drivers/pci/hotplug/pciehp_ctrl.c | 248 ++++++++++++++++++--------------------
+ drivers/pci/hotplug/pciehp_hpc.c | 122 +++++-------------
drivers/pci/hotplug/pciehp_pci.c | 14 --
- 5 files changed, 215 insertions(+), 306 deletions(-)
+ 5 files changed, 207 insertions(+), 298 deletions(-)
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -96,7 +96,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
int request_result;
wait_queue_head_t requester;
};
-@@ -185,29 +163,29 @@ struct controller {
+@@ -185,28 +163,28 @@ struct controller {
#define PSN(ctrl) (((ctrl)->slot_cap & PCI_EXP_SLTCAP_PSN) >> 19)
void pciehp_request(struct controller *ctrl, int action);
@@ -125,7 +125,6 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
-
-void pciehp_set_attention_status(struct slot *slot, u8 status);
-void pciehp_get_latch_status(struct slot *slot, u8 *status);
--void pciehp_get_adapter_status(struct slot *slot, u8 *status);
-int pciehp_query_power_fault(struct slot *slot);
-void pciehp_green_led_on(struct slot *slot);
-void pciehp_green_led_off(struct slot *slot);
@@ -136,15 +135,14 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
+
+void pciehp_set_attention_status(struct controller *ctrl, u8 status);
+void pciehp_get_latch_status(struct controller *ctrl, u8 *status);
-+void pciehp_get_adapter_status(struct controller *ctrl, u8 *status);
+int pciehp_query_power_fault(struct controller *ctrl);
+void pciehp_green_led_on(struct controller *ctrl);
+void pciehp_green_led_off(struct controller *ctrl);
+void pciehp_green_led_blink(struct controller *ctrl);
+ bool pciehp_card_present(struct controller *ctrl);
+ bool pciehp_card_present_or_link_active(struct controller *ctrl);
int pciehp_check_link_status(struct controller *ctrl);
- bool pciehp_check_link_active(struct controller *ctrl);
- void pciehp_release_ctrl(struct controller *ctrl);
-@@ -219,9 +197,9 @@ int pciehp_get_attention_status(struct h
+@@ -220,9 +198,9 @@ int pciehp_get_attention_status(struct h
int pciehp_set_raw_indicator_status(struct hotplug_slot *h_slot, u8 status);
int pciehp_get_raw_indicator_status(struct hotplug_slot *h_slot, u8 *status);
@@ -239,8 +237,8 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
+ struct pci_dev *pdev = ctrl->pcie->port;
pci_config_pm_runtime_get(pdev);
-- pciehp_get_adapter_status(slot, value);
-+ pciehp_get_adapter_status(ctrl, value);
+- *value = pciehp_card_present_or_link_active(slot->ctrl);
++ *value = pciehp_card_present_or_link_active(ctrl);
pci_config_pm_runtime_put(pdev);
return 0;
}
@@ -249,18 +247,17 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
static void pciehp_check_presence(struct controller *ctrl)
{
- struct slot *slot = ctrl->slot;
- u8 occupied;
+ bool occupied;
down_read(&ctrl->reset_lock);
- mutex_lock(&slot->lock);
+ mutex_lock(&ctrl->lock);
-- pciehp_get_adapter_status(slot, &occupied);
+ occupied = pciehp_card_present_or_link_active(ctrl);
- if ((occupied && (slot->state == OFF_STATE ||
- slot->state == BLINKINGON_STATE)) ||
- (!occupied && (slot->state == ON_STATE ||
- slot->state == BLINKINGOFF_STATE)))
-+ pciehp_get_adapter_status(ctrl, &occupied);
+ if ((occupied && (ctrl->state == OFF_STATE ||
+ ctrl->state == BLINKINGON_STATE)) ||
+ (!occupied && (ctrl->state == ON_STATE ||
@@ -503,7 +500,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
break;
case BLINKINGOFF_STATE:
case BLINKINGON_STATE:
-@@ -201,46 +199,43 @@ void pciehp_handle_button_press(struct s
+@@ -201,143 +199,138 @@ void pciehp_handle_button_press(struct s
* press the attention again before the 5 sec. limit
* expires to cancel hot-add or hot-remove
*/
@@ -566,10 +563,9 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
+void pciehp_handle_presence_or_link_change(struct controller *ctrl, u32 events)
{
- struct controller *ctrl = slot->ctrl;
- bool link_active;
- u8 present;
+ bool present, link_active;
-@@ -248,102 +243,100 @@ void pciehp_handle_presence_or_link_chan
+ /*
* If the slot is on and presence or link has changed, turn it off.
* Even if it's occupied again, we cannot assume the card is the same.
*/
@@ -603,9 +599,8 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
/* Turn the slot on if it's occupied or link is up */
- mutex_lock(&slot->lock);
-- pciehp_get_adapter_status(slot, &present);
+ mutex_lock(&ctrl->lock);
-+ pciehp_get_adapter_status(ctrl, &present);
+ present = pciehp_card_present(ctrl);
link_active = pciehp_check_link_active(ctrl);
if (!present && !link_active) {
- mutex_unlock(&slot->lock);
@@ -649,13 +644,6 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
u8 getstatus = 0;
- struct controller *ctrl = p_slot->ctrl;
-- pciehp_get_adapter_status(p_slot, &getstatus);
-+ pciehp_get_adapter_status(ctrl, &getstatus);
- if (!getstatus) {
-- ctrl_info(ctrl, "Slot(%s): No adapter\n", slot_name(p_slot));
-+ ctrl_info(ctrl, "Slot(%s): No adapter\n", slot_name(ctrl));
- return -ENODEV;
- }
- if (MRL_SENS(p_slot->ctrl)) {
- pciehp_get_latch_status(p_slot, &getstatus);
+ if (MRL_SENS(ctrl)) {
@@ -693,9 +681,9 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
- mutex_lock(&slot->hotplug_lock);
- ret = __pciehp_enable_slot(slot);
- mutex_unlock(&slot->hotplug_lock);
-+ pm_runtime_get_sync(&ctrl->pcie->port->dev);
++ mutex_lock(&ctrl->lock);
+ ret = __pciehp_enable_slot(ctrl);
-+ pm_runtime_put(&ctrl->pcie->port->dev);
++ mutex_unlock(&ctrl->lock);
if (ret && ATTN_BUTTN(ctrl))
- pciehp_green_led_off(slot); /* may be blinking */
@@ -705,12 +693,12 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
- slot->state = ON_STATE;
- mutex_unlock(&slot->lock);
+ mutex_lock(&ctrl->lock);
-+ ctrl->state = ret ? OFF_STATE : ON_STATE;
++ ctrl->state = ON_STATE;
+ mutex_unlock(&ctrl->lock);
return ret;
}
-@@ -351,48 +344,46 @@ int pciehp_enable_slot(struct slot *slot
+@@ -345,48 +338,46 @@ int pciehp_enable_slot(struct slot *slot
/*
* Note: This function must be called with slot->hotplug_lock held
*/
@@ -776,7 +764,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
/*
* The IRQ thread becomes a no-op if the user pulls out the
* card before the thread wakes up, so initialize to -ENODEV.
-@@ -404,33 +395,32 @@ int pciehp_sysfs_enable_slot(struct hotp
+@@ -398,33 +389,32 @@ int pciehp_sysfs_enable_slot(struct hotp
return ctrl->request_result;
case POWERON_STATE:
ctrl_info(ctrl, "Slot(%s): Already in powering on state\n",
@@ -818,7 +806,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
pciehp_request(ctrl, DISABLE_SLOT);
wait_event(ctrl->requester,
!atomic_read(&ctrl->pending_events));
-@@ -438,20 +428,20 @@ int pciehp_sysfs_disable_slot(struct hot
+@@ -432,20 +422,20 @@ int pciehp_sysfs_disable_slot(struct hot
break;
case POWEROFF_STATE:
ctrl_info(ctrl, "Slot(%s): Already in powering off state\n",
@@ -886,7 +874,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
struct pci_dev *pdev = ctrl_dev(ctrl);
u16 slot_ctrl;
-@@ -397,27 +395,27 @@ void pciehp_get_power_status(struct slot
+@@ -397,9 +395,9 @@ void pciehp_get_power_status(struct slot
}
}
@@ -898,18 +886,8 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
u16 slot_status;
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
- *status = !!(slot_status & PCI_EXP_SLTSTA_MRLSS);
- }
-
--void pciehp_get_adapter_status(struct slot *slot, u8 *status)
-+void pciehp_get_adapter_status(struct controller *ctrl, u8 *status)
- {
-- struct pci_dev *pdev = ctrl_dev(slot->ctrl);
-+ struct pci_dev *pdev = ctrl_dev(ctrl);
- u16 slot_status;
-
- pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
- *status = !!(slot_status & PCI_EXP_SLTSTA_PDS);
+@@ -429,9 +427,9 @@ bool pciehp_card_present_or_link_active(
+ return pciehp_card_present(ctrl) || pciehp_check_link_active(ctrl);
}
-int pciehp_query_power_fault(struct slot *slot)
@@ -920,7 +898,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
u16 slot_status;
pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
-@@ -427,8 +425,7 @@ int pciehp_query_power_fault(struct slot
+@@ -441,8 +439,7 @@ int pciehp_query_power_fault(struct slot
int pciehp_set_raw_indicator_status(struct hotplug_slot *hotplug_slot,
u8 status)
{
@@ -930,7 +908,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
struct pci_dev *pdev = ctrl_dev(ctrl);
pci_config_pm_runtime_get(pdev);
-@@ -438,9 +435,8 @@ int pciehp_set_raw_indicator_status(stru
+@@ -452,9 +449,8 @@ int pciehp_set_raw_indicator_status(stru
return 0;
}
@@ -941,7 +919,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
u16 slot_cmd;
if (!ATTN_LED(ctrl))
-@@ -464,10 +460,8 @@ void pciehp_set_attention_status(struct
+@@ -478,10 +474,8 @@ void pciehp_set_attention_status(struct
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd);
}
@@ -953,7 +931,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
if (!PWR_LED(ctrl))
return;
-@@ -478,10 +472,8 @@ void pciehp_green_led_on(struct slot *sl
+@@ -492,10 +486,8 @@ void pciehp_green_led_on(struct slot *sl
PCI_EXP_SLTCTL_PWR_IND_ON);
}
@@ -965,7 +943,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
if (!PWR_LED(ctrl))
return;
-@@ -492,10 +484,8 @@ void pciehp_green_led_off(struct slot *s
+@@ -506,10 +498,8 @@ void pciehp_green_led_off(struct slot *s
PCI_EXP_SLTCTL_PWR_IND_OFF);
}
@@ -977,7 +955,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
if (!PWR_LED(ctrl))
return;
-@@ -506,9 +496,8 @@ void pciehp_green_led_blink(struct slot
+@@ -520,9 +510,8 @@ void pciehp_green_led_blink(struct slot
PCI_EXP_SLTCTL_PWR_IND_BLINK);
}
@@ -988,7 +966,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
struct pci_dev *pdev = ctrl_dev(ctrl);
u16 slot_status;
int retval;
-@@ -532,10 +521,8 @@ int pciehp_power_on_slot(struct slot *sl
+@@ -546,10 +535,8 @@ int pciehp_power_on_slot(struct slot *sl
return retval;
}
@@ -1000,7 +978,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
pcie_write_cmd(ctrl, PCI_EXP_SLTCTL_PWR_OFF, PCI_EXP_SLTCTL_PCC);
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__,
pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL,
-@@ -609,7 +596,6 @@ static irqreturn_t pciehp_isr(int irq, v
+@@ -623,7 +610,6 @@ static irqreturn_t pciehp_isr(int irq, v
static irqreturn_t pciehp_ist(int irq, void *dev_id)
{
struct controller *ctrl = (struct controller *)dev_id;
@@ -1008,7 +986,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
u32 events;
synchronize_hardirq(irq);
-@@ -620,16 +606,16 @@ static irqreturn_t pciehp_ist(int irq, v
+@@ -634,16 +620,16 @@ static irqreturn_t pciehp_ist(int irq, v
/* Check Attention Button Pressed */
if (events & PCI_EXP_SLTSTA_ABP) {
ctrl_info(ctrl, "Slot(%s): Attention button pressed\n",
@@ -1030,7 +1008,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
}
/*
-@@ -638,9 +624,9 @@ static irqreturn_t pciehp_ist(int irq, v
+@@ -652,9 +638,9 @@ static irqreturn_t pciehp_ist(int irq, v
*/
down_read(&ctrl->reset_lock);
if (events & DISABLE_SLOT)
@@ -1042,7 +1020,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
up_read(&ctrl->reset_lock);
wake_up(&ctrl->requester);
-@@ -735,8 +721,7 @@ void pcie_clear_hotplug_events(struct co
+@@ -749,8 +735,7 @@ void pcie_clear_hotplug_events(struct co
*/
int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, int probe)
{
@@ -1052,7 +1030,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
struct pci_dev *pdev = ctrl_dev(ctrl);
u16 stat_mask = 0, ctrl_mask = 0;
int rc;
-@@ -786,42 +771,6 @@ void pcie_shutdown_notification(struct c
+@@ -800,42 +785,6 @@ void pcie_shutdown_notification(struct c
}
}
@@ -1095,9 +1073,9 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
static inline void dbg_ctrl(struct controller *ctrl)
{
struct pci_dev *pdev = ctrl->pcie->port;
-@@ -845,10 +794,11 @@ struct controller *pcie_init(struct pcie
+@@ -859,10 +808,11 @@ struct controller *pcie_init(struct pcie
u32 slot_cap, link_cap;
- u8 occupied, poweron;
+ u8 poweron;
struct pci_dev *pdev = dev->port;
+ struct pci_bus *subordinate = pdev->subordinate;
@@ -1108,7 +1086,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
ctrl->pcie = dev;
pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap);
-@@ -865,11 +815,17 @@ struct controller *pcie_init(struct pcie
+@@ -879,11 +829,17 @@ struct controller *pcie_init(struct pcie
ctrl->slot_cap = slot_cap;
mutex_init(&ctrl->ctrl_lock);
@@ -1126,7 +1104,7 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
/* Check if Data Link Layer Link Active Reporting is implemented */
pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &link_cap);
if (link_cap & PCI_EXP_LNKCAP_DLLLARC)
-@@ -895,33 +851,25 @@ struct controller *pcie_init(struct pcie
+@@ -909,32 +865,24 @@ struct controller *pcie_init(struct pcie
FLAG(link_cap, PCI_EXP_LNKCAP_DLLLARC),
pdev->broken_cmd_compl ? " (with Cmd Compl erratum)" : "");
@@ -1138,11 +1116,9 @@ Signed-off-by: Oliver Neukum <oneukum@suse.com>
* requested yet, so avoid triggering a notification with this command.
*/
if (POWER_CTRL(ctrl)) {
-- pciehp_get_adapter_status(ctrl->slot, &occupied);
- pciehp_get_power_status(ctrl->slot, &poweron);
-+ pciehp_get_adapter_status(ctrl, &occupied);
+ pciehp_get_power_status(ctrl, &poweron);
- if (!occupied && poweron) {
+ if (!pciehp_card_present_or_link_active(ctrl) && poweron) {
pcie_disable_notification(ctrl);
- pciehp_power_off_slot(ctrl->slot);
+ pciehp_power_off_slot(ctrl);
diff --git a/patches.drivers/ALSA-hda-Use-a-macro-for-snd_array-iteration-loops.patch b/patches.drivers/ALSA-hda-Use-a-macro-for-snd_array-iteration-loops.patch
index dad5218ee0..bb568df3b9 100644
--- a/patches.drivers/ALSA-hda-Use-a-macro-for-snd_array-iteration-loops.patch
+++ b/patches.drivers/ALSA-hda-Use-a-macro-for-snd_array-iteration-loops.patch
@@ -4,7 +4,7 @@ Date: Mon, 23 Apr 2018 17:24:56 +0200
Subject: [PATCH] ALSA: hda - Use a macro for snd_array iteration loops
Git-commit: a9c2dfc8527318a27db045cd7ea51e8ecab8c884
Patch-mainline: v4.18-rc1
-References: bsc#1121278
+References: bsc#1051510 bsc#1121278
Introduce a new helper macro, snd_array_for_each(), to iterate for
each snd_array element. It slightly improves the readability than
@@ -19,10 +19,10 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
include/sound/hdaudio.h | 5 +++++
sound/hda/hdac_regmap.c | 4 ++--
- sound/pci/hda/hda_auto_parser.c | 10 ++++-----
- sound/pci/hda/hda_codec.c | 36 ++++++++++++++++-----------------
- sound/pci/hda/hda_generic.c | 27 ++++++++++++-------------
- sound/pci/hda/hda_sysfs.c | 20 +++++++++---------
+ sound/pci/hda/hda_auto_parser.c | 10 +++++-----
+ sound/pci/hda/hda_codec.c | 36 ++++++++++++++++++------------------
+ sound/pci/hda/hda_generic.c | 27 +++++++++++++--------------
+ sound/pci/hda/hda_sysfs.c | 20 ++++++++++----------
sound/pci/hda/patch_conexant.c | 5 ++---
sound/pci/hda/patch_realtek.c | 4 ++--
8 files changed, 57 insertions(+), 54 deletions(-)
@@ -418,5 +418,5 @@ index aef1f52db7d9..7f2d5b157b75 100644
if (pin->nid != mic_pin)
snd_hda_codec_read(codec, pin->nid, 0,
--
-2.20.1
+2.16.4
diff --git a/patches.drivers/ALSA-hda-realtek-Avoid-superfluous-COEF-EAPD-setups.patch b/patches.drivers/ALSA-hda-realtek-Avoid-superfluous-COEF-EAPD-setups.patch
new file mode 100644
index 0000000000..328ce301eb
--- /dev/null
+++ b/patches.drivers/ALSA-hda-realtek-Avoid-superfluous-COEF-EAPD-setups.patch
@@ -0,0 +1,143 @@
+From c9af753f26bdf80291eb2c2279b9de1989fbc591 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Fri, 10 May 2019 11:01:43 +0200
+Subject: [PATCH] ALSA: hda/realtek - Avoid superfluous COEF EAPD setups
+Git-commit: c9af753f26bdf80291eb2c2279b9de1989fbc591
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+Realtek codec driver applied the COEF setups to change the EAPD
+control to the default mode (i.e. control by EPAD verbs) at the init
+callback. It works, but this is too excessive at the same time, since
+it's called at each runtime PM resume. That is, the initialization
+should be done only once after the probe. One may think that moving
+this to the probe should be OK, but no -- there is a catch; when a
+system resumes from S4 (hibernation), we need to re-initialize this
+again manually, because it's out of regcache restoration.
+
+This patch addresses the issue by introducing alc_pre_init() function
+that performs such a task. This is called from each codec probe
+function, and it's called from the resume callback conditionally only
+from S4 resume.
+
+Reported-and-tested-by: Kailang Yang <kailang@realtek.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ sound/pci/hda/patch_realtek.c | 31 ++++++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -509,7 +509,6 @@ static void alc_eapd_shutup(struct hda_c
+ /* generic EAPD initialization */
+ static void alc_auto_init_amp(struct hda_codec *codec, int type)
+ {
+- alc_fill_eapd_coef(codec);
+ alc_auto_setup_eapd(codec, true);
+ alc_write_gpio(codec);
+ switch (type) {
+@@ -837,10 +836,22 @@ static int alc_build_controls(struct hda
+ * Common callbacks
+ */
+
++static void alc_pre_init(struct hda_codec *codec)
++{
++ alc_fill_eapd_coef(codec);
++}
++
++#define is_s4_resume(codec) \
++ ((codec)->core.dev.power.power_state.event == PM_EVENT_RESTORE)
++
+ static int alc_init(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+
++ /* hibernation resume needs the full chip initialization */
++ if (is_s4_resume(codec))
++ alc_pre_init(codec);
++
+ if (spec->init_hook)
+ spec->init_hook(codec);
+
+@@ -1556,6 +1567,8 @@ static int patch_alc880(struct hda_codec
+
+ codec->patch_ops.unsol_event = alc880_unsol_event;
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
+ alc880_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+@@ -1804,6 +1817,8 @@ static int patch_alc260(struct hda_codec
+
+ spec->shutup = alc_eapd_shutup;
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl,
+ alc260_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+@@ -2512,6 +2527,8 @@ static int patch_alc882(struct hda_codec
+ break;
+ }
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
+ alc882_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+@@ -2675,6 +2692,8 @@ static int patch_alc262(struct hda_codec
+ #endif
+ alc_fix_pll_init(codec, 0x20, 0x0a, 10);
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
+ alc262_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+@@ -2816,6 +2835,8 @@ static int patch_alc268(struct hda_codec
+
+ spec->shutup = alc_eapd_shutup;
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
+@@ -7518,6 +7539,8 @@ static int patch_alc269(struct hda_codec
+ spec->init_hook = alc5505_dsp_init;
+ }
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, alc269_fixup_models,
+ alc269_fixup_tbl, alc269_fixups);
+ snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups);
+@@ -7782,6 +7805,8 @@ static int patch_alc861(struct hda_codec
+ spec->power_hook = alc_power_eapd;
+ #endif
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
+@@ -7871,6 +7896,8 @@ static int patch_alc861vd(struct hda_cod
+
+ spec->shutup = alc_eapd_shutup;
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
+ snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
+
+@@ -8592,6 +8619,8 @@ static int patch_alc662(struct hda_codec
+ break;
+ }
+
++ alc_pre_init(codec);
++
+ snd_hda_pick_fixup(codec, alc662_fixup_models,
+ alc662_fixup_tbl, alc662_fixups);
+ snd_hda_pick_pin_fixup(codec, alc662_pin_fixup_tbl, alc662_fixups);
diff --git a/patches.drivers/ALSA-hda-realtek-Corrected-fixup-for-System76-Gazell.patch b/patches.drivers/ALSA-hda-realtek-Corrected-fixup-for-System76-Gazell.patch
new file mode 100644
index 0000000000..1814966393
--- /dev/null
+++ b/patches.drivers/ALSA-hda-realtek-Corrected-fixup-for-System76-Gazell.patch
@@ -0,0 +1,43 @@
+From 891afcf2462d2cc4ef7caf94215358ca61fa32cb Mon Sep 17 00:00:00 2001
+From: Jeremy Soller <jeremy@system76.com>
+Date: Fri, 10 May 2019 10:15:07 -0400
+Subject: [PATCH] ALSA: hda/realtek - Corrected fixup for System76 Gazelle (gaze14)
+Git-commit: 891afcf2462d2cc4ef7caf94215358ca61fa32cb
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+A mistake was made in the identification of the four variants of the
+System76 Gazelle (gaze14). This patch corrects the PCI ID of the
+17-inch, GTX 1660 Ti variant from 0x8560 to 0x8551. This patch also
+adds the correct fixups for the 15-inch and 17-inch GTX 1650 variants
+with PCI IDs 0x8560 and 0x8561.
+
+Tests were done on all four variants ensuring full audio capability.
+
+Fixes: 80a5052db751 ("ALSA: hdea/realtek - Headset fixup for System76 Gazelle (gaze14)")
+Signed-off-by: Jeremy Soller <jeremy@system76.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ sound/pci/hda/patch_realtek.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 2a50e580aa56..3511ea91eae8 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6997,7 +6997,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x1558, 0x1325, "System76 Darter Pro (darp5)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1558, 0x8550, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+- SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
++ SND_PCI_QUIRK(0x1558, 0x8551, "System76 Gazelle (gaze14)", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
++ SND_PCI_QUIRK(0x1558, 0x8560, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
++ SND_PCI_QUIRK(0x1558, 0x8561, "System76 Gazelle (gaze14)", ALC269_FIXUP_HEADSET_MIC),
+ SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC233_FIXUP_LENOVO_MULTI_CODECS),
+ SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
+ SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
+--
+2.16.4
+
diff --git a/patches.drivers/ALSA-hda-realtek-Fix-for-Lenovo-B50-70-inverted-inte.patch b/patches.drivers/ALSA-hda-realtek-Fix-for-Lenovo-B50-70-inverted-inte.patch
new file mode 100644
index 0000000000..8d98d5c0bb
--- /dev/null
+++ b/patches.drivers/ALSA-hda-realtek-Fix-for-Lenovo-B50-70-inverted-inte.patch
@@ -0,0 +1,44 @@
+From 56df90b631fc027fe28b70d41352d820797239bb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Micha=C5=82=20Wadowski?= <wadosm@gmail.com>
+Date: Tue, 14 May 2019 16:58:00 +0200
+Subject: [PATCH] ALSA: hda/realtek - Fix for Lenovo B50-70 inverted internal microphone bug
+Mime-version: 1.0
+Content-type: text/plain; charset=UTF-8
+Content-transfer-encoding: 8bit
+Git-commit: 56df90b631fc027fe28b70d41352d820797239bb
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+Add patch for realtek codec in Lenovo B50-70 that fixes inverted
+internal microphone channel.
+Device IdeaPad Y410P has the same PCI SSID as Lenovo B50-70,
+but first one is about fix the noise and it didn't seem help in a
+later kernel version.
+So I replaced IdeaPad Y410P device description with B50-70 and apply
+inverted microphone fix.
+
+Bugzilla: https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1524215
+Signed-off-by: Michał Wadowski <wadosm@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ sound/pci/hda/patch_realtek.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 3511ea91eae8..f83f21d64dd4 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7042,7 +7042,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
+ SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+ SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
+- SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP),
++ SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
+ SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+ SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC),
+ SND_PCI_QUIRK(0x17aa, 0x501e, "Thinkpad L440", ALC292_FIXUP_TPT440_DOCK),
+--
+2.16.4
+
diff --git a/patches.drivers/ALSA-hda-realtek-Fixup-headphone-noise-via-runtime-s.patch b/patches.drivers/ALSA-hda-realtek-Fixup-headphone-noise-via-runtime-s.patch
new file mode 100644
index 0000000000..8bb6f289b5
--- /dev/null
+++ b/patches.drivers/ALSA-hda-realtek-Fixup-headphone-noise-via-runtime-s.patch
@@ -0,0 +1,113 @@
+From dad3197da7a3817f27bb24f7fd3c135ffa707202 Mon Sep 17 00:00:00 2001
+From: Kailang Yang <kailang@realtek.com>
+Date: Fri, 10 May 2019 16:28:57 +0800
+Subject: [PATCH] ALSA: hda/realtek - Fixup headphone noise via runtime suspend
+Git-commit: dad3197da7a3817f27bb24f7fd3c135ffa707202
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+Dell platform with ALC298.
+system enter to runtime suspend. Headphone had noise.
+Let Headset Mic not shutup will solve this issue.
+
+[ Fixed minor coding style issues by tiwai ]
+
+Signed-off-by: Kailang Yang <kailang@realtek.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ sound/pci/hda/patch_realtek.c | 59 +++++++++++++++++++++++++------------------
+ 1 file changed, 35 insertions(+), 24 deletions(-)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index c53ca589c930..c39f48e02ee9 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -478,12 +478,45 @@ static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
+ set_eapd(codec, *p, on);
+ }
+
++static int find_ext_mic_pin(struct hda_codec *codec);
++
++static void alc_headset_mic_no_shutup(struct hda_codec *codec)
++{
++ const struct hda_pincfg *pin;
++ int mic_pin = find_ext_mic_pin(codec);
++ int i;
++
++ /* don't shut up pins when unloading the driver; otherwise it breaks
++ * the default pin setup at the next load of the driver
++ */
++ if (codec->bus->shutdown)
++ return;
++
++ snd_array_for_each(&codec->init_pins, i, pin) {
++ /* use read here for syncing after issuing each verb */
++ if (pin->nid != mic_pin)
++ snd_hda_codec_read(codec, pin->nid, 0,
++ AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
++ }
++
++ codec->pins_shutup = 1;
++}
++
+ static void alc_shutup_pins(struct hda_codec *codec)
+ {
+ struct alc_spec *spec = codec->spec;
+
+- if (!spec->no_shutup_pins)
+- snd_hda_shutup_pins(codec);
++ switch (codec->core.vendor_id) {
++ case 0x10ec0286:
++ case 0x10ec0288:
++ case 0x10ec0298:
++ alc_headset_mic_no_shutup(codec);
++ break;
++ default:
++ if (!spec->no_shutup_pins)
++ snd_hda_shutup_pins(codec);
++ break;
++ }
+ }
+
+ /* generic shutup callback;
+@@ -2924,27 +2957,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
+ return alc_parse_auto_config(codec, alc269_ignore, ssids);
+ }
+
+-static int find_ext_mic_pin(struct hda_codec *codec);
+-
+-static void alc286_shutup(struct hda_codec *codec)
+-{
+- const struct hda_pincfg *pin;
+- int i;
+- int mic_pin = find_ext_mic_pin(codec);
+- /* don't shut up pins when unloading the driver; otherwise it breaks
+- * the default pin setup at the next load of the driver
+- */
+- if (codec->bus->shutdown)
+- return;
+- snd_array_for_each(&codec->init_pins, i, pin) {
+- /* use read here for syncing after issuing each verb */
+- if (pin->nid != mic_pin)
+- snd_hda_codec_read(codec, pin->nid, 0,
+- AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
+- }
+- codec->pins_shutup = 1;
+-}
+-
+ static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up)
+ {
+ alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0);
+@@ -7736,7 +7748,6 @@ static int patch_alc269(struct hda_codec *codec)
+ case 0x10ec0286:
+ case 0x10ec0288:
+ spec->codec_variant = ALC269_TYPE_ALC286;
+- spec->shutup = alc286_shutup;
+ break;
+ case 0x10ec0298:
+ spec->codec_variant = ALC269_TYPE_ALC298;
+--
+2.16.4
+
diff --git a/patches.drivers/HID-input-add-mapping-for-Expose-Overview-key.patch b/patches.drivers/HID-input-add-mapping-for-Expose-Overview-key.patch
new file mode 100644
index 0000000000..f7893ce1ca
--- /dev/null
+++ b/patches.drivers/HID-input-add-mapping-for-Expose-Overview-key.patch
@@ -0,0 +1,39 @@
+From 96dd86871e1fffbc39e4fa61c9c75ec54ee9af0f Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Fri, 18 Jan 2019 13:59:08 -0800
+Subject: [PATCH] HID: input: add mapping for Expose/Overview key
+Mime-version: 1.0
+Content-type: text/plain; charset=UTF-8
+Content-transfer-encoding: 8bit
+Git-commit: 96dd86871e1fffbc39e4fa61c9c75ec54ee9af0f
+Patch-mainline: v5.1-rc6
+References: bsc#1051510
+
+According to HUTRR77 usage 0x29f from the consumer page is reserved for
+the Desktop application to present all running user’s application windows.
+Linux defines KEY_SCALE to request Compiz Scale (Expose) mode, so let's
+add the mapping.
+
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/hid/hid-input.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index def58c6aa835..5f800e7b04f2 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -1030,6 +1030,8 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
+ case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT); break;
+ case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL); break;
+
++ case 0x29f: map_key_clear(KEY_SCALE); break;
++
+ default: map_key_clear(KEY_UNKNOWN);
+ }
+ break;
+--
+2.16.4
+
diff --git a/patches.drivers/HID-input-add-mapping-for-Toggle-Display-key.patch b/patches.drivers/HID-input-add-mapping-for-Toggle-Display-key.patch
new file mode 100644
index 0000000000..106c5c7a36
--- /dev/null
+++ b/patches.drivers/HID-input-add-mapping-for-Toggle-Display-key.patch
@@ -0,0 +1,41 @@
+From c01908a14bf735b871170092807c618bb9dae654 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Fri, 18 Jan 2019 14:35:45 -0800
+Subject: [PATCH] HID: input: add mapping for "Toggle Display" key
+Git-commit: c01908a14bf735b871170092807c618bb9dae654
+Patch-mainline: v5.1-rc6
+References: bsc#1051510
+
+According to HUT 1.12 usage 0xb5 from the generic desktop page is reserved
+for switching between external and internal display, so let's add the
+mapping.
+
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/hid/hid-input.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index ecb1b6f26853..da76358cde06 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -677,6 +677,14 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
+ break;
+ }
+
++ if ((usage->hid & 0xf0) == 0xb0) { /* SC - Display */
++ switch (usage->hid & 0xf) {
++ case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
++ default: goto ignore;
++ }
++ break;
++ }
++
+ /*
+ * Some lazy vendors declare 255 usages for System Control,
+ * leading to the creation of ABS_X|Y axis and too many others.
+--
+2.16.4
+
diff --git a/patches.drivers/HID-input-add-mapping-for-keyboard-Brightness-Up-Dow.patch b/patches.drivers/HID-input-add-mapping-for-keyboard-Brightness-Up-Dow.patch
new file mode 100644
index 0000000000..4c91542c96
--- /dev/null
+++ b/patches.drivers/HID-input-add-mapping-for-keyboard-Brightness-Up-Dow.patch
@@ -0,0 +1,36 @@
+From 7975a1d6a7afeb3eb61c971a153d24dd8fa032f3 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Fri, 18 Jan 2019 14:05:52 -0800
+Subject: [PATCH] HID: input: add mapping for keyboard Brightness Up/Down/Toggle keys
+Git-commit: 7975a1d6a7afeb3eb61c971a153d24dd8fa032f3
+Patch-mainline: v5.1-rc6
+References: bsc#1051510
+
+According to HUTRR73 usages 0x79, 0x7a and 0x7c from the consumer page
+correspond to Brightness Up/Down/Toggle keys, so let's add the mappings.
+
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/hid/hid-input.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
+index 5f800e7b04f2..cebe8a8cce2e 100644
+--- a/drivers/hid/hid-input.c
++++ b/drivers/hid/hid-input.c
+@@ -900,6 +900,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
+ case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX); break;
+ case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO); break;
+
++ case 0x079: map_key_clear(KEY_KBDILLUMUP); break;
++ case 0x07a: map_key_clear(KEY_KBDILLUMDOWN); break;
++ case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE); break;
++
+ case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
+ case 0x083: map_key_clear(KEY_LAST); break;
+ case 0x084: map_key_clear(KEY_ENTER); break;
+--
+2.16.4
+
diff --git a/patches.drivers/Input-elan_i2c-add-hardware-ID-for-multiple-Lenovo-l.patch b/patches.drivers/Input-elan_i2c-add-hardware-ID-for-multiple-Lenovo-l.patch
new file mode 100644
index 0000000000..daab894a07
--- /dev/null
+++ b/patches.drivers/Input-elan_i2c-add-hardware-ID-for-multiple-Lenovo-l.patch
@@ -0,0 +1,70 @@
+From 738c06d0e4562e0acf9f2c7438a22b2d5afc67aa Mon Sep 17 00:00:00 2001
+From: KT Liao <kt.liao@emc.com.tw>
+Date: Tue, 26 Mar 2019 17:28:32 -0700
+Subject: [PATCH] Input: elan_i2c - add hardware ID for multiple Lenovo laptops
+Git-commit: 738c06d0e4562e0acf9f2c7438a22b2d5afc67aa
+Patch-mainline: v5.1-rc6
+References: bsc#1051510
+
+There are many Lenovo laptops which need elan_i2c support, this patch adds
+relevant IDs to the Elan driver so that touchpads are recognized.
+
+Signed-off-by: KT Liao <kt.liao@emc.com.tw>
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/input/mouse/elan_i2c_core.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/input/mouse/elan_i2c_core.c
++++ b/drivers/input/mouse/elan_i2c_core.c
+@@ -1225,22 +1225,47 @@ static const struct acpi_device_id elan_
+ { "ELAN0600", 0 },
+ { "ELAN0601", 0 },
+ { "ELAN0602", 0 },
++ { "ELAN0603", 0 },
++ { "ELAN0604", 0 },
+ { "ELAN0605", 0 },
++ { "ELAN0606", 0 },
++ { "ELAN0607", 0 },
+ { "ELAN0608", 0 },
+ { "ELAN0605", 0 },
+ { "ELAN0609", 0 },
+ { "ELAN060B", 0 },
+ { "ELAN060C", 0 },
++ { "ELAN060F", 0 },
++ { "ELAN0610", 0 },
+ { "ELAN0611", 0 },
+ { "ELAN0612", 0 },
++ { "ELAN0615", 0 },
++ { "ELAN0616", 0 },
+ { "ELAN0617", 0 },
+ { "ELAN0618", 0 },
++ { "ELAN0619", 0 },
++ { "ELAN061A", 0 },
++ { "ELAN061B", 0 },
+ { "ELAN061C", 0 },
+ { "ELAN061D", 0 },
+ { "ELAN061E", 0 },
++ { "ELAN061F", 0 },
+ { "ELAN0620", 0 },
+ { "ELAN0621", 0 },
+ { "ELAN0622", 0 },
++ { "ELAN0623", 0 },
++ { "ELAN0624", 0 },
++ { "ELAN0625", 0 },
++ { "ELAN0626", 0 },
++ { "ELAN0627", 0 },
++ { "ELAN0628", 0 },
++ { "ELAN0629", 0 },
++ { "ELAN062A", 0 },
++ { "ELAN062B", 0 },
++ { "ELAN062C", 0 },
++ { "ELAN062D", 0 },
++ { "ELAN0631", 0 },
++ { "ELAN0632", 0 },
+ { "ELAN1000", 0 },
+ { }
+ };
diff --git a/patches.drivers/Input-synaptics-rmi4-fix-possible-double-free.patch b/patches.drivers/Input-synaptics-rmi4-fix-possible-double-free.patch
new file mode 100644
index 0000000000..53b55e4051
--- /dev/null
+++ b/patches.drivers/Input-synaptics-rmi4-fix-possible-double-free.patch
@@ -0,0 +1,47 @@
+From bce1a78423961fce676ac65540a31b6ffd179e6d Mon Sep 17 00:00:00 2001
+From: Pan Bian <bianpan2016@163.com>
+Date: Fri, 19 Apr 2019 07:39:00 +0000
+Subject: [PATCH] Input: synaptics-rmi4 - fix possible double free
+Git-commit: bce1a78423961fce676ac65540a31b6ffd179e6d
+Patch-mainline: v5.1-rc7
+References: bsc#1051510
+
+The RMI4 function structure has been released in rmi_register_function
+if error occurs. However, it will be released again in the function
+rmi_create_function, which may result in a double-free bug.
+
+Signed-off-by: Pan Bian <bianpan2016@163.com>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/input/rmi4/rmi_driver.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
+index fc3ab93b7aea..7fb358f96195 100644
+--- a/drivers/input/rmi4/rmi_driver.c
++++ b/drivers/input/rmi4/rmi_driver.c
+@@ -860,7 +860,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
+
+ error = rmi_register_function(fn);
+ if (error)
+- goto err_put_fn;
++ return error;
+
+ if (pdt->function_number == 0x01)
+ data->f01_container = fn;
+@@ -870,10 +870,6 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
+ list_add_tail(&fn->node, &data->function_list);
+
+ return RMI_SCAN_CONTINUE;
+-
+-err_put_fn:
+- put_device(&fn->dev);
+- return error;
+ }
+
+ void rmi_enable_irq(struct rmi_device *rmi_dev, bool clear_wake)
+--
+2.16.4
+
diff --git a/patches.drivers/ath10k-snoc-fix-unbalanced-clock-error-handling.patch b/patches.drivers/ath10k-snoc-fix-unbalanced-clock-error-handling.patch
new file mode 100644
index 0000000000..95128e2ba8
--- /dev/null
+++ b/patches.drivers/ath10k-snoc-fix-unbalanced-clock-error-handling.patch
@@ -0,0 +1,39 @@
+From 82e60d920e8ad70cd9a280ab156566755f1fe4aa Mon Sep 17 00:00:00 2001
+From: Brian Norris <briannorris@chromium.org>
+Date: Mon, 5 Nov 2018 14:35:22 +0200
+Subject: [PATCH] ath10k: snoc: fix unbalanced clock error handling
+Git-commit: 82e60d920e8ad70cd9a280ab156566755f1fe4aa
+Patch-mainline: v5.0-rc1
+References: bsc#1111666
+
+Similar to regulator error handling, we should only start tearing down
+the 'i - 1' clock when clock 'i' fails to enable. Otherwise, we might
+end up with an unbalanced clock, where we never successfully enabled the
+clock, but we try to disable it anyway.
+
+Fixes: a6a793f98786 ("ath10k: vote for hardware resources for WCN3990")
+Signed-off-by: Brian Norris <briannorris@chromium.org>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/net/wireless/ath/ath10k/snoc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
+index 48292ed7d494..81b86a787c34 100644
+--- a/drivers/net/wireless/ath/ath10k/snoc.c
++++ b/drivers/net/wireless/ath/ath10k/snoc.c
+@@ -1494,7 +1494,7 @@ static int ath10k_snoc_clk_init(struct ath10k *ar)
+ return 0;
+
+ err_clock_config:
+- for (; i >= 0; i--) {
++ for (i = i - 1; i >= 0; i--) {
+ clk_info = &ar_snoc->clk[i];
+
+ if (!clk_info->handle)
+--
+2.16.4
+
diff --git a/patches.drivers/iio-adc-xilinx-fix-potential-use-after-free-on-remov.patch b/patches.drivers/iio-adc-xilinx-fix-potential-use-after-free-on-remov.patch
new file mode 100644
index 0000000000..94befeb519
--- /dev/null
+++ b/patches.drivers/iio-adc-xilinx-fix-potential-use-after-free-on-remov.patch
@@ -0,0 +1,35 @@
+From 62039b6aef63380ba7a37c113bbaeee8a55c5342 Mon Sep 17 00:00:00 2001
+From: Sven Van Asbroeck <thesven73@gmail.com>
+Date: Sun, 10 Mar 2019 14:58:24 -0400
+Subject: [PATCH] iio: adc: xilinx: fix potential use-after-free on remove
+Git-commit: 62039b6aef63380ba7a37c113bbaeee8a55c5342
+Patch-mainline: v5.1-rc6
+References: bsc#1051510
+
+When cancel_delayed_work() returns, the delayed work may still
+be running. This means that the core could potentially free
+the private structure (struct xadc) while the delayed work
+is still using it. This is a potential use-after-free.
+
+Fix by calling cancel_delayed_work_sync(), which waits for
+any residual work to finish before returning.
+
+Signed-off-by: Sven Van Asbroeck <TheSven73@gmail.com>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/iio/adc/xilinx-xadc-core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/adc/xilinx-xadc-core.c
++++ b/drivers/iio/adc/xilinx-xadc-core.c
+@@ -1299,7 +1299,7 @@ static int xadc_remove(struct platform_d
+ }
+ free_irq(irq, indio_dev);
+ clk_disable_unprepare(xadc->clk);
+- cancel_delayed_work(&xadc->zynq_unmask_work);
++ cancel_delayed_work_sync(&xadc->zynq_unmask_work);
+ kfree(xadc->data);
+ kfree(indio_dev->channels);
+
diff --git a/patches.drivers/iommu-arm-smmu-v3-Don-t-disable-SMMU-in-kdump-kernel.patch b/patches.drivers/iommu-arm-smmu-v3-Don-t-disable-SMMU-in-kdump-kernel.patch
index d062b08630..e7c429d553 100644
--- a/patches.drivers/iommu-arm-smmu-v3-Don-t-disable-SMMU-in-kdump-kernel.patch
+++ b/patches.drivers/iommu-arm-smmu-v3-Don-t-disable-SMMU-in-kdump-kernel.patch
@@ -2,8 +2,7 @@ From: Will Deacon <will.deacon@arm.com>
Date: Tue, 23 Apr 2019 11:59:36 +0100
Subject: iommu/arm-smmu-v3: Don't disable SMMU in kdump kernel
Git-commit: 3f54c447df34ff9efac7809a4a80fd3208efc619
-Patch-mainline: Queued in subsystem maintainer repository
-Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git
+Patch-mainline: v5.2-rc1
References: bsc#1120566
Disabling the SMMU when probing from within a kdump kernel so that all
diff --git a/patches.drivers/ipmi-Prevent-use-after-free-in-deliver_response.patch b/patches.drivers/ipmi-Prevent-use-after-free-in-deliver_response.patch
new file mode 100644
index 0000000000..c96b6dc4c5
--- /dev/null
+++ b/patches.drivers/ipmi-Prevent-use-after-free-in-deliver_response.patch
@@ -0,0 +1,74 @@
+From 479d6b39b9e0d2de648ebf146f23a1e40962068f Mon Sep 17 00:00:00 2001
+From: Fred Klassen <fklassen@appneta.com>
+Date: Sat, 19 Jan 2019 14:28:18 -0800
+Subject: [PATCH] ipmi: Prevent use-after-free in deliver_response
+Git-commit: 479d6b39b9e0d2de648ebf146f23a1e40962068f
+Patch-mainline: v5.0-rc4
+References: bsc#1111666
+
+Some IPMI modules (e.g. ibmpex_msg_handler()) will have ipmi_usr_hdlr
+handlers that call ipmi_free_recv_msg() directly. This will essentially
+kfree(msg), leading to use-after-free.
+
+This does not happen in the ipmi_devintf module, which will queue the
+message and run ipmi_free_recv_msg() later.
+
+Bug: KASAN: use-after-free in deliver_response+0x12f/0x1b0
+Read of size 8 at addr ffff888a7bf20018 by task ksoftirqd/3/27
+Cpu: 3 PID: 27 Comm: ksoftirqd/3 Tainted: G O 4.19.11-amd64-ani99-debug #12.0.1.601133+pv
+Hardware name: AppNeta r1000/X11SPW-TF, BIOS 2.1a-AP 09/17/2018
+Call Trace:
+dump_stack+0x92/0xeb
+print_address_description+0x73/0x290
+kasan_report+0x258/0x380
+deliver_response+0x12f/0x1b0
+? ipmi_free_recv_msg+0x50/0x50
+deliver_local_response+0xe/0x50
+handle_one_recv_msg+0x37a/0x21d0
+handle_new_recv_msgs+0x1ce/0x440
+...
+
+Allocated by task 9885:
+kasan_kmalloc+0xa0/0xd0
+kmem_cache_alloc_trace+0x116/0x290
+ipmi_alloc_recv_msg+0x28/0x70
+i_ipmi_request+0xb4a/0x1640
+ipmi_request_settime+0x1b8/0x1e0
+...
+
+Freed by task 27:
+__kasan_slab_free+0x12e/0x180
+kfree+0xe9/0x280
+deliver_response+0x122/0x1b0
+deliver_local_response+0xe/0x50
+handle_one_recv_msg+0x37a/0x21d0
+handle_new_recv_msgs+0x1ce/0x440
+tasklet_action_common.isra.19+0xc4/0x250
+__do_softirq+0x11f/0x51f
+
+Fixes: e86ee2d44b44 ("ipmi: Rework locking and shutdown for hot remove")
+Cc: stable@vger.kernel.org # 4.18
+Signed-off-by: Fred Klassen <fklassen@appneta.com>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/char/ipmi/ipmi_msghandler.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 7a9fbe60a840..cc5665c47a0e 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -885,7 +885,7 @@ static int deliver_response(struct ipmi_smi *intf, struct ipmi_recv_msg *msg)
+
+ if (user) {
+ user->handler->ipmi_recv_hndl(msg, user->handler_data);
+- release_ipmi_user(msg->user, index);
++ release_ipmi_user(user, index);
+ } else {
+ /* User went away, give up. */
+ ipmi_free_recv_msg(msg);
+--
+2.16.4
+
diff --git a/patches.drivers/ipmi-fix-sleep-in-atomic-in-free_user-at-cleanup-SRC.patch b/patches.drivers/ipmi-fix-sleep-in-atomic-in-free_user-at-cleanup-SRC.patch
new file mode 100644
index 0000000000..d37d0eb6f8
--- /dev/null
+++ b/patches.drivers/ipmi-fix-sleep-in-atomic-in-free_user-at-cleanup-SRC.patch
@@ -0,0 +1,100 @@
+From 3b9a907223d7f6b9d1dadea29436842ae9bcd76d Mon Sep 17 00:00:00 2001
+From: Corey Minyard <cminyard@mvista.com>
+Date: Wed, 3 Apr 2019 15:58:16 -0500
+Subject: [PATCH] ipmi: fix sleep-in-atomic in free_user at cleanup SRCU user->release_barrier
+Git-commit: 3b9a907223d7f6b9d1dadea29436842ae9bcd76d
+Patch-mainline: v5.1-rc6
+References: bsc#1111666
+
+free_user() could be called in atomic context.
+
+This patch pushed the free operation off into a workqueue.
+
+Example:
+
+ BUG: sleeping function called from invalid context at kernel/workqueue.c:2856
+ in_atomic(): 1, irqs_disabled(): 0, pid: 177, name: ksoftirqd/27
+ CPU: 27 PID: 177 Comm: ksoftirqd/27 Not tainted 4.19.25-3 #1
+ Hardware name: AIC 1S-HV26-08/MB-DPSB04-06, BIOS IVYBV060 10/21/2015
+ Call Trace:
+ dump_stack+0x5c/0x7b
+ ___might_sleep+0xec/0x110
+ __flush_work+0x48/0x1f0
+ ? try_to_del_timer_sync+0x4d/0x80
+ _cleanup_srcu_struct+0x104/0x140
+ free_user+0x18/0x30 [ipmi_msghandler]
+ ipmi_free_recv_msg+0x3a/0x50 [ipmi_msghandler]
+ deliver_response+0xbd/0xd0 [ipmi_msghandler]
+ deliver_local_response+0xe/0x30 [ipmi_msghandler]
+ handle_one_recv_msg+0x163/0xc80 [ipmi_msghandler]
+ ? dequeue_entity+0xa0/0x960
+ handle_new_recv_msgs+0x15c/0x1f0 [ipmi_msghandler]
+ tasklet_action_common.isra.22+0x103/0x120
+ __do_softirq+0xf8/0x2d7
+ run_ksoftirqd+0x26/0x50
+ smpboot_thread_fn+0x11d/0x1e0
+ kthread+0x103/0x140
+ ? sort_range+0x20/0x20
+ ? kthread_destroy_worker+0x40/0x40
+ ret_from_fork+0x1f/0x40
+
+Fixes: 77f8269606bf ("ipmi: fix use-after-free of user->release_barrier.rda")
+
+Reported-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
+Signed-off-by: Corey Minyard <cminyard@mvista.com>
+Cc: stable@vger.kernel.org # 5.0
+Cc: Yang Yingliang <yangyingliang@huawei.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/char/ipmi/ipmi_msghandler.c | 18 ++++++++++++++++--
+ 1 file changed, 16 insertions(+), 2 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -215,6 +215,9 @@ struct ipmi_user {
+
+ /* Does this interface receive IPMI events? */
+ bool gets_events;
++
++ /* Free must run in process context for RCU cleanup. */
++ struct work_struct remove_work;
+ };
+
+ static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index)
+@@ -1088,6 +1091,14 @@ static int intf_err_seq(struct ipmi_smi
+ return rv;
+ }
+
++static void free_user_work(struct work_struct *work)
++{
++ struct ipmi_user *user = container_of(work, struct ipmi_user,
++ remove_work);
++
++ cleanup_srcu_struct(&user->release_barrier);
++ kfree(user);
++}
+
+ int ipmi_create_user(unsigned int if_num,
+ const struct ipmi_user_hndl *handler,
+@@ -1141,6 +1152,8 @@ int ipmi_create_user(unsigned int
+ goto out_kfree;
+
+ found:
++ INIT_WORK(&new_user->remove_work, free_user_work);
++
+ rv = init_srcu_struct(&new_user->release_barrier);
+ if (rv)
+ goto out_kfree;
+@@ -1203,8 +1216,9 @@ EXPORT_SYMBOL(ipmi_get_smi_info);
+ static void free_user(struct kref *ref)
+ {
+ struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
+- cleanup_srcu_struct(&user->release_barrier);
+- kfree(user);
++
++ /* SRCU cleanup must happen in task context. */
++ schedule_work(&user->remove_work);
+ }
+
+ static void _ipmi_destroy_user(struct ipmi_user *user)
diff --git a/patches.drivers/iw_cxgb4-only-allow-1-flush-on-user-qps.patch b/patches.drivers/iw_cxgb4-only-allow-1-flush-on-user-qps.patch
index 2c31435895..a859fb5f5f 100644
--- a/patches.drivers/iw_cxgb4-only-allow-1-flush-on-user-qps.patch
+++ b/patches.drivers/iw_cxgb4-only-allow-1-flush-on-user-qps.patch
@@ -1,9 +1,10 @@
+From 308aa2b8f7b7db3332a7d41099fd37851fb793b2 Mon Sep 17 00:00:00 2001
From: Steve Wise <swise@opengridcomputing.com>
Date: Fri, 31 Aug 2018 07:15:56 -0700
-Subject: iw_cxgb4: only allow 1 flush on user qps
-Patch-mainline: v4.19-rc4
+Subject: [PATCH] iw_cxgb4: only allow 1 flush on user qps
Git-commit: 308aa2b8f7b7db3332a7d41099fd37851fb793b2
-References: bsc#1104276 FATE#325935
+Patch-mainline: v4.19-rc4
+References: bsc#1051510 bsc#1104276 FATE#325935
Once the qp has been flushed, it cannot be flushed again. The user qp
flush logic wasn't enforcing it however. The bug can cause
diff --git a/patches.drivers/leds-pwm-silently-error-out-on-EPROBE_DEFER.patch b/patches.drivers/leds-pwm-silently-error-out-on-EPROBE_DEFER.patch
new file mode 100644
index 0000000000..f690b8f16b
--- /dev/null
+++ b/patches.drivers/leds-pwm-silently-error-out-on-EPROBE_DEFER.patch
@@ -0,0 +1,38 @@
+From 9aec30371fb095a0c9415f3f0146ae269c3713d8 Mon Sep 17 00:00:00 2001
+From: Jerome Brunet <jbrunet@baylibre.com>
+Date: Thu, 6 Sep 2018 15:59:04 +0200
+Subject: [PATCH] leds: pwm: silently error out on EPROBE_DEFER
+Git-commit: 9aec30371fb095a0c9415f3f0146ae269c3713d8
+Patch-mainline: v4.20-rc1
+References: bsc#1051510
+
+When probing, if we fail to get the pwm due to probe deferal, we shouldn't
+print an error message. Just be silent in this case.
+
+Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
+Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/leds/leds-pwm.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
+index df80c89ebe7f..5d3faae51d59 100644
+--- a/drivers/leds/leds-pwm.c
++++ b/drivers/leds/leds-pwm.c
+@@ -100,8 +100,9 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv,
+ led_data->pwm = devm_pwm_get(dev, led->name);
+ if (IS_ERR(led_data->pwm)) {
+ ret = PTR_ERR(led_data->pwm);
+- dev_err(dev, "unable to request PWM for %s: %d\n",
+- led->name, ret);
++ if (ret != -EPROBE_DEFER)
++ dev_err(dev, "unable to request PWM for %s: %d\n",
++ led->name, ret);
+ return ret;
+ }
+
+--
+2.16.4
+
diff --git a/patches.drivers/mac8390-Fix-mmio-access-size-probe.patch b/patches.drivers/mac8390-Fix-mmio-access-size-probe.patch
new file mode 100644
index 0000000000..47b238ce12
--- /dev/null
+++ b/patches.drivers/mac8390-Fix-mmio-access-size-probe.patch
@@ -0,0 +1,74 @@
+From bb9e5c5bcd76f4474eac3baf643d7a39f7bac7bb Mon Sep 17 00:00:00 2001
+From: Finn Thain <fthain@telegraphics.com.au>
+Date: Sat, 16 Mar 2019 14:21:19 +1100
+Subject: [PATCH] mac8390: Fix mmio access size probe
+Git-commit: bb9e5c5bcd76f4474eac3baf643d7a39f7bac7bb
+Patch-mainline: v5.1-rc3
+References: bsc#1051510
+
+The bug that Stan reported is as follows. After a restart, a 16-bit NIC
+may be incorrectly identified as a 32-bit NIC and stop working.
+
+mac8390 slot.E: Memory length resource not found, probing
+mac8390 slot.E: Farallon EtherMac II-C (type farallon)
+mac8390 slot.E: MAC 00:00:c5:30:c2:99, IRQ 61, 32 KB shared memory at 0xfeed0000, 32-bit access.
+
+The bug never arises after a cold start and only intermittently after a
+warm start. (I didn't investigate why the bug is intermittent.)
+
+It turns out that memcpy_toio() is deprecated and memcmp_withio() also
+has issues. Replacing these calls with mmio accessors fixes the problem.
+
+Reported-and-tested-by: Stan Johnson <userm57@yahoo.com>
+Fixes: 2964db0f5904 ("m68k: Mac DP8390 update")
+Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/net/ethernet/8390/mac8390.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/8390/mac8390.c
++++ b/drivers/net/ethernet/8390/mac8390.c
+@@ -156,8 +156,6 @@ static void dayna_block_output(struct ne
+ #define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c))
+ #define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c))
+
+-#define memcmp_withio(a, b, c) memcmp((a), (void *)(b), (c))
+-
+ /* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */
+ static void slow_sane_get_8390_hdr(struct net_device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page);
+@@ -237,19 +235,26 @@ static enum mac8390_type __init mac8390_
+
+ static enum mac8390_access __init mac8390_testio(volatile unsigned long membase)
+ {
+- unsigned long outdata = 0xA5A0B5B0;
+- unsigned long indata = 0x00000000;
++ u32 outdata = 0xA5A0B5B0;
++ u32 indata = 0;
++
+ /* Try writing 32 bits */
+- memcpy_toio(membase, &outdata, 4);
+- /* Now compare them */
+- if (memcmp_withio(&outdata, membase, 4) == 0)
++ nubus_writel(outdata, membase);
++ /* Now read it back */
++ indata = nubus_readl(membase);
++ if (outdata == indata)
+ return ACCESS_32;
++
++ outdata = 0xC5C0D5D0;
++ indata = 0;
++
+ /* Write 16 bit output */
+ word_memcpy_tocard(membase, &outdata, 4);
+ /* Now read it back */
+ word_memcpy_fromcard(&indata, membase, 4);
+ if (outdata == indata)
+ return ACCESS_16;
++
+ return ACCESS_UNKNOWN;
+ }
+
diff --git a/patches.drivers/media-atmel-atmel-isc-fix-INIT_WORK-misplacement.patch b/patches.drivers/media-atmel-atmel-isc-fix-INIT_WORK-misplacement.patch
new file mode 100644
index 0000000000..91b7299f76
--- /dev/null
+++ b/patches.drivers/media-atmel-atmel-isc-fix-INIT_WORK-misplacement.patch
@@ -0,0 +1,46 @@
+From 79199002db5c571e335131856b3ff057ffd9f3c0 Mon Sep 17 00:00:00 2001
+From: Eugen Hristev <eugen.hristev@microchip.com>
+Date: Fri, 12 Apr 2019 06:19:46 -0400
+Subject: [PATCH] media: atmel: atmel-isc: fix INIT_WORK misplacement
+Git-commit: 79199002db5c571e335131856b3ff057ffd9f3c0
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+In case the completion function failes, unbind will be called
+which will call cancel_work for awb_work.
+This will trigger a WARN message from the workqueue.
+To avoid this, move the INIT_WORK call at the start of the completion
+function. This way the work is always initialized, which corresponds
+to the 'always canceled' unbind code.
+
+Fixes: 93d4a26c3d ("[media] atmel-isc: add the isc pipeline function")
+
+Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/media/platform/atmel/atmel-isc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/media/platform/atmel/atmel-isc.c
++++ b/drivers/media/platform/atmel/atmel-isc.c
+@@ -1553,6 +1553,8 @@ static int isc_async_complete(struct v4l
+ struct vb2_queue *q = &isc->vb2_vidq;
+ int ret;
+
++ INIT_WORK(&isc->awb_work, isc_awb_work);
++
+ ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
+ if (ret < 0) {
+ v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n");
+@@ -1612,8 +1614,6 @@ static int isc_async_complete(struct v4l
+ return ret;
+ }
+
+- INIT_WORK(&isc->awb_work, isc_awb_work);
+-
+ /* Register video device */
+ strlcpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name));
+ vdev->release = video_device_release_empty;
diff --git a/patches.drivers/media-davinci-vpbe-array-underflow-in-vpbe_enum_outp.patch b/patches.drivers/media-davinci-vpbe-array-underflow-in-vpbe_enum_outp.patch
new file mode 100644
index 0000000000..94c1d793fa
--- /dev/null
+++ b/patches.drivers/media-davinci-vpbe-array-underflow-in-vpbe_enum_outp.patch
@@ -0,0 +1,54 @@
+From b72845ee5577b227131b1fef23f9d9a296621d7b Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Wed, 24 Apr 2019 05:46:27 -0400
+Subject: [PATCH] media: davinci/vpbe: array underflow in vpbe_enum_outputs()
+Git-commit: b72845ee5577b227131b1fef23f9d9a296621d7b
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+In vpbe_enum_outputs() we check if (temp_index >= cfg->num_outputs) but
+the problem is that "temp_index" can be negative. This patch changes
+the types to unsigned to address this array underflow bug.
+
+Fixes: 66715cdc3224 ("[media] davinci vpbe: VPBE display driver")
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Acked-by: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/media/platform/davinci/vpbe.c | 2 +-
+ include/media/davinci/vpbe.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/media/platform/davinci/vpbe.c b/drivers/media/platform/davinci/vpbe.c
+index 8339163a5231..4e24f5d781f4 100644
+--- a/drivers/media/platform/davinci/vpbe.c
++++ b/drivers/media/platform/davinci/vpbe.c
+@@ -104,7 +104,7 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev,
+ struct v4l2_output *output)
+ {
+ struct vpbe_config *cfg = vpbe_dev->cfg;
+- int temp_index = output->index;
++ unsigned int temp_index = output->index;
+
+ if (temp_index >= cfg->num_outputs)
+ return -EINVAL;
+diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h
+index 5c31a7682492..f76d2f25a824 100644
+--- a/include/media/davinci/vpbe.h
++++ b/include/media/davinci/vpbe.h
+@@ -92,7 +92,7 @@ struct vpbe_config {
+ struct encoder_config_info *ext_encoders;
+ /* amplifier information goes here */
+ struct amp_config_info *amp;
+- int num_outputs;
++ unsigned int num_outputs;
+ /* Order is venc outputs followed by LCD and then external encoders */
+ struct vpbe_output *outputs;
+ };
+--
+2.16.4
+
diff --git a/patches.drivers/media-omap_vout-potential-buffer-overflow-in-vidioc_.patch b/patches.drivers/media-omap_vout-potential-buffer-overflow-in-vidioc_.patch
new file mode 100644
index 0000000000..04f40a3fb0
--- /dev/null
+++ b/patches.drivers/media-omap_vout-potential-buffer-overflow-in-vidioc_.patch
@@ -0,0 +1,68 @@
+From dd6e2a981bfe83aa4a493143fd8cf1edcda6c091 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 11 Apr 2019 05:01:57 -0400
+Subject: [PATCH] media: omap_vout: potential buffer overflow in vidioc_dqbuf()
+Git-commit: dd6e2a981bfe83aa4a493143fd8cf1edcda6c091
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+The "b->index" is a u32 the comes from the user in the ioctl. It hasn't
+been checked. We aren't supposed to use it but we're instead supposed
+to use the value that gets written to it when we call videobuf_dqbuf().
+
+The videobuf_dqbuf() first memsets it to zero and then re-initializes it
+inside the videobuf_status() function. It's this final value which we
+want.
+
+Hans Verkuil pointed out that we need to check the return from
+videobuf_dqbuf(). I ended up doing a little cleanup related to that as
+well.
+
+Fixes: 72915e851da9 ("[media] V4L2: OMAP: VOUT: dma map and unmap v4l2 buffers in qbuf and dqbuf")
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
+Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/media/platform/omap/omap_vout.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c
+index 37f0d7146dfa..cb6a9e3946b6 100644
+--- a/drivers/media/platform/omap/omap_vout.c
++++ b/drivers/media/platform/omap/omap_vout.c
+@@ -1527,23 +1527,20 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
+ unsigned long size;
+ struct videobuf_buffer *vb;
+
+- vb = q->bufs[b->index];
+-
+ if (!vout->streaming)
+ return -EINVAL;
+
+- if (file->f_flags & O_NONBLOCK)
+- /* Call videobuf_dqbuf for non blocking mode */
+- ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 1);
+- else
+- /* Call videobuf_dqbuf for blocking mode */
+- ret = videobuf_dqbuf(q, (struct v4l2_buffer *)b, 0);
++ ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK));
++ if (ret)
++ return ret;
++
++ vb = q->bufs[b->index];
+
+ addr = (unsigned long) vout->buf_phy_addr[vb->i];
+ size = (unsigned long) vb->size;
+ dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr,
+ size, DMA_TO_DEVICE);
+- return ret;
++ return 0;
+ }
+
+ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
+--
+2.16.4
+
diff --git a/patches.drivers/power-supply-axp20x_usb_power-Fix-typo-in-VBUS-curre.patch b/patches.drivers/power-supply-axp20x_usb_power-Fix-typo-in-VBUS-curre.patch
new file mode 100644
index 0000000000..f842e339af
--- /dev/null
+++ b/patches.drivers/power-supply-axp20x_usb_power-Fix-typo-in-VBUS-curre.patch
@@ -0,0 +1,66 @@
+From c11f0b8f226a411915f8d7467bd554a8c9ceec42 Mon Sep 17 00:00:00 2001
+From: Chen-Yu Tsai <wens@csie.org>
+Date: Tue, 16 Apr 2019 14:40:19 +0800
+Subject: [PATCH] power: supply: axp20x_usb_power: Fix typo in VBUS current limit macros
+Git-commit: c11f0b8f226a411915f8d7467bd554a8c9ceec42
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+The VBUS current limit value macros have VBUS typed as VBUC, while
+the bitmask macro is named correctly. Fix it.
+
+Fixes: 69fb4dcada77 ("power: Add an axp20x-usb-power driver")
+Signed-off-by: Chen-Yu Tsai <wens@csie.org>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/power/supply/axp20x_usb_power.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/power/supply/axp20x_usb_power.c b/drivers/power/supply/axp20x_usb_power.c
+index f52fe77edb6f..cd9b90d79839 100644
+--- a/drivers/power/supply/axp20x_usb_power.c
++++ b/drivers/power/supply/axp20x_usb_power.c
+@@ -36,10 +36,10 @@
+ #define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
+ #define AXP20X_VBUS_VHOLD_OFFSET 3
+ #define AXP20X_VBUS_CLIMIT_MASK 3
+-#define AXP20X_VBUC_CLIMIT_900mA 0
+-#define AXP20X_VBUC_CLIMIT_500mA 1
+-#define AXP20X_VBUC_CLIMIT_100mA 2
+-#define AXP20X_VBUC_CLIMIT_NONE 3
++#define AXP20X_VBUS_CLIMIT_900mA 0
++#define AXP20X_VBUS_CLIMIT_500mA 1
++#define AXP20X_VBUS_CLIMIT_100mA 2
++#define AXP20X_VBUS_CLIMIT_NONE 3
+
+ #define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
+ #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
+@@ -107,19 +107,19 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
+ return ret;
+
+ switch (v & AXP20X_VBUS_CLIMIT_MASK) {
+- case AXP20X_VBUC_CLIMIT_100mA:
++ case AXP20X_VBUS_CLIMIT_100mA:
+ if (power->axp20x_id == AXP221_ID)
+ val->intval = -1; /* No 100mA limit */
+ else
+ val->intval = 100000;
+ break;
+- case AXP20X_VBUC_CLIMIT_500mA:
++ case AXP20X_VBUS_CLIMIT_500mA:
+ val->intval = 500000;
+ break;
+- case AXP20X_VBUC_CLIMIT_900mA:
++ case AXP20X_VBUS_CLIMIT_900mA:
+ val->intval = 900000;
+ break;
+- case AXP20X_VBUC_CLIMIT_NONE:
++ case AXP20X_VBUS_CLIMIT_NONE:
+ val->intval = -1;
+ break;
+ }
+--
+2.16.4
+
diff --git a/patches.drivers/power-supply-axp288_charger-Fix-unchecked-return-val.patch b/patches.drivers/power-supply-axp288_charger-Fix-unchecked-return-val.patch
new file mode 100644
index 0000000000..115d9f2bb3
--- /dev/null
+++ b/patches.drivers/power-supply-axp288_charger-Fix-unchecked-return-val.patch
@@ -0,0 +1,46 @@
+From c3422ad5f84a66739ec6a37251ca27638c85b6be Mon Sep 17 00:00:00 2001
+From: "Gustavo A. R. Silva" <gustavo@embeddedor.com>
+Date: Mon, 18 Mar 2019 11:14:39 -0500
+Subject: [PATCH] power: supply: axp288_charger: Fix unchecked return value
+Git-commit: c3422ad5f84a66739ec6a37251ca27638c85b6be
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+Currently there is no check on platform_get_irq() return value
+in case it fails, hence never actually reporting any errors and
+causing unexpected behavior when using such value as argument
+for function regmap_irq_get_virq().
+
+Fix this by adding a proper check, a message reporting any errors
+and returning *pirq*
+
+Addresses-coverity-id: 1443940 ("Improper use of negative value")
+Fixes: 843735b788a4 ("power: axp288_charger: axp288 charger driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
+Reviewed-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/power/supply/axp288_charger.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/power/supply/axp288_charger.c b/drivers/power/supply/axp288_charger.c
+index f8c6da9277b3..00b961890a38 100644
+--- a/drivers/power/supply/axp288_charger.c
++++ b/drivers/power/supply/axp288_charger.c
+@@ -833,6 +833,10 @@ static int axp288_charger_probe(struct platform_device *pdev)
+ /* Register charger interrupts */
+ for (i = 0; i < CHRG_INTR_END; i++) {
+ pirq = platform_get_irq(info->pdev, i);
++ if (pirq < 0) {
++ dev_err(&pdev->dev, "Failed to get IRQ: %d\n", pirq);
++ return pirq;
++ }
+ info->irq[i] = regmap_irq_get_virq(info->regmap_irqc, pirq);
+ if (info->irq[i] < 0) {
+ dev_warn(&info->pdev->dev,
+--
+2.16.4
+
diff --git a/patches.drivers/scsi-smartpqi-add-h3c-controller-ids b/patches.drivers/scsi-smartpqi-add-h3c-controller-ids
new file mode 100644
index 0000000000..0d6ec20b2e
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-h3c-controller-ids
@@ -0,0 +1,47 @@
+From: Ajish Koshy <ajish.koshy@microsemi.com>
+Date: Thu, 14 Mar 2019 16:57:55 -0500
+Subject: scsi: smartpqi: add H3C controller IDs
+Git-commit: 0595a0b4aeed134e3ff3be80cd7b7bce57f056ac
+Patch-mainline: v5.2-rc1
+References: bsc#1133547
+
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: David Carroll <david.carroll@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index b7a815450b78..6f6b26bfd88b 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -7950,6 +7950,22 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x152d, 0x8a37)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0x1104)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0x1105)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0x1106)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0x1107)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x193d, 0x8460)
+
diff --git a/patches.drivers/scsi-smartpqi-add-h3c-ssid b/patches.drivers/scsi-smartpqi-add-h3c-ssid
new file mode 100644
index 0000000000..3bc664c027
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-h3c-ssid
@@ -0,0 +1,40 @@
+From: Murthy Bhat <murthy.bhat@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:53 -0600
+Subject: scsi: smartpqi: add h3c ssid
+Git-commit: 84a77fefe0451bd9e6894362423d8fa6d14419ab
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index f6c83cb155b0..b0d00157a667 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -7326,6 +7326,14 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x193d, 0x8461)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0xc460)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x193d, 0xc461)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x193d, 0xf460)
+
diff --git a/patches.drivers/scsi-smartpqi-add-no_write_same-for-logical-volumes b/patches.drivers/scsi-smartpqi-add-no_write_same-for-logical-volumes
new file mode 100644
index 0000000000..e8f979cd8c
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-no_write_same-for-logical-volumes
@@ -0,0 +1,52 @@
+From: Dave Carroll <david.carroll@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:23 -0600
+Subject: scsi: smartpqi: add no_write_same for logical volumes
+Git-commit: b6e2ef67ed8365d60a0cebc1313b57df8b9e909e
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+During slave_alloc, for logical volumes include no_write_same into the
+scsi_device structure. This will insure that WRITE_SAME will not be used
+for LD's.
+
+Reviewed-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Justin Lindley <justin.lindley@microsemi.com>
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 0f28ce5ff32b..591787b46333 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -176,6 +176,11 @@ static inline void pqi_scsi_done(struct scsi_cmnd *scmd)
+ scmd->scsi_done(scmd);
+ }
+
++static inline void pqi_disable_write_same(struct scsi_device *sdev)
++{
++ sdev->no_write_same = 1;
++}
++
+ static inline bool pqi_scsi3addr_equal(u8 *scsi3addr1, u8 *scsi3addr2)
+ {
+ return memcmp(scsi3addr1, scsi3addr2, 8) == 0;
+@@ -5326,6 +5331,8 @@ static int pqi_slave_alloc(struct scsi_device *sdev)
+ scsi_change_queue_depth(sdev,
+ device->advertised_queue_depth);
+ }
++ if (pqi_is_logical_device(device))
++ pqi_disable_write_same(sdev);
+ }
+
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+
diff --git a/patches.drivers/scsi-smartpqi-add-ofa-support b/patches.drivers/scsi-smartpqi-add-ofa-support
new file mode 100644
index 0000000000..9169fa621f
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-ofa-support
@@ -0,0 +1,1144 @@
+From: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Date: Tue, 18 Dec 2018 17:39:07 -0600
+Subject: scsi: smartpqi: add ofa support
+Git-commit: 4fd22c13ad4409ee44a121b54855bb48d2afd58a
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- when OFA event occurs, driver will stop traffic to RAID/HBA path. Driver
+ waits for all the outstanding requests to complete.
+- Driver sends OFA event acknowledgment to firmware.
+- Driver will wait until the new firmware is up and running.
+- Driver will free up the resources.
+- Driver calls SIS/PQI initialization and rescans the device list.
+- Driver will resume the traffic to RAID/HBA path.
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Signed-off-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 76 ++++
+ drivers/scsi/smartpqi/smartpqi_init.c | 587 +++++++++++++++++++++++++++++++---
+ drivers/scsi/smartpqi/smartpqi_sis.c | 13
+ drivers/scsi/smartpqi/smartpqi_sis.h | 1
+ 4 files changed, 634 insertions(+), 43 deletions(-)
+
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -100,6 +100,12 @@ struct pqi_ctrl_registers {
+ struct pqi_device_registers pqi_registers; /* 4000h */
+ };
+
++#if ((HZ) < 1000)
++#define PQI_HZ 1000
++#else
++#define PQI_HZ (HZ)
++#endif
++
+ #define PQI_DEVICE_REGISTERS_OFFSET 0x4000
+
+ enum pqi_io_path {
+@@ -350,6 +356,10 @@ struct pqi_event_config {
+
+ #define PQI_MAX_EVENT_DESCRIPTORS 255
+
++#define PQI_EVENT_OFA_MEMORY_ALLOCATION 0x0
++#define PQI_EVENT_OFA_QUIESCE 0x1
++#define PQI_EVENT_OFA_CANCELLED 0x2
++
+ struct pqi_event_response {
+ struct pqi_iu_header header;
+ u8 event_type;
+@@ -357,7 +367,17 @@ struct pqi_event_response {
+ u8 request_acknowlege : 1;
+ __le16 event_id;
+ __le32 additional_event_id;
+- u8 data[16];
++ union {
++ struct {
++ __le32 bytes_requested;
++ u8 reserved[12];
++ } ofa_memory_allocation;
++
++ struct {
++ __le16 reason; /* reason for cancellation */
++ u8 reserved[14];
++ } ofa_cancelled;
++ } data;
+ };
+
+ struct pqi_event_acknowledge_request {
+@@ -420,6 +440,25 @@ struct pqi_vendor_general_response {
+ };
+
+ #define PQI_VENDOR_GENERAL_CONFIG_TABLE_UPDATE 0
++#define PQI_VENDOR_GENERAL_HOST_MEMORY_UPDATE 1
++
++#define PQI_OFA_VERSION 1
++#define PQI_OFA_SIGNATURE "OFA_QRM"
++#define PQI_OFA_MAX_SG_DESCRIPTORS 64
++
++#define PQI_OFA_MEMORY_DESCRIPTOR_LENGTH \
++ (offsetof(struct pqi_ofa_memory, sg_descriptor) + \
++ (PQI_OFA_MAX_SG_DESCRIPTORS * sizeof(struct pqi_sg_descriptor)))
++
++struct pqi_ofa_memory {
++ __le64 signature; /* "OFA_QRM" */
++ __le16 version; /* version of this struct(1 = 1st version) */
++ u8 reserved[62];
++ __le32 bytes_allocated; /* total allocated memory in bytes */
++ __le16 num_memory_descriptors;
++ u8 reserved1[2];
++ struct pqi_sg_descriptor sg_descriptor[1];
++};
+
+ struct pqi_aio_error_info {
+ u8 status;
+@@ -526,6 +565,7 @@ struct pqi_raid_error_info {
+ #define PQI_EVENT_TYPE_HARDWARE 0x2
+ #define PQI_EVENT_TYPE_PHYSICAL_DEVICE 0x4
+ #define PQI_EVENT_TYPE_LOGICAL_DEVICE 0x5
++#define PQI_EVENT_TYPE_OFA 0xfb
+ #define PQI_EVENT_TYPE_AIO_STATE_CHANGE 0xfd
+ #define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE 0xfe
+
+@@ -685,6 +725,7 @@ struct pqi_encryption_info {
+ #define PQI_CONFIG_TABLE_SECTION_FIRMWARE_ERRATA 2
+ #define PQI_CONFIG_TABLE_SECTION_DEBUG 3
+ #define PQI_CONFIG_TABLE_SECTION_HEARTBEAT 4
++#define PQI_CONFIG_TABLE_SECTION_SOFT_RESET 5
+
+ struct pqi_config_table {
+ u8 signature[8]; /* "CFGTABLE" */
+@@ -724,8 +765,9 @@ struct pqi_config_table_firmware_feature
+ /* u8 features_enabled[]; */
+ };
+
+-#define PQI_FIRMWARE_FEATURE_OFA 0
+-#define PQI_FIRMWARE_FEATURE_SMP 1
++#define PQI_FIRMWARE_FEATURE_OFA 0
++#define PQI_FIRMWARE_FEATURE_SMP 1
++#define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11
+
+ struct pqi_config_table_debug {
+ struct pqi_config_table_section_header header;
+@@ -737,6 +779,22 @@ struct pqi_config_table_heartbeat {
+ __le32 heartbeat_counter;
+ };
+
++struct pqi_config_table_soft_reset {
++ struct pqi_config_table_section_header header;
++ u8 soft_reset_status;
++};
++
++#define PQI_SOFT_RESET_INITIATE 0x1
++#define PQI_SOFT_RESET_ABORT 0x2
++
++enum pqi_soft_reset_status {
++ RESET_INITIATE_FIRMWARE,
++ RESET_INITIATE_DRIVER,
++ RESET_ABORT,
++ RESET_NORESPONSE,
++ RESET_TIMEDOUT
++};
++
+ union pqi_reset_register {
+ struct {
+ u32 reset_type : 3;
+@@ -1000,13 +1058,15 @@ struct pqi_io_request {
+ struct list_head request_list_entry;
+ };
+
+-#define PQI_NUM_SUPPORTED_EVENTS 6
++#define PQI_NUM_SUPPORTED_EVENTS 7
+
+ struct pqi_event {
+ bool pending;
+ u8 event_type;
+ __le16 event_id;
+ __le32 additional_event_id;
++ __le32 ofa_bytes_requested;
++ __le16 ofa_cancel_reason;
+ };
+
+ #define PQI_RESERVED_IO_SLOTS_LUN_RESET 1
+@@ -1067,13 +1127,16 @@ struct pqi_ctrl_info {
+
+ struct mutex scan_mutex;
+ struct mutex lun_reset_mutex;
++ struct mutex ofa_mutex; /* serialize ofa */
+ bool controller_online;
+ bool block_requests;
+ bool in_shutdown;
++ bool in_ofa;
+ u8 inbound_spanning_supported : 1;
+ u8 outbound_spanning_supported : 1;
+ u8 pqi_mode_enabled : 1;
+ u8 pqi_reset_quiesce_supported : 1;
++ u8 soft_reset_handshake_supported : 1;
+
+ struct list_head scsi_device_list;
+ spinlock_t scsi_device_list_lock;
+@@ -1094,6 +1157,7 @@ struct pqi_ctrl_info {
+ int previous_num_interrupts;
+ u32 previous_heartbeat_count;
+ __le32 __iomem *heartbeat_counter;
++ u8 __iomem *soft_reset_status;
+ struct timer_list heartbeat_timer;
+ struct work_struct ctrl_offline_work;
+
+@@ -1105,6 +1169,10 @@ struct pqi_ctrl_info {
+ struct list_head raid_bypass_retry_list;
+ spinlock_t raid_bypass_retry_list_lock;
+ struct work_struct raid_bypass_retry_work;
++
++ struct pqi_ofa_memory *pqi_ofa_mem_virt_addr;
++ dma_addr_t pqi_ofa_mem_dma_handle;
++ void **pqi_ofa_chunk_virt_addr;
+ };
+
+ enum pqi_ctrl_mode {
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -74,6 +74,13 @@ static int pqi_aio_submit_io(struct pqi_
+ struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
+ unsigned int cdb_length, struct pqi_queue_group *queue_group,
+ struct pqi_encryption_info *encryption_info, bool raid_bypass);
++static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info);
++static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info);
++static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info);
++static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info,
++ u32 bytes_requested);
++static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info);
++static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info);
+ static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device, unsigned long timeout_secs);
+
+@@ -115,6 +122,7 @@ static unsigned int pqi_supported_event_
+ PQI_EVENT_TYPE_HARDWARE,
+ PQI_EVENT_TYPE_PHYSICAL_DEVICE,
+ PQI_EVENT_TYPE_LOGICAL_DEVICE,
++ PQI_EVENT_TYPE_OFA,
+ PQI_EVENT_TYPE_AIO_STATE_CHANGE,
+ PQI_EVENT_TYPE_AIO_CONFIG_CHANGE,
+ };
+@@ -292,6 +300,21 @@ static inline bool pqi_device_in_reset(s
+ return device->in_reset;
+ }
+
++static inline void pqi_ctrl_ofa_start(struct pqi_ctrl_info *ctrl_info)
++{
++ ctrl_info->in_ofa = true;
++}
++
++static inline void pqi_ctrl_ofa_done(struct pqi_ctrl_info *ctrl_info)
++{
++ ctrl_info->in_ofa = false;
++}
++
++static inline bool pqi_ctrl_in_ofa(struct pqi_ctrl_info *ctrl_info)
++{
++ return ctrl_info->in_ofa;
++}
++
+ static inline void pqi_device_remove_start(struct pqi_scsi_dev *device)
+ {
+ device->in_remove = true;
+@@ -308,6 +331,8 @@ static inline void pqi_schedule_rescan_w
+ {
+ if (pqi_ctrl_offline(ctrl_info))
+ return;
++ if (pqi_ctrl_in_ofa(ctrl_info))
++ return;
+
+ schedule_delayed_work(&ctrl_info->rescan_work, delay);
+ }
+@@ -317,7 +342,7 @@ static inline void pqi_schedule_rescan_w
+ pqi_schedule_rescan_worker_with_delay(ctrl_info, 0);
+ }
+
+-#define PQI_RESCAN_WORK_DELAY (10 * HZ)
++#define PQI_RESCAN_WORK_DELAY (10 * PQI_HZ)
+
+ static inline void pqi_schedule_rescan_worker_delayed(
+ struct pqi_ctrl_info *ctrl_info)
+@@ -338,6 +363,27 @@ static inline u32 pqi_read_heartbeat_cou
+ return readl(ctrl_info->heartbeat_counter);
+ }
+
++static inline u8 pqi_read_soft_reset_status(struct pqi_ctrl_info *ctrl_info)
++{
++ if (!ctrl_info->soft_reset_status)
++ return 0;
++
++ return readb(ctrl_info->soft_reset_status);
++}
++
++static inline void pqi_clear_soft_reset_status(struct pqi_ctrl_info *ctrl_info,
++ u8 clear)
++{
++ u8 status;
++
++ if (!ctrl_info->soft_reset_status)
++ return;
++
++ status = pqi_read_soft_reset_status(ctrl_info);
++ status &= ~clear;
++ writeb(status, ctrl_info->soft_reset_status);
++}
++
+ static int pqi_map_single(struct pci_dev *pci_dev,
+ struct pqi_sg_descriptor *sg_descriptor, void *buffer,
+ size_t buffer_length, enum dma_data_direction data_direction)
+@@ -846,7 +892,7 @@ static int pqi_write_current_time_to_hos
+ return rc;
+ }
+
+-#define PQI_UPDATE_TIME_WORK_INTERVAL (24UL * 60 * 60 * HZ)
++#define PQI_UPDATE_TIME_WORK_INTERVAL (24UL * 60 * 60 * PQI_HZ)
+
+ static void pqi_update_time_worker(struct work_struct *work)
+ {
+@@ -1814,6 +1860,9 @@ static void pqi_update_device_list(struc
+
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+
++ if (pqi_ctrl_in_ofa(ctrl_info))
++ pqi_ctrl_ofa_done(ctrl_info);
++
+ /* Remove all devices that have gone away. */
+ list_for_each_entry_safe(device, next, &delete_list,
+ delete_list_entry) {
+@@ -2157,7 +2206,13 @@ static int pqi_scan_scsi_devices(struct
+
+ static void pqi_scan_start(struct Scsi_Host *shost)
+ {
+- pqi_scan_scsi_devices(shost_to_hba(shost));
++ struct pqi_ctrl_info *ctrl_info;
++
++ ctrl_info = shost_to_hba(shost);
++ if (pqi_ctrl_in_ofa(ctrl_info))
++ return;
++
++ pqi_scan_scsi_devices(ctrl_info);
+ }
+
+ /* Returns TRUE if scan is finished. */
+@@ -2184,6 +2239,12 @@ static void pqi_wait_until_lun_reset_fin
+ mutex_unlock(&ctrl_info->lun_reset_mutex);
+ }
+
++static void pqi_wait_until_ofa_finished(struct pqi_ctrl_info *ctrl_info)
++{
++ mutex_lock(&ctrl_info->ofa_mutex);
++ mutex_unlock(&ctrl_info->ofa_mutex);
++}
++
+ static inline void pqi_set_encryption_info(
+ struct pqi_encryption_info *encryption_info, struct raid_map *raid_map,
+ u64 first_block)
+@@ -2560,7 +2621,7 @@ static int pqi_wait_for_pqi_mode_ready(s
+ u8 status;
+
+ pqi_registers = ctrl_info->pqi_registers;
+- timeout = (PQI_MODE_READY_TIMEOUT_SECS * HZ) + jiffies;
++ timeout = (PQI_MODE_READY_TIMEOUT_SECS * PQI_HZ) + jiffies;
+
+ while (1) {
+ signature = readq(&pqi_registers->signature);
+@@ -2999,6 +3060,111 @@ static void pqi_acknowledge_event(struct
+ pqi_send_event_ack(ctrl_info, &request, sizeof(request));
+ }
+
++#define PQI_SOFT_RESET_STATUS_TIMEOUT_SECS 30
++#define PQI_SOFT_RESET_STATUS_POLL_INTERVAL_SECS 1
++
++static enum pqi_soft_reset_status pqi_poll_for_soft_reset_status(
++ struct pqi_ctrl_info *ctrl_info)
++{
++ unsigned long timeout;
++ u8 status;
++
++ timeout = (PQI_SOFT_RESET_STATUS_TIMEOUT_SECS * PQI_HZ) + jiffies;
++
++ while (1) {
++ status = pqi_read_soft_reset_status(ctrl_info);
++ if (status & PQI_SOFT_RESET_INITIATE)
++ return RESET_INITIATE_DRIVER;
++
++ if (status & PQI_SOFT_RESET_ABORT)
++ return RESET_ABORT;
++
++ if (time_after(jiffies, timeout)) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "timed out waiting for soft reset status\n");
++ return RESET_TIMEDOUT;
++ }
++
++ if (!sis_is_firmware_running(ctrl_info))
++ return RESET_NORESPONSE;
++
++ ssleep(PQI_SOFT_RESET_STATUS_POLL_INTERVAL_SECS);
++ }
++}
++
++static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info,
++ enum pqi_soft_reset_status reset_status)
++{
++ int rc;
++
++ switch (reset_status) {
++ case RESET_INITIATE_DRIVER:
++ /* fall through */
++ case RESET_TIMEDOUT:
++ dev_info(&ctrl_info->pci_dev->dev,
++ "resetting controller %u\n", ctrl_info->ctrl_id);
++ sis_soft_reset(ctrl_info);
++ /* fall through */
++ case RESET_INITIATE_FIRMWARE:
++ rc = pqi_ofa_ctrl_restart(ctrl_info);
++ pqi_ofa_free_host_buffer(ctrl_info);
++ dev_info(&ctrl_info->pci_dev->dev,
++ "Online Firmware Activation for controller %u: %s\n",
++ ctrl_info->ctrl_id, rc == 0 ? "SUCCESS" : "FAILED");
++ break;
++ case RESET_ABORT:
++ pqi_ofa_ctrl_unquiesce(ctrl_info);
++ dev_info(&ctrl_info->pci_dev->dev,
++ "Online Firmware Activation for controller %u: %s\n",
++ ctrl_info->ctrl_id, "ABORTED");
++ break;
++ case RESET_NORESPONSE:
++ pqi_ofa_free_host_buffer(ctrl_info);
++ pqi_take_ctrl_offline(ctrl_info);
++ break;
++ }
++}
++
++static void pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_event *event)
++{
++ u16 event_id;
++ enum pqi_soft_reset_status status;
++
++ event_id = get_unaligned_le16(&event->event_id);
++
++ mutex_lock(&ctrl_info->ofa_mutex);
++
++ if (event_id == PQI_EVENT_OFA_QUIESCE) {
++ dev_info(&ctrl_info->pci_dev->dev,
++ "Received Online Firmware Activation quiesce event for controller %u\n",
++ ctrl_info->ctrl_id);
++ pqi_ofa_ctrl_quiesce(ctrl_info);
++ pqi_acknowledge_event(ctrl_info, event);
++ if (ctrl_info->soft_reset_handshake_supported) {
++ status = pqi_poll_for_soft_reset_status(ctrl_info);
++ pqi_process_soft_reset(ctrl_info, status);
++ } else {
++ pqi_process_soft_reset(ctrl_info,
++ RESET_INITIATE_FIRMWARE);
++ }
++
++ } else if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) {
++ pqi_acknowledge_event(ctrl_info, event);
++ pqi_ofa_setup_host_buffer(ctrl_info,
++ le32_to_cpu(event->ofa_bytes_requested));
++ pqi_ofa_host_memory_update(ctrl_info);
++ } else if (event_id == PQI_EVENT_OFA_CANCELLED) {
++ pqi_ofa_free_host_buffer(ctrl_info);
++ pqi_acknowledge_event(ctrl_info, event);
++ dev_info(&ctrl_info->pci_dev->dev,
++ "Online Firmware Activation(%u) cancel reason : %u\n",
++ ctrl_info->ctrl_id, event->ofa_cancel_reason);
++ }
++
++ mutex_unlock(&ctrl_info->ofa_mutex);
++}
++
+ static void pqi_event_worker(struct work_struct *work)
+ {
+ unsigned int i;
+@@ -3018,6 +3184,11 @@ static void pqi_event_worker(struct work
+ for (i = 0; i < PQI_NUM_SUPPORTED_EVENTS; i++) {
+ if (event->pending) {
+ event->pending = false;
++ if (event->event_type == PQI_EVENT_TYPE_OFA) {
++ pqi_ctrl_unbusy(ctrl_info);
++ pqi_ofa_process_event(ctrl_info, event);
++ return;
++ }
+ pqi_acknowledge_event(ctrl_info, event);
+ }
+ event++;
+@@ -3027,7 +3198,7 @@ out:
+ pqi_ctrl_unbusy(ctrl_info);
+ }
+
+-#define PQI_HEARTBEAT_TIMER_INTERVAL (10 * HZ)
++#define PQI_HEARTBEAT_TIMER_INTERVAL (10 * PQI_HZ)
+
+ static void pqi_heartbeat_timer_handler(unsigned long data)
+ {
+@@ -3097,6 +3268,24 @@ static inline bool pqi_is_supported_even
+ return pqi_event_type_to_event_index(event_type) != -1;
+ }
+
++static void pqi_ofa_capture_event_payload(struct pqi_event *event,
++ struct pqi_event_response *response)
++{
++ u16 event_id;
++
++ event_id = get_unaligned_le16(&event->event_id);
++
++ if (event->event_type == PQI_EVENT_TYPE_OFA) {
++ if (event_id == PQI_EVENT_OFA_MEMORY_ALLOCATION) {
++ event->ofa_bytes_requested =
++ response->data.ofa_memory_allocation.bytes_requested;
++ } else if (event_id == PQI_EVENT_OFA_CANCELLED) {
++ event->ofa_cancel_reason =
++ response->data.ofa_cancelled.reason;
++ }
++ }
++}
++
+ static unsigned int pqi_process_event_intr(struct pqi_ctrl_info *ctrl_info)
+ {
+ unsigned int num_events;
+@@ -3131,6 +3320,7 @@ static unsigned int pqi_process_event_in
+ event->event_id = response->event_id;
+ event->additional_event_id =
+ response->additional_event_id;
++ pqi_ofa_capture_event_payload(event, response);
+ }
+ }
+
+@@ -3564,7 +3754,7 @@ static int pqi_alloc_admin_queues(struct
+ return 0;
+ }
+
+-#define PQI_ADMIN_QUEUE_CREATE_TIMEOUT_JIFFIES HZ
++#define PQI_ADMIN_QUEUE_CREATE_TIMEOUT_JIFFIES PQI_HZ
+ #define PQI_ADMIN_QUEUE_CREATE_POLL_INTERVAL_MSECS 1
+
+ static int pqi_create_admin_queues(struct pqi_ctrl_info *ctrl_info)
+@@ -3657,7 +3847,7 @@ static int pqi_poll_for_admin_response(s
+ admin_queues = &ctrl_info->admin_queues;
+ oq_ci = admin_queues->oq_ci_copy;
+
+- timeout = (PQI_ADMIN_REQUEST_TIMEOUT_SECS * HZ) + jiffies;
++ timeout = (PQI_ADMIN_REQUEST_TIMEOUT_SECS * PQI_HZ) + jiffies;
+
+ while (1) {
+ oq_pi = readl(admin_queues->oq_pi);
+@@ -3772,7 +3962,7 @@ static int pqi_wait_for_completion_io(st
+
+ while (1) {
+ if (wait_for_completion_io_timeout(wait,
+- PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS * HZ)) {
++ PQI_WAIT_FOR_COMPLETION_IO_TIMEOUT_SECS * PQI_HZ)) {
+ rc = 0;
+ break;
+ }
+@@ -5144,7 +5334,8 @@ static int pqi_scsi_queue_command(struct
+ }
+
+ pqi_ctrl_busy(ctrl_info);
+- if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device)) {
++ if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device) ||
++ pqi_ctrl_in_ofa(ctrl_info)) {
+ rc = SCSI_MLQUEUE_HOST_BUSY;
+ goto out;
+ }
+@@ -5289,12 +5480,48 @@ static void pqi_fail_io_queued_for_devic
+ }
+ }
+
++static void pqi_fail_io_queued_for_all_devices(struct pqi_ctrl_info *ctrl_info)
++{
++ unsigned int i;
++ unsigned int path;
++ struct pqi_queue_group *queue_group;
++ unsigned long flags;
++ struct pqi_io_request *io_request;
++ struct pqi_io_request *next;
++ struct scsi_cmnd *scmd;
++
++ for (i = 0; i < ctrl_info->num_queue_groups; i++) {
++ queue_group = &ctrl_info->queue_groups[i];
++
++ for (path = 0; path < 2; path++) {
++ spin_lock_irqsave(&queue_group->submit_lock[path],
++ flags);
++
++ list_for_each_entry_safe(io_request, next,
++ &queue_group->request_list[path],
++ request_list_entry) {
++
++ scmd = io_request->scmd;
++ if (!scmd)
++ continue;
++
++ list_del(&io_request->request_list_entry);
++ set_host_byte(scmd, DID_RESET);
++ pqi_scsi_done(scmd);
++ }
++
++ spin_unlock_irqrestore(
++ &queue_group->submit_lock[path], flags);
++ }
++ }
++}
++
+ static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device, unsigned long timeout_secs)
+ {
+ unsigned long timeout;
+
+- timeout = (timeout_secs * HZ) + jiffies;
++ timeout = (timeout_secs * PQI_HZ) + jiffies;
+
+ while (atomic_read(&device->scsi_cmds_outstanding)) {
+ pqi_check_ctrl_health(ctrl_info);
+@@ -5313,12 +5540,15 @@ static int pqi_device_wait_for_pending_i
+ return 0;
+ }
+
+-static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info)
++static int pqi_ctrl_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
++ unsigned long timeout_secs)
+ {
+ bool io_pending;
+ unsigned long flags;
++ unsigned long timeout;
+ struct pqi_scsi_dev *device;
+
++ timeout = (timeout_secs * PQI_HZ) + jiffies;
+ while (1) {
+ io_pending = false;
+
+@@ -5340,6 +5570,13 @@ static int pqi_ctrl_wait_for_pending_io(
+ if (pqi_ctrl_offline(ctrl_info))
+ return -ENXIO;
+
++ if (timeout_secs != NO_TIMEOUT) {
++ if (time_after(jiffies, timeout)) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "timed out waiting for pending IO\n");
++ return -ETIMEDOUT;
++ }
++ }
+ usleep_range(1000, 2000);
+ }
+
+@@ -5363,7 +5600,7 @@ static int pqi_wait_for_lun_reset_comple
+
+ while (1) {
+ if (wait_for_completion_io_timeout(wait,
+- PQI_LUN_RESET_TIMEOUT_SECS * HZ)) {
++ PQI_LUN_RESET_TIMEOUT_SECS * PQI_HZ)) {
+ rc = 0;
+ break;
+ }
+@@ -5418,11 +5655,12 @@ static int pqi_lun_reset(struct pqi_ctrl
+ #define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000
+ /* Performs a reset at the LUN level. */
+
+-static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
++static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device)
+ {
+ int rc;
+ unsigned int retries;
++ unsigned long timeout_secs;
+
+ for (retries = 0;;) {
+ rc = pqi_lun_reset(ctrl_info, device);
+@@ -5431,13 +5669,38 @@ static int pqi_device_reset(struct pqi_c
+ break;
+ msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS);
+ }
+- if (rc == 0)
+- rc = pqi_device_wait_for_pending_io(ctrl_info,
+- device, NO_TIMEOUT);
++ timeout_secs = rc ? PQI_LUN_RESET_TIMEOUT_SECS : NO_TIMEOUT;
++
++ rc |= pqi_device_wait_for_pending_io(ctrl_info, device, timeout_secs);
+
+ return rc == 0 ? SUCCESS : FAILED;
+ }
+
++static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_scsi_dev *device)
++{
++ int rc;
++
++ mutex_lock(&ctrl_info->lun_reset_mutex);
++
++ pqi_ctrl_block_requests(ctrl_info);
++ pqi_ctrl_wait_until_quiesced(ctrl_info);
++ pqi_fail_io_queued_for_device(ctrl_info, device);
++ rc = pqi_wait_until_inbound_queues_empty(ctrl_info);
++ pqi_device_reset_start(device);
++ pqi_ctrl_unblock_requests(ctrl_info);
++
++ if (rc)
++ rc = FAILED;
++ else
++ rc = _pqi_device_reset(ctrl_info, device);
++
++ pqi_device_reset_done(device);
++
++ mutex_unlock(&ctrl_info->lun_reset_mutex);
++ return rc;
++}
++
+ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
+ {
+ int rc;
+@@ -5455,28 +5718,16 @@ static int pqi_eh_device_reset_handler(s
+
+ pqi_check_ctrl_health(ctrl_info);
+ if (pqi_ctrl_offline(ctrl_info)) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "controller %u offlined - cannot send device reset\n",
++ ctrl_info->ctrl_id);
+ rc = FAILED;
+ goto out;
+ }
+
+- mutex_lock(&ctrl_info->lun_reset_mutex);
+-
+- pqi_ctrl_block_requests(ctrl_info);
+- pqi_ctrl_wait_until_quiesced(ctrl_info);
+- pqi_fail_io_queued_for_device(ctrl_info, device);
+- rc = pqi_wait_until_inbound_queues_empty(ctrl_info);
+- pqi_device_reset_start(device);
+- pqi_ctrl_unblock_requests(ctrl_info);
+-
+- if (rc)
+- rc = FAILED;
+- else
+- rc = pqi_device_reset(ctrl_info, device);
+-
+- pqi_device_reset_done(device);
+-
+- mutex_unlock(&ctrl_info->lun_reset_mutex);
++ pqi_wait_until_ofa_finished(ctrl_info);
+
++ rc = pqi_device_reset(ctrl_info, device);
+ out:
+ dev_err(&ctrl_info->pci_dev->dev,
+ "reset of scsi %d:%d:%d:%d: %s\n",
+@@ -5795,6 +6046,9 @@ static int pqi_ioctl(struct scsi_device
+
+ ctrl_info = shost_to_hba(sdev->host);
+
++ if (pqi_ctrl_in_ofa(ctrl_info))
++ return -EBUSY;
++
+ switch (cmd) {
+ case CCISS_DEREGDISK:
+ case CCISS_REGNEWDISK:
+@@ -6457,6 +6711,11 @@ static struct pqi_firmware_feature pqi_f
+ .feature_bit = PQI_FIRMWARE_FEATURE_SMP,
+ .feature_status = pqi_firmware_feature_status,
+ },
++ {
++ .feature_name = "New Soft Reset Handshake",
++ .feature_bit = PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE,
++ .feature_status = pqi_firmware_feature_status,
++ },
+ };
+
+ static void pqi_process_firmware_features(
+@@ -6509,13 +6768,19 @@ static void pqi_process_firmware_feature
+ return;
+ }
+
++ ctrl_info->soft_reset_handshake_supported = false;
+ for (i = 0; i < ARRAY_SIZE(pqi_firmware_features); i++) {
+ if (!pqi_firmware_features[i].supported)
+ continue;
+ if (pqi_is_firmware_feature_enabled(firmware_features,
+ firmware_features_iomem_addr,
+- pqi_firmware_features[i].feature_bit))
++ pqi_firmware_features[i].feature_bit)) {
+ pqi_firmware_features[i].enabled = true;
++ if (pqi_firmware_features[i].feature_bit ==
++ PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE)
++ ctrl_info->soft_reset_handshake_supported =
++ true;
++ }
+ pqi_firmware_feature_update(ctrl_info,
+ &pqi_firmware_features[i]);
+ }
+@@ -6596,6 +6861,13 @@ static int pqi_process_config_table(stru
+ struct pqi_config_table_heartbeat,
+ heartbeat_counter);
+ break;
++ case PQI_CONFIG_TABLE_SECTION_SOFT_RESET:
++ ctrl_info->soft_reset_status =
++ table_iomem_addr +
++ section_offset +
++ offsetof(struct pqi_config_table_soft_reset,
++ soft_reset_status);
++ break;
+ }
+
+ section_offset =
+@@ -6879,6 +7151,24 @@ static int pqi_ctrl_init_resume(struct p
+ return rc;
+
+ /*
++ * Get the controller properties. This allows us to determine
++ * whether or not it supports PQI mode.
++ */
++ rc = sis_get_ctrl_properties(ctrl_info);
++ if (rc) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "error obtaining controller properties\n");
++ return rc;
++ }
++
++ rc = sis_get_pqi_capabilities(ctrl_info);
++ if (rc) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "error obtaining controller capabilities\n");
++ return rc;
++ }
++
++ /*
+ * If the function we are about to call succeeds, the
+ * controller will transition from legacy SIS mode
+ * into PQI mode.
+@@ -6918,9 +7208,14 @@ static int pqi_ctrl_init_resume(struct p
+ pqi_change_irq_mode(ctrl_info, IRQ_MODE_MSIX);
+
+ ctrl_info->controller_online = true;
+- pqi_start_heartbeat_timer(ctrl_info);
+ pqi_ctrl_unblock_requests(ctrl_info);
+
++ rc = pqi_process_config_table(ctrl_info);
++ if (rc)
++ return rc;
++
++ pqi_start_heartbeat_timer(ctrl_info);
++
+ rc = pqi_enable_events(ctrl_info);
+ if (rc) {
+ dev_err(&ctrl_info->pci_dev->dev,
+@@ -6928,6 +7223,13 @@ static int pqi_ctrl_init_resume(struct p
+ return rc;
+ }
+
++ rc = pqi_get_ctrl_firmware_version(ctrl_info);
++ if (rc) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "error obtaining firmware version\n");
++ return rc;
++ }
++
+ rc = pqi_set_diag_rescan(ctrl_info);
+ if (rc) {
+ dev_err(&ctrl_info->pci_dev->dev,
+@@ -7045,6 +7347,7 @@ static struct pqi_ctrl_info *pqi_alloc_c
+
+ mutex_init(&ctrl_info->scan_mutex);
+ mutex_init(&ctrl_info->lun_reset_mutex);
++ mutex_init(&ctrl_info->ofa_mutex);
+
+ INIT_LIST_HEAD(&ctrl_info->scsi_device_list);
+ spin_lock_init(&ctrl_info->scsi_device_list_lock);
+@@ -7121,6 +7424,217 @@ static void pqi_remove_ctrl(struct pqi_c
+ pqi_free_ctrl_resources(ctrl_info);
+ }
+
++static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info)
++{
++ pqi_cancel_update_time_worker(ctrl_info);
++ pqi_cancel_rescan_worker(ctrl_info);
++ pqi_wait_until_lun_reset_finished(ctrl_info);
++ pqi_wait_until_scan_finished(ctrl_info);
++ pqi_ctrl_ofa_start(ctrl_info);
++ pqi_ctrl_block_requests(ctrl_info);
++ pqi_ctrl_wait_until_quiesced(ctrl_info);
++ pqi_ctrl_wait_for_pending_io(ctrl_info, PQI_PENDING_IO_TIMEOUT_SECS);
++ pqi_fail_io_queued_for_all_devices(ctrl_info);
++ pqi_wait_until_inbound_queues_empty(ctrl_info);
++ pqi_stop_heartbeat_timer(ctrl_info);
++ ctrl_info->pqi_mode_enabled = false;
++ pqi_save_ctrl_mode(ctrl_info, SIS_MODE);
++}
++
++static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info)
++{
++ pqi_ofa_free_host_buffer(ctrl_info);
++ ctrl_info->pqi_mode_enabled = true;
++ pqi_save_ctrl_mode(ctrl_info, PQI_MODE);
++ ctrl_info->controller_online = true;
++ pqi_ctrl_unblock_requests(ctrl_info);
++ pqi_start_heartbeat_timer(ctrl_info);
++ pqi_schedule_update_time_worker(ctrl_info);
++ pqi_clear_soft_reset_status(ctrl_info,
++ PQI_SOFT_RESET_ABORT);
++ pqi_scan_scsi_devices(ctrl_info);
++}
++
++static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info,
++ u32 total_size, u32 chunk_size)
++{
++ u32 sg_count;
++ u32 size;
++ int i;
++ struct pqi_sg_descriptor *mem_descriptor = NULL;
++ struct device *dev;
++ struct pqi_ofa_memory *ofap;
++
++ dev = &ctrl_info->pci_dev->dev;
++
++ sg_count = (total_size + chunk_size - 1);
++ do_div(sg_count, chunk_size);
++
++ ofap = ctrl_info->pqi_ofa_mem_virt_addr;
++
++ if (sg_count*chunk_size < total_size)
++ goto out;
++
++ ctrl_info->pqi_ofa_chunk_virt_addr =
++ kcalloc(sg_count, sizeof(void *), GFP_KERNEL);
++ if (!ctrl_info->pqi_ofa_chunk_virt_addr)
++ goto out;
++
++ for (size = 0, i = 0; size < total_size; size += chunk_size, i++) {
++ dma_addr_t dma_handle;
++
++ ctrl_info->pqi_ofa_chunk_virt_addr[i] =
++ dma_zalloc_coherent(dev, chunk_size, &dma_handle,
++ GFP_KERNEL);
++
++ if (!ctrl_info->pqi_ofa_chunk_virt_addr[i])
++ break;
++
++ mem_descriptor = &ofap->sg_descriptor[i];
++ put_unaligned_le64 ((u64) dma_handle, &mem_descriptor->address);
++ put_unaligned_le32 (chunk_size, &mem_descriptor->length);
++ }
++
++ if (!size || size < total_size)
++ goto out_free_chunks;
++
++ put_unaligned_le32(CISS_SG_LAST, &mem_descriptor->flags);
++ put_unaligned_le16(sg_count, &ofap->num_memory_descriptors);
++ put_unaligned_le32(size, &ofap->bytes_allocated);
++
++ return 0;
++
++out_free_chunks:
++ while (--i >= 0) {
++ mem_descriptor = &ofap->sg_descriptor[i];
++ dma_free_coherent(dev, chunk_size,
++ ctrl_info->pqi_ofa_chunk_virt_addr[i],
++ get_unaligned_le64(&mem_descriptor->address));
++ }
++ kfree(ctrl_info->pqi_ofa_chunk_virt_addr);
++
++out:
++ put_unaligned_le32 (0, &ofap->bytes_allocated);
++ return -ENOMEM;
++}
++
++static int pqi_ofa_alloc_host_buffer(struct pqi_ctrl_info *ctrl_info)
++{
++ u32 total_size;
++ u32 min_chunk_size;
++ u32 chunk_sz;
++
++ total_size = le32_to_cpu(
++ ctrl_info->pqi_ofa_mem_virt_addr->bytes_allocated);
++ min_chunk_size = total_size / PQI_OFA_MAX_SG_DESCRIPTORS;
++
++ for (chunk_sz = total_size; chunk_sz >= min_chunk_size; chunk_sz /= 2)
++ if (!pqi_ofa_alloc_mem(ctrl_info, total_size, chunk_sz))
++ return 0;
++
++ return -ENOMEM;
++}
++
++static void pqi_ofa_setup_host_buffer(struct pqi_ctrl_info *ctrl_info,
++ u32 bytes_requested)
++{
++ struct pqi_ofa_memory *pqi_ofa_memory;
++ struct device *dev;
++
++ dev = &ctrl_info->pci_dev->dev;
++ pqi_ofa_memory = dma_zalloc_coherent(dev,
++ PQI_OFA_MEMORY_DESCRIPTOR_LENGTH,
++ &ctrl_info->pqi_ofa_mem_dma_handle,
++ GFP_KERNEL);
++
++ if (!pqi_ofa_memory)
++ return;
++
++ put_unaligned_le16(PQI_OFA_VERSION, &pqi_ofa_memory->version);
++ memcpy(&pqi_ofa_memory->signature, PQI_OFA_SIGNATURE,
++ sizeof(pqi_ofa_memory->signature));
++ pqi_ofa_memory->bytes_allocated = cpu_to_le32(bytes_requested);
++
++ ctrl_info->pqi_ofa_mem_virt_addr = pqi_ofa_memory;
++
++ if (pqi_ofa_alloc_host_buffer(ctrl_info) < 0) {
++ dev_err(dev, "Failed to allocate host buffer of size = %u",
++ bytes_requested);
++ }
++}
++
++static void pqi_ofa_free_host_buffer(struct pqi_ctrl_info *ctrl_info)
++{
++ int i;
++ struct pqi_sg_descriptor *mem_descriptor;
++ struct pqi_ofa_memory *ofap;
++
++ ofap = ctrl_info->pqi_ofa_mem_virt_addr;
++
++ if (!ofap)
++ return;
++
++ if (!ofap->bytes_allocated)
++ goto out;
++
++ mem_descriptor = ofap->sg_descriptor;
++
++ for (i = 0; i < get_unaligned_le16(&ofap->num_memory_descriptors);
++ i++) {
++ dma_free_coherent(&ctrl_info->pci_dev->dev,
++ get_unaligned_le32(&mem_descriptor[i].length),
++ ctrl_info->pqi_ofa_chunk_virt_addr[i],
++ get_unaligned_le64(&mem_descriptor[i].address));
++ }
++ kfree(ctrl_info->pqi_ofa_chunk_virt_addr);
++
++out:
++ dma_free_coherent(&ctrl_info->pci_dev->dev,
++ PQI_OFA_MEMORY_DESCRIPTOR_LENGTH, ofap,
++ ctrl_info->pqi_ofa_mem_dma_handle);
++ ctrl_info->pqi_ofa_mem_virt_addr = NULL;
++}
++
++static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info)
++{
++ struct pqi_vendor_general_request request;
++ size_t size;
++ struct pqi_ofa_memory *ofap;
++
++ memset(&request, 0, sizeof(request));
++
++ ofap = ctrl_info->pqi_ofa_mem_virt_addr;
++
++ request.header.iu_type = PQI_REQUEST_IU_VENDOR_GENERAL;
++ put_unaligned_le16(sizeof(request) - PQI_REQUEST_HEADER_LENGTH,
++ &request.header.iu_length);
++ put_unaligned_le16(PQI_VENDOR_GENERAL_HOST_MEMORY_UPDATE,
++ &request.function_code);
++
++ if (ofap) {
++ size = offsetof(struct pqi_ofa_memory, sg_descriptor) +
++ get_unaligned_le16(&ofap->num_memory_descriptors) *
++ sizeof(struct pqi_sg_descriptor);
++
++ put_unaligned_le64((u64)ctrl_info->pqi_ofa_mem_dma_handle,
++ &request.data.ofa_memory_allocation.buffer_address);
++ put_unaligned_le32(size,
++ &request.data.ofa_memory_allocation.buffer_length);
++
++ }
++
++ return pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
++ 0, NULL, NO_TIMEOUT);
++}
++
++#define PQI_POST_RESET_DELAY_B4_MSGU_READY 5000
++
++static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info)
++{
++ msleep(PQI_POST_RESET_DELAY_B4_MSGU_READY);
++ return pqi_ctrl_init_resume(ctrl_info);
++}
++
+ static void pqi_perform_lockup_action(void)
+ {
+ switch (pqi_lockup_action) {
+@@ -7340,11 +7854,12 @@ static __maybe_unused int pqi_suspend(st
+ pqi_cancel_rescan_worker(ctrl_info);
+ pqi_wait_until_scan_finished(ctrl_info);
+ pqi_wait_until_lun_reset_finished(ctrl_info);
++ pqi_wait_until_ofa_finished(ctrl_info);
+ pqi_flush_cache(ctrl_info, SUSPEND);
+ pqi_ctrl_block_requests(ctrl_info);
+ pqi_ctrl_wait_until_quiesced(ctrl_info);
+ pqi_wait_until_inbound_queues_empty(ctrl_info);
+- pqi_ctrl_wait_for_pending_io(ctrl_info);
++ pqi_ctrl_wait_for_pending_io(ctrl_info, NO_TIMEOUT);
+ pqi_stop_heartbeat_timer(ctrl_info);
+
+ if (state.event == PM_EVENT_FREEZE)
+--- a/drivers/scsi/smartpqi/smartpqi_sis.c
++++ b/drivers/scsi/smartpqi/smartpqi_sis.c
+@@ -34,6 +34,7 @@
+ #define SIS_REENABLE_SIS_MODE 0x1
+ #define SIS_ENABLE_MSIX 0x40
+ #define SIS_ENABLE_INTX 0x80
++#define SIS_SOFT_RESET 0x100
+ #define SIS_CMD_READY 0x200
+ #define SIS_TRIGGER_SHUTDOWN 0x800000
+ #define SIS_PQI_RESET_QUIESCE 0x1000000
+@@ -90,7 +91,7 @@ static int sis_wait_for_ctrl_ready_with_
+ unsigned long timeout;
+ u32 status;
+
+- timeout = (timeout_secs * HZ) + jiffies;
++ timeout = (timeout_secs * PQI_HZ) + jiffies;
+
+ while (1) {
+ status = readl(&ctrl_info->registers->sis_firmware_status);
+@@ -202,7 +203,7 @@ static int sis_send_sync_cmd(struct pqi_
+ * the top of the loop in order to give the controller time to start
+ * processing the command before we start polling.
+ */
+- timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * HZ) + jiffies;
++ timeout = (SIS_CMD_COMPLETE_TIMEOUT_SECS * PQI_HZ) + jiffies;
+ while (1) {
+ msleep(SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS);
+ doorbell = readl(&registers->sis_ctrl_to_host_doorbell);
+@@ -348,7 +349,7 @@ static int sis_wait_for_doorbell_bit_to_
+ u32 doorbell_register;
+ unsigned long timeout;
+
+- timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * HZ) + jiffies;
++ timeout = (SIS_DOORBELL_BIT_CLEAR_TIMEOUT_SECS * PQI_HZ) + jiffies;
+
+ while (1) {
+ doorbell_register =
+@@ -420,6 +421,12 @@ u32 sis_read_driver_scratch(struct pqi_c
+ return readl(&ctrl_info->registers->sis_driver_scratch);
+ }
+
++void sis_soft_reset(struct pqi_ctrl_info *ctrl_info)
++{
++ writel(SIS_SOFT_RESET,
++ &ctrl_info->registers->sis_host_to_ctrl_doorbell);
++}
++
+ static void __attribute__((unused)) verify_structures(void)
+ {
+ BUILD_BUG_ON(offsetof(struct sis_base_struct,
+--- a/drivers/scsi/smartpqi/smartpqi_sis.h
++++ b/drivers/scsi/smartpqi/smartpqi_sis.h
+@@ -33,5 +33,6 @@ int sis_pqi_reset_quiesce(struct pqi_ctr
+ int sis_reenable_sis_mode(struct pqi_ctrl_info *ctrl_info);
+ void sis_write_driver_scratch(struct pqi_ctrl_info *ctrl_info, u32 value);
+ u32 sis_read_driver_scratch(struct pqi_ctrl_info *ctrl_info);
++void sis_soft_reset(struct pqi_ctrl_info *ctrl_info);
+
+ #endif /* _SMARTPQI_SIS_H */
diff --git a/patches.drivers/scsi-smartpqi-add-retries-for-device-reset b/patches.drivers/scsi-smartpqi-add-retries-for-device-reset
new file mode 100644
index 0000000000..26baf426bd
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-retries-for-device-reset
@@ -0,0 +1,75 @@
+From: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:16 -0600
+Subject: scsi: smartpqi: Add retries for device reset
+Git-commit: 3406384b76a77ea3b3bab7923c1a3bd4649318f5
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Justin Lindley <justin.lindley@microsemi.com>
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 1 +
+ drivers/scsi/smartpqi/smartpqi_init.c | 14 +++++++++++++-
+ 2 files changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index bbf056ddd026..646982e45904 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -587,6 +587,7 @@ typedef u32 pqi_index_t;
+ #define SOP_TASK_ATTRIBUTE_ACA 4
+
+ #define SOP_TMF_COMPLETE 0x0
++#define SOP_TMF_REJECTED 0x4
+ #define SOP_TMF_FUNCTION_SUCCEEDED 0x8
+
+ /* additional CDB bytes usage field codes */
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index e195d9aa5734..0f28ce5ff32b 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -2665,6 +2665,9 @@ static int pqi_interpret_task_management_response(
+ case SOP_TMF_FUNCTION_SUCCEEDED:
+ rc = 0;
+ break;
++ case SOP_TMF_REJECTED:
++ rc = -EAGAIN;
++ break;
+ default:
+ rc = -EIO;
+ break;
+@@ -5218,14 +5221,23 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info,
+ return rc;
+ }
+
++#define PQI_LUN_RESET_RETRIES 3
++#define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000
+ /* Performs a reset at the LUN level. */
+
+ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device)
+ {
+ int rc;
++ unsigned int retries;
+
+- rc = pqi_lun_reset(ctrl_info, device);
++ for (retries = 0;;) {
++ rc = pqi_lun_reset(ctrl_info, device);
++ if (rc != -EAGAIN ||
++ ++retries > PQI_LUN_RESET_RETRIES)
++ break;
++ msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS);
++ }
+ if (rc == 0)
+ rc = pqi_device_wait_for_pending_io(ctrl_info, device);
+
+
diff --git a/patches.drivers/scsi-smartpqi-add-smp_utils-support b/patches.drivers/scsi-smartpqi-add-smp_utils-support
new file mode 100644
index 0000000000..ae883107f4
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-smp_utils-support
@@ -0,0 +1,690 @@
+From: Don Brace <don.brace@microsemi.com>
+Date: Fri, 7 Dec 2018 16:30:05 -0600
+Subject: scsi: smartpqi: add smp_utils support
+Git-commit: 3d46a59a191e81f7ada771b8db71553916b851da
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 89 ++++++++++++++
+ drivers/scsi/smartpqi/smartpqi_init.c | 131 ++++++++++++--------
+ drivers/scsi/smartpqi/smartpqi_sas_transport.c | 164 +++++++++++++++++++++++--
+ 3 files changed, 324 insertions(+), 60 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index 4f52b5be3693..ba499a636f43 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -21,6 +21,9 @@
+ #if !defined(_SMARTPQI_H)
+ #define _SMARTPQI_H
+
++#include <scsi/scsi_host.h>
++#include <linux/bsg-lib.h>
++
+ #pragma pack(1)
+
+ #define PQI_DEVICE_SIGNATURE "PQI DREG"
+@@ -855,6 +858,7 @@ struct pqi_scsi_dev {
+ u8 unique_id[16];
+ u8 is_physical_device : 1;
+ u8 is_external_raid_device : 1;
++ u8 is_expander_smp_device : 1;
+ u8 target_lun_valid : 1;
+ u8 device_gone : 1;
+ u8 new_device : 1;
+@@ -964,6 +968,7 @@ struct pqi_sas_node {
+ struct pqi_sas_port {
+ struct list_head port_list_entry;
+ u64 sas_address;
++ struct pqi_scsi_dev *device;
+ struct sas_port *port;
+ int next_phy_index;
+ struct list_head phy_list_head;
+@@ -1129,11 +1134,14 @@ enum pqi_ctrl_mode {
+ #define BMIC_WRITE 0x27
+ #define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
+ #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
++#define BMIC_CSMI_PASSTHRU 0x68
+ #define BMIC_WRITE_HOST_WELLNESS 0xa5
+ #define BMIC_FLUSH_CACHE 0xc2
+ #define BMIC_SET_DIAG_OPTIONS 0xf4
+ #define BMIC_SENSE_DIAG_OPTIONS 0xf5
+
++#define CSMI_CC_SAS_SMP_PASSTHRU 0X17
++
+ #define SA_FLUSH_CACHE 0x1
+
+ #define MASKED_DEVICE(lunid) ((lunid)[3] & 0xc0)
+@@ -1160,6 +1168,10 @@ struct bmic_identify_controller {
+ u8 reserved3[32];
+ };
+
++#define SA_EXPANDER_SMP_DEVICE 0x05
++/*SCSI Invalid Device Type for SAS devices*/
++#define PQI_SAS_SCSI_INVALID_DEVTYPE 0xff
++
+ struct bmic_identify_physical_device {
+ u8 scsi_bus; /* SCSI Bus number on controller */
+ u8 scsi_id; /* SCSI ID on this bus */
+@@ -1240,6 +1252,50 @@ struct bmic_identify_physical_device {
+ u8 padding_to_multiple_of_512[9];
+ };
+
++struct bmic_smp_request {
++ u8 frame_type;
++ u8 function;
++ u8 allocated_response_length;
++ u8 request_length;
++ u8 additional_request_bytes[1016];
++};
++
++struct bmic_smp_response {
++ u8 frame_type;
++ u8 function;
++ u8 function_result;
++ u8 response_length;
++ u8 additional_response_bytes[1016];
++};
++
++struct bmic_csmi_ioctl_header {
++ __le32 header_length;
++ u8 signature[8];
++ __le32 timeout;
++ __le32 control_code;
++ __le32 return_code;
++ __le32 length;
++};
++
++struct bmic_csmi_smp_passthru {
++ u8 phy_identifier;
++ u8 port_identifier;
++ u8 connection_rate;
++ u8 reserved;
++ __be64 destination_sas_address;
++ __le32 request_length;
++ struct bmic_smp_request request;
++ u8 connection_status;
++ u8 reserved1[3];
++ __le32 response_length;
++ struct bmic_smp_response response;
++};
++
++struct bmic_csmi_smp_passthru_buffer {
++ struct bmic_csmi_ioctl_header ioctl_header;
++ struct bmic_csmi_smp_passthru parameters;
++};
++
+ struct bmic_flush_cache {
+ u8 disable_flag;
+ u8 system_power_action;
+@@ -1263,6 +1319,36 @@ struct bmic_diag_options {
+
+ #pragma pack()
+
++static inline struct pqi_ctrl_info *shost_to_hba(struct Scsi_Host *shost)
++{
++ void *hostdata = shost_priv(shost);
++
++ return *((struct pqi_ctrl_info **)hostdata);
++}
++
++static inline bool pqi_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
++{
++ return !ctrl_info->controller_online;
++}
++
++static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info)
++{
++ atomic_inc(&ctrl_info->num_busy_threads);
++}
++
++static inline void pqi_ctrl_unbusy(struct pqi_ctrl_info *ctrl_info)
++{
++ atomic_dec(&ctrl_info->num_busy_threads);
++}
++
++static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info)
++{
++ return ctrl_info->block_requests;
++}
++
++void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
++ struct sas_rphy *rphy);
++
+ int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info);
+ void pqi_delete_sas_host(struct pqi_ctrl_info *ctrl_info);
+ int pqi_add_sas_device(struct pqi_sas_node *pqi_sas_node,
+@@ -1271,6 +1357,9 @@ void pqi_remove_sas_device(struct pqi_scsi_dev *device);
+ struct pqi_scsi_dev *pqi_find_device_by_sas_rphy(
+ struct pqi_ctrl_info *ctrl_info, struct sas_rphy *rphy);
+ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd);
++int pqi_csmi_smp_passthru(struct pqi_ctrl_info *ctrl_info,
++ struct bmic_csmi_smp_passthru_buffer *buffer, size_t buffer_length,
++ struct pqi_raid_error_info *error_info);
+
+ extern struct sas_function_template pqi_sas_transport_functions;
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 509a081a6f17..96e171038eb6 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -188,13 +188,6 @@ static inline bool pqi_scsi3addr_equal(u8 *scsi3addr1, u8 *scsi3addr2)
+ return memcmp(scsi3addr1, scsi3addr2, 8) == 0;
+ }
+
+-static inline struct pqi_ctrl_info *shost_to_hba(struct Scsi_Host *shost)
+-{
+- void *hostdata = shost_priv(shost);
+-
+- return *((struct pqi_ctrl_info **)hostdata);
+-}
+-
+ static inline bool pqi_is_logical_device(struct pqi_scsi_dev *device)
+ {
+ return !device->is_physical_device;
+@@ -205,11 +198,6 @@ static inline bool pqi_is_external_raid_addr(u8 *scsi3addr)
+ return scsi3addr[2] != 0;
+ }
+
+-static inline bool pqi_ctrl_offline(struct pqi_ctrl_info *ctrl_info)
+-{
+- return !ctrl_info->controller_online;
+-}
+-
+ static inline void pqi_check_ctrl_health(struct pqi_ctrl_info *ctrl_info)
+ {
+ if (ctrl_info->controller_online)
+@@ -248,11 +236,6 @@ static inline void pqi_ctrl_unblock_requests(struct pqi_ctrl_info *ctrl_info)
+ scsi_unblock_requests(ctrl_info->scsi_host);
+ }
+
+-static inline bool pqi_ctrl_blocked(struct pqi_ctrl_info *ctrl_info)
+-{
+- return ctrl_info->block_requests;
+-}
+-
+ static unsigned long pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info,
+ unsigned long timeout_msecs)
+ {
+@@ -282,16 +265,6 @@ static unsigned long pqi_wait_if_ctrl_blocked(struct pqi_ctrl_info *ctrl_info,
+ return remaining_msecs;
+ }
+
+-static inline void pqi_ctrl_busy(struct pqi_ctrl_info *ctrl_info)
+-{
+- atomic_inc(&ctrl_info->num_busy_threads);
+-}
+-
+-static inline void pqi_ctrl_unbusy(struct pqi_ctrl_info *ctrl_info)
+-{
+- atomic_dec(&ctrl_info->num_busy_threads);
+-}
+-
+ static inline void pqi_ctrl_wait_until_quiesced(struct pqi_ctrl_info *ctrl_info)
+ {
+ while (atomic_read(&ctrl_info->num_busy_threads) >
+@@ -472,6 +445,13 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+ cdb[6] = cmd;
+ put_unaligned_be16(cdb_length, &cdb[7]);
+ break;
++ case BMIC_CSMI_PASSTHRU:
++ request->data_direction = SOP_BIDIRECTIONAL;
++ cdb[0] = BMIC_WRITE;
++ cdb[5] = CSMI_CC_SAS_SMP_PASSTHRU;
++ cdb[6] = cmd;
++ put_unaligned_be16(cdb_length, &cdb[7]);
++ break;
+ default:
+ dev_err(&ctrl_info->pci_dev->dev, "unknown command 0x%c\n",
+ cmd);
+@@ -713,6 +693,13 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
+ return rc;
+ }
+
++int pqi_csmi_smp_passthru(struct pqi_ctrl_info *ctrl_info,
++ struct bmic_csmi_smp_passthru_buffer *buffer, size_t buffer_length,
++ struct pqi_raid_error_info *error_info)
++{
++ return pqi_send_ctrl_raid_with_error(ctrl_info, BMIC_CSMI_PASSTHRU,
++ buffer, buffer_length, error_info);
++}
+
+ #define PQI_FETCH_PTRAID_DATA (1UL<<31)
+
+@@ -1298,6 +1285,9 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
+ u8 *buffer;
+ unsigned int retries;
+
++ if (device->is_expander_smp_device)
++ return 0;
++
+ buffer = kmalloc(64, GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+@@ -1585,6 +1575,14 @@ static enum pqi_find_result pqi_scsi_find_entry(struct pqi_ctrl_info *ctrl_info,
+ return DEVICE_NOT_FOUND;
+ }
+
++static inline const char *pqi_device_type(struct pqi_scsi_dev *device)
++{
++ if (device->is_expander_smp_device)
++ return "Enclosure SMP ";
++
++ return scsi_device_type(device->devtype);
++}
++
+ #define PQI_DEV_INFO_BUFFER_LENGTH 128
+
+ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
+@@ -1620,7 +1618,7 @@ static void pqi_dev_info(struct pqi_ctrl_info *ctrl_info,
+
+ count += snprintf(buffer + count, PQI_DEV_INFO_BUFFER_LENGTH - count,
+ " %s %.8s %.16s ",
+- scsi_device_type(device->devtype),
++ pqi_device_type(device),
+ device->vendor,
+ device->model);
+
+@@ -1665,6 +1663,8 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
+ existing_device->is_physical_device = new_device->is_physical_device;
+ existing_device->is_external_raid_device =
+ new_device->is_external_raid_device;
++ existing_device->is_expander_smp_device =
++ new_device->is_expander_smp_device;
+ existing_device->aio_enabled = new_device->aio_enabled;
+ memcpy(existing_device->vendor, new_device->vendor,
+ sizeof(existing_device->vendor));
+@@ -1721,6 +1721,14 @@ static inline void pqi_fixup_botched_add(struct pqi_ctrl_info *ctrl_info,
+ device->keep_device = false;
+ }
+
++static inline bool pqi_is_device_added(struct pqi_scsi_dev *device)
++{
++ if (device->is_expander_smp_device)
++ return device->sas_port != NULL;
++
++ return device->sdev != NULL;
++}
++
+ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *new_device_list[], unsigned int num_new_devices)
+ {
+@@ -1815,7 +1823,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
+ } else {
+ pqi_dev_info(ctrl_info, "removed", device);
+ }
+- if (device->sdev)
++ if (pqi_is_device_added(device))
+ pqi_remove_device(ctrl_info, device);
+ list_del(&device->delete_list_entry);
+ pqi_free_device(device);
+@@ -1837,7 +1845,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
+
+ /* Expose any new devices. */
+ list_for_each_entry_safe(device, next, &add_list, add_list_entry) {
+- if (!device->sdev) {
++ if (!pqi_is_device_added(device)) {
+ pqi_dev_info(ctrl_info, "added", device);
+ rc = pqi_add_device(ctrl_info, device);
+ if (rc) {
+@@ -1854,7 +1862,12 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info,
+
+ static bool pqi_is_supported_device(struct pqi_scsi_dev *device)
+ {
+- bool is_supported = false;
++ bool is_supported;
++
++ if (device->is_expander_smp_device)
++ return true;
++
++ is_supported = false;
+
+ switch (device->devtype) {
+ case TYPE_DISK:
+@@ -1888,6 +1901,24 @@ static inline bool pqi_skip_device(u8 *scsi3addr)
+ return false;
+ }
+
++static inline bool pqi_is_device_with_sas_address(struct pqi_scsi_dev *device)
++{
++ if (!device->is_physical_device)
++ return false;
++
++ if (device->is_expander_smp_device)
++ return true;
++
++ switch (device->devtype) {
++ case TYPE_DISK:
++ case TYPE_ZBC:
++ case TYPE_ENCLOSURE:
++ return true;
++ }
++
++ return false;
++}
++
+ static inline bool pqi_expose_device(struct pqi_scsi_dev *device)
+ {
+ return !device->is_physical_device ||
+@@ -2002,9 +2033,14 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
+
+ memcpy(device->scsi3addr, scsi3addr, sizeof(device->scsi3addr));
+ device->is_physical_device = is_physical_device;
+- if (!is_physical_device)
++ if (is_physical_device) {
++ if (phys_lun_ext_entry->device_type ==
++ SA_EXPANDER_SMP_DEVICE)
++ device->is_expander_smp_device = true;
++ } else {
+ device->is_external_raid_device =
+ pqi_is_external_raid_addr(scsi3addr);
++ }
+
+ /* Gather information about the device. */
+ rc = pqi_get_device_info(ctrl_info, device);
+@@ -2037,30 +2073,23 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
+ device->wwid = phys_lun_ext_entry->wwid;
+ if ((phys_lun_ext_entry->device_flags &
+ REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED) &&
+- phys_lun_ext_entry->aio_handle)
++ phys_lun_ext_entry->aio_handle) {
+ device->aio_enabled = true;
++ device->aio_handle =
++ phys_lun_ext_entry->aio_handle;
++ }
++ if (device->devtype == TYPE_DISK ||
++ device->devtype == TYPE_ZBC) {
++ pqi_get_physical_disk_info(ctrl_info,
++ device, id_phys);
++ }
+ } else {
+ memcpy(device->volume_id, log_lun_ext_entry->volume_id,
+ sizeof(device->volume_id));
+ }
+
+- switch (device->devtype) {
+- case TYPE_DISK:
+- case TYPE_ZBC:
+- case TYPE_ENCLOSURE:
+- if (device->is_physical_device) {
+- device->sas_address =
+- get_unaligned_be64(&device->wwid);
+- if (device->devtype == TYPE_DISK ||
+- device->devtype == TYPE_ZBC) {
+- device->aio_handle =
+- phys_lun_ext_entry->aio_handle;
+- pqi_get_physical_disk_info(ctrl_info,
+- device, id_phys);
+- }
+- }
+- break;
+- }
++ if (pqi_is_device_with_sas_address(device))
++ device->sas_address = get_unaligned_be64(&device->wwid);
+
+ new_device_list[num_valid_devices++] = device;
+ }
+@@ -2103,7 +2132,7 @@ static void pqi_remove_all_scsi_devices(struct pqi_ctrl_info *ctrl_info)
+ if (!device)
+ break;
+
+- if (device->sdev)
++ if (pqi_is_device_added(device))
+ pqi_remove_device(ctrl_info, device);
+ pqi_free_device(device);
+ }
+diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+index b209a35e482e..0e4ef215115f 100644
+--- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c
++++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+@@ -17,9 +17,11 @@
+ */
+
+ #include <linux/kernel.h>
++#include <linux/bsg-lib.h>
+ #include <scsi/scsi_host.h>
+ #include <scsi/scsi_cmnd.h>
+ #include <scsi/scsi_transport_sas.h>
++#include <asm/unaligned.h>
+ #include "smartpqi.h"
+
+ static struct pqi_sas_phy *pqi_alloc_sas_phy(struct pqi_sas_port *pqi_sas_port)
+@@ -97,14 +99,32 @@ static int pqi_sas_port_add_rphy(struct pqi_sas_port *pqi_sas_port,
+
+ identify = &rphy->identify;
+ identify->sas_address = pqi_sas_port->sas_address;
+- identify->initiator_port_protocols = SAS_PROTOCOL_STP;
+- identify->target_port_protocols = SAS_PROTOCOL_STP;
++
++ if (pqi_sas_port->device &&
++ pqi_sas_port->device->is_expander_smp_device) {
++ identify->initiator_port_protocols = SAS_PROTOCOL_SMP;
++ identify->target_port_protocols = SAS_PROTOCOL_SMP;
++ } else {
++ identify->initiator_port_protocols = SAS_PROTOCOL_STP;
++ identify->target_port_protocols = SAS_PROTOCOL_STP;
++ }
+
+ return sas_rphy_add(rphy);
+ }
+
++static struct sas_rphy *pqi_sas_rphy_alloc(struct pqi_sas_port *pqi_sas_port)
++{
++ if (pqi_sas_port->device &&
++ pqi_sas_port->device->is_expander_smp_device)
++ return sas_expander_alloc(pqi_sas_port->port,
++ SAS_FANOUT_EXPANDER_DEVICE);
++
++ return sas_end_device_alloc(pqi_sas_port->port);
++}
++
+ static struct pqi_sas_port *pqi_alloc_sas_port(
+- struct pqi_sas_node *pqi_sas_node, u64 sas_address)
++ struct pqi_sas_node *pqi_sas_node, u64 sas_address,
++ struct pqi_scsi_dev *device)
+ {
+ int rc;
+ struct pqi_sas_port *pqi_sas_port;
+@@ -127,6 +147,7 @@ static struct pqi_sas_port *pqi_alloc_sas_port(
+
+ pqi_sas_port->port = port;
+ pqi_sas_port->sas_address = sas_address;
++ pqi_sas_port->device = device;
+ list_add_tail(&pqi_sas_port->port_list_entry,
+ &pqi_sas_node->port_list_head);
+
+@@ -146,7 +167,7 @@ static void pqi_free_sas_port(struct pqi_sas_port *pqi_sas_port)
+ struct pqi_sas_phy *next;
+
+ list_for_each_entry_safe(pqi_sas_phy, next,
+- &pqi_sas_port->phy_list_head, phy_list_entry)
++ &pqi_sas_port->phy_list_head, phy_list_entry)
+ pqi_free_sas_phy(pqi_sas_phy);
+
+ sas_port_delete(pqi_sas_port->port);
+@@ -176,7 +197,7 @@ static void pqi_free_sas_node(struct pqi_sas_node *pqi_sas_node)
+ return;
+
+ list_for_each_entry_safe(pqi_sas_port, next,
+- &pqi_sas_node->port_list_head, port_list_entry)
++ &pqi_sas_node->port_list_head, port_list_entry)
+ pqi_free_sas_port(pqi_sas_port);
+
+ kfree(pqi_sas_node);
+@@ -206,13 +227,14 @@ int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info)
+ struct pqi_sas_port *pqi_sas_port;
+ struct pqi_sas_phy *pqi_sas_phy;
+
+- parent_dev = &shost->shost_gendev;
++ parent_dev = &shost->shost_dev;
+
+ pqi_sas_node = pqi_alloc_sas_node(parent_dev);
+ if (!pqi_sas_node)
+ return -ENOMEM;
+
+- pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node, ctrl_info->sas_address);
++ pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node,
++ ctrl_info->sas_address, NULL);
+ if (!pqi_sas_port) {
+ rc = -ENODEV;
+ goto free_sas_node;
+@@ -254,11 +276,12 @@ int pqi_add_sas_device(struct pqi_sas_node *pqi_sas_node,
+ struct pqi_sas_port *pqi_sas_port;
+ struct sas_rphy *rphy;
+
+- pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node, device->sas_address);
++ pqi_sas_port = pqi_alloc_sas_port(pqi_sas_node,
++ device->sas_address, device);
+ if (!pqi_sas_port)
+ return -ENOMEM;
+
+- rphy = sas_end_device_alloc(pqi_sas_port->port);
++ rphy = pqi_sas_rphy_alloc(pqi_sas_port);
+ if (!rphy) {
+ rc = -ENODEV;
+ goto free_sas_port;
+@@ -329,6 +352,128 @@ static int pqi_sas_phy_speed(struct sas_phy *phy,
+ return -EINVAL;
+ }
+
++#define CSMI_IOCTL_TIMEOUT 60
++#define SMP_CRC_FIELD_LENGTH 4
++
++static struct bmic_csmi_smp_passthru_buffer *
++pqi_build_csmi_smp_passthru_buffer(struct sas_rphy *rphy,
++ struct bsg_job *job)
++{
++ struct bmic_csmi_smp_passthru_buffer *smp_buf;
++ struct bmic_csmi_ioctl_header *ioctl_header;
++ struct bmic_csmi_smp_passthru *parameters;
++ u32 req_size;
++ u32 resp_size;
++
++ smp_buf = kzalloc(sizeof(*smp_buf), GFP_KERNEL);
++ if (!smp_buf)
++ return NULL;
++
++ req_size = job->request_payload.payload_len;
++ resp_size = job->reply_payload.payload_len;
++
++ ioctl_header = &smp_buf->ioctl_header;
++ put_unaligned_le32(sizeof(smp_buf->ioctl_header),
++ &ioctl_header->header_length);
++ put_unaligned_le32(CSMI_IOCTL_TIMEOUT, &ioctl_header->timeout);
++ put_unaligned_le32(CSMI_CC_SAS_SMP_PASSTHRU,
++ &ioctl_header->control_code);
++ put_unaligned_le32(sizeof(smp_buf->parameters), &ioctl_header->length);
++
++ parameters = &smp_buf->parameters;
++ parameters->phy_identifier = rphy->identify.phy_identifier;
++ parameters->port_identifier = 0;
++ parameters->connection_rate = 0;
++ put_unaligned_be64(rphy->identify.sas_address,
++ &parameters->destination_sas_address);
++
++ if (req_size > SMP_CRC_FIELD_LENGTH)
++ req_size -= SMP_CRC_FIELD_LENGTH;
++
++ put_unaligned_le32(req_size, &parameters->request_length);
++
++ put_unaligned_le32(resp_size, &parameters->response_length);
++
++ sg_copy_to_buffer(job->request_payload.sg_list,
++ job->reply_payload.sg_cnt, &parameters->request,
++ req_size);
++
++ return smp_buf;
++}
++
++static unsigned int pqi_build_sas_smp_handler_reply(
++ struct bmic_csmi_smp_passthru_buffer *smp_buf, struct bsg_job *job,
++ struct pqi_raid_error_info *error_info)
++{
++ sg_copy_from_buffer(job->reply_payload.sg_list,
++ job->reply_payload.sg_cnt, &smp_buf->parameters.response,
++ le32_to_cpu(smp_buf->parameters.response_length));
++
++ job->reply_len = le16_to_cpu(error_info->sense_data_length);
++ memcpy(job->reply, error_info->data,
++ le16_to_cpu(error_info->sense_data_length));
++
++ return job->reply_payload.payload_len -
++ get_unaligned_le32(&error_info->data_in_transferred);
++}
++
++void pqi_sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost,
++ struct sas_rphy *rphy)
++{
++ int rc;
++ struct pqi_ctrl_info *ctrl_info = shost_to_hba(shost);
++ struct bmic_csmi_smp_passthru_buffer *smp_buf;
++ struct pqi_raid_error_info error_info;
++ unsigned int reslen = 0;
++
++ pqi_ctrl_busy(ctrl_info);
++
++ if (job->reply_payload.payload_len == 0) {
++ rc = -ENOMEM;
++ goto out;
++ }
++
++ if (!rphy) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (rphy->identify.device_type != SAS_FANOUT_EXPANDER_DEVICE) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (job->request_payload.sg_cnt > 1 || job->reply_payload.sg_cnt > 1) {
++ rc = -EINVAL;
++ goto out;
++ }
++
++ if (pqi_ctrl_offline(ctrl_info)) {
++ rc = -ENXIO;
++ goto out;
++ }
++
++ if (pqi_ctrl_blocked(ctrl_info)) {
++ rc = -EBUSY;
++ goto out;
++ }
++
++ smp_buf = pqi_build_csmi_smp_passthru_buffer(rphy, job);
++ if (!smp_buf) {
++ rc = -ENOMEM;
++ goto out;
++ }
++
++ rc = pqi_csmi_smp_passthru(ctrl_info, smp_buf, sizeof(*smp_buf),
++ &error_info);
++ if (rc)
++ goto out;
++
++ reslen = pqi_build_sas_smp_handler_reply(smp_buf, job, &error_info);
++out:
++ bsg_job_done(job, rc, reslen);
++ pqi_ctrl_unbusy(ctrl_info);
++}
+ struct sas_function_template pqi_sas_transport_functions = {
+ .get_linkerrors = pqi_sas_get_linkerrors,
+ .get_enclosure_identifier = pqi_sas_get_enclosure_identifier,
+@@ -338,4 +483,5 @@ struct sas_function_template pqi_sas_transport_functions = {
+ .phy_setup = pqi_sas_phy_setup,
+ .phy_release = pqi_sas_phy_release,
+ .set_phy_speed = pqi_sas_phy_speed,
++ .smp_handler = pqi_sas_smp_handler,
+ };
+
diff --git a/patches.drivers/scsi-smartpqi-add-spdx b/patches.drivers/scsi-smartpqi-add-spdx
new file mode 100644
index 0000000000..2daf1999dd
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-spdx
@@ -0,0 +1,140 @@
+From: Don Brace <don.brace@microsemi.com>
+Date: Thu, 14 Mar 2019 16:58:09 -0500
+Subject: scsi: smartpqi: add spdx
+Git-commit: 2cc37b1575c6f51cc1bb3ed761de5476917cb6ff
+Patch-mainline: v5.2-rc1
+References: bsc#1133547
+
+Reviewed-by: David Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/Makefile | 1 +
+ drivers/scsi/smartpqi/smartpqi.h | 10 +---------
+ drivers/scsi/smartpqi/smartpqi_init.c | 10 +---------
+ drivers/scsi/smartpqi/smartpqi_sas_transport.c | 10 +---------
+ drivers/scsi/smartpqi/smartpqi_sis.c | 10 +---------
+ drivers/scsi/smartpqi/smartpqi_sis.h | 10 +---------
+ 6 files changed, 6 insertions(+), 45 deletions(-)
+
+--- a/drivers/scsi/smartpqi/Makefile
++++ b/drivers/scsi/smartpqi/Makefile
+@@ -1,3 +1,4 @@
++# SPDX-License-Identifier: GPL-2.0
+ ccflags-y += -I.
+ obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi.o
+ smartpqi-objs := smartpqi_init.o smartpqi_sis.o smartpqi_sas_transport.o
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -1,18 +1,10 @@
++/* SPDX-License-Identifier: GPL-2.0 */
+ /*
+ * driver for Microsemi PQI-based storage controllers
+ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
+ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; version 2 of the License.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+- * NON INFRINGEMENT. See the GNU General Public License for more details.
+- *
+ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -1,18 +1,10 @@
++// SPDX-License-Identifier: GPL-2.0
+ /*
+ * driver for Microsemi PQI-based storage controllers
+ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
+ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; version 2 of the License.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+- * NON INFRINGEMENT. See the GNU General Public License for more details.
+- *
+ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+--- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c
++++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+@@ -1,18 +1,10 @@
++// SPDX-License-Identifier: GPL-2.0
+ /*
+ * driver for Microsemi PQI-based storage controllers
+ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
+ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; version 2 of the License.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+- * NON INFRINGEMENT. See the GNU General Public License for more details.
+- *
+ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+--- a/drivers/scsi/smartpqi/smartpqi_sis.c
++++ b/drivers/scsi/smartpqi/smartpqi_sis.c
+@@ -1,18 +1,10 @@
++// SPDX-License-Identifier: GPL-2.0
+ /*
+ * driver for Microsemi PQI-based storage controllers
+ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
+ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; version 2 of the License.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+- * NON INFRINGEMENT. See the GNU General Public License for more details.
+- *
+ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+--- a/drivers/scsi/smartpqi/smartpqi_sis.h
++++ b/drivers/scsi/smartpqi/smartpqi_sis.h
+@@ -1,18 +1,10 @@
++/* SPDX-License-Identifier: GPL-2.0 */
+ /*
+ * driver for Microsemi PQI-based storage controllers
+ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
+ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+- * This program is free software; you can redistribute it and/or modify
+- * it under the terms of the GNU General Public License as published by
+- * the Free Software Foundation; version 2 of the License.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+- * NON INFRINGEMENT. See the GNU General Public License for more details.
+- *
+ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
diff --git a/patches.drivers/scsi-smartpqi-add-support-for-huawei-controllers b/patches.drivers/scsi-smartpqi-add-support-for-huawei-controllers
new file mode 100644
index 0000000000..6b52a2ac78
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-support-for-huawei-controllers
@@ -0,0 +1,56 @@
+From: Ajish Koshy <ajish.koshy@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:18 -0600
+Subject: scsi: smartpqi: add support for huawei controllers
+Git-commit: c1b104755b0b11579e292aa153c0605264c81648
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 24 ++++++++++++++++++++++++
+ 1 file changed, 24 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index ed4dd71426be..3678bd7ac8b7 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -7381,6 +7381,30 @@ static const struct pci_device_id pqi_pci_id_table[] = {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ 0x1bd4, 0x004c)
+ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x19e5, 0xd227)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x19e5, 0xd228)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x19e5, 0xd229)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x19e5, 0xd22a)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x19e5, 0xd22b)
++ },
++ {
++ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
++ 0x19e5, 0xd22c)
++ },
+ {
+ PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f,
+ PCI_VENDOR_ID_ADAPTEC2, 0x0110)
+
diff --git a/patches.drivers/scsi-smartpqi-add-support-for-pqi-config-table-handshake b/patches.drivers/scsi-smartpqi-add-support-for-pqi-config-table-handshake
new file mode 100644
index 0000000000..68c82a329a
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-support-for-pqi-config-table-handshake
@@ -0,0 +1,418 @@
+From: Kevin Barnett <kevin.barnett@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:10 -0600
+Subject: scsi: smartpqi: add support for PQI Config Table handshake
+Git-commit: b212c2510d7ca15af8758eade5e4002ed5267d1b
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Add support for new IUs and parsing of the Firmware Features section of the
+PQI Config Table to implement the "handshake" between the driver and
+firmware to communicate firmware features supported and enabled by the
+driver.
+
+Reviewed-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Justin Lindley <justin.lindley@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 43 ++++++
+ drivers/scsi/smartpqi/smartpqi_init.c | 254 +++++++++++++++++++++++++++++++++-
+ 2 files changed, 293 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index e97bf2670315..bbf056ddd026 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -389,6 +389,35 @@ struct pqi_task_management_response {
+ u8 response_code;
+ };
+
++struct pqi_vendor_general_request {
++ struct pqi_iu_header header;
++ __le16 request_id;
++ __le16 function_code;
++ union {
++ struct {
++ __le16 first_section;
++ __le16 last_section;
++ u8 reserved[48];
++ } config_table_update;
++
++ struct {
++ __le64 buffer_address;
++ __le32 buffer_length;
++ u8 reserved[40];
++ } ofa_memory_allocation;
++ } data;
++};
++
++struct pqi_vendor_general_response {
++ struct pqi_iu_header header;
++ __le16 request_id;
++ __le16 function_code;
++ __le16 status;
++ u8 reserved[2];
++};
++
++#define PQI_VENDOR_GENERAL_CONFIG_TABLE_UPDATE 0
++
+ struct pqi_aio_error_info {
+ u8 status;
+ u8 service_response;
+@@ -419,6 +448,7 @@ struct pqi_raid_error_info {
+ #define PQI_REQUEST_IU_GENERAL_ADMIN 0x60
+ #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72
+ #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73
++#define PQI_REQUEST_IU_VENDOR_GENERAL 0x75
+ #define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT 0xf6
+
+ #define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81
+@@ -430,6 +460,7 @@ struct pqi_raid_error_info {
+ #define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR 0xf3
+ #define PQI_RESPONSE_IU_AIO_PATH_DISABLED 0xf4
+ #define PQI_RESPONSE_IU_VENDOR_EVENT 0xf5
++#define PQI_RESPONSE_IU_VENDOR_GENERAL 0xf7
+
+ #define PQI_GENERAL_ADMIN_FUNCTION_REPORT_DEVICE_CAPABILITY 0x0
+ #define PQI_GENERAL_ADMIN_FUNCTION_CREATE_IQ 0x10
+@@ -644,6 +675,7 @@ struct pqi_encryption_info {
+ #define PQI_CONFIG_TABLE_MAX_LENGTH ((u16)~0)
+
+ /* configuration table section IDs */
++#define PQI_CONFIG_TABLE_ALL_SECTIONS (-1)
+ #define PQI_CONFIG_TABLE_SECTION_GENERAL_INFO 0
+ #define PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES 1
+ #define PQI_CONFIG_TABLE_SECTION_FIRMWARE_ERRATA 2
+@@ -680,6 +712,17 @@ struct pqi_config_table_general_info {
+ /* command */
+ };
+
++struct pqi_config_table_firmware_features {
++ struct pqi_config_table_section_header header;
++ __le16 num_elements;
++ u8 features_supported[];
++/* u8 features_requested_by_host[]; */
++/* u8 features_enabled[]; */
++};
++
++#define PQI_FIRMWARE_FEATURE_OFA 0
++#define PQI_FIRMWARE_FEATURE_SMP 1
++
+ struct pqi_config_table_debug {
+ struct pqi_config_table_section_header header;
+ __le32 scratchpad;
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index c9a1a4973574..e195d9aa5734 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -2706,6 +2706,12 @@ static unsigned int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info,
+ case PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS:
+ case PQI_RESPONSE_IU_GENERAL_MANAGEMENT:
+ break;
++ case PQI_RESPONSE_IU_VENDOR_GENERAL:
++ io_request->status =
++ get_unaligned_le16(
++ &((struct pqi_vendor_general_response *)
++ response)->status);
++ break;
+ case PQI_RESPONSE_IU_TASK_MANAGEMENT:
+ io_request->status =
+ pqi_interpret_task_management_response(
+@@ -5946,6 +5952,233 @@ static int pqi_get_ctrl_firmware_version(struct pqi_ctrl_info *ctrl_info)
+ return rc;
+ }
+
++struct pqi_config_table_section_info {
++ struct pqi_ctrl_info *ctrl_info;
++ void *section;
++ u32 section_offset;
++ void __iomem *section_iomem_addr;
++};
++
++static inline bool pqi_is_firmware_feature_supported(
++ struct pqi_config_table_firmware_features *firmware_features,
++ unsigned int bit_position)
++{
++ unsigned int byte_index;
++
++ byte_index = bit_position / BITS_PER_BYTE;
++
++ if (byte_index >= le16_to_cpu(firmware_features->num_elements))
++ return false;
++
++ return firmware_features->features_supported[byte_index] &
++ (1 << (bit_position % BITS_PER_BYTE)) ? true : false;
++}
++
++static inline bool pqi_is_firmware_feature_enabled(
++ struct pqi_config_table_firmware_features *firmware_features,
++ void __iomem *firmware_features_iomem_addr,
++ unsigned int bit_position)
++{
++ unsigned int byte_index;
++ u8 __iomem *features_enabled_iomem_addr;
++
++ byte_index = (bit_position / BITS_PER_BYTE) +
++ (le16_to_cpu(firmware_features->num_elements) * 2);
++
++ features_enabled_iomem_addr = firmware_features_iomem_addr +
++ offsetof(struct pqi_config_table_firmware_features,
++ features_supported) + byte_index;
++
++ return *((__force u8 *)features_enabled_iomem_addr) &
++ (1 << (bit_position % BITS_PER_BYTE)) ? true : false;
++}
++
++static inline void pqi_request_firmware_feature(
++ struct pqi_config_table_firmware_features *firmware_features,
++ unsigned int bit_position)
++{
++ unsigned int byte_index;
++
++ byte_index = (bit_position / BITS_PER_BYTE) +
++ le16_to_cpu(firmware_features->num_elements);
++
++ firmware_features->features_supported[byte_index] |=
++ (1 << (bit_position % BITS_PER_BYTE));
++}
++
++static int pqi_config_table_update(struct pqi_ctrl_info *ctrl_info,
++ u16 first_section, u16 last_section)
++{
++ struct pqi_vendor_general_request request;
++
++ memset(&request, 0, sizeof(request));
++
++ request.header.iu_type = PQI_REQUEST_IU_VENDOR_GENERAL;
++ put_unaligned_le16(sizeof(request) - PQI_REQUEST_HEADER_LENGTH,
++ &request.header.iu_length);
++ put_unaligned_le16(PQI_VENDOR_GENERAL_CONFIG_TABLE_UPDATE,
++ &request.function_code);
++ put_unaligned_le16(first_section,
++ &request.data.config_table_update.first_section);
++ put_unaligned_le16(last_section,
++ &request.data.config_table_update.last_section);
++
++ return pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
++ 0, NULL, NO_TIMEOUT);
++}
++
++static int pqi_enable_firmware_features(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_config_table_firmware_features *firmware_features,
++ void __iomem *firmware_features_iomem_addr)
++{
++ void *features_requested;
++ void __iomem *features_requested_iomem_addr;
++
++ features_requested = firmware_features->features_supported +
++ le16_to_cpu(firmware_features->num_elements);
++
++ features_requested_iomem_addr = firmware_features_iomem_addr +
++ (features_requested - (void *)firmware_features);
++
++ memcpy_toio(features_requested_iomem_addr, features_requested,
++ le16_to_cpu(firmware_features->num_elements));
++
++ return pqi_config_table_update(ctrl_info,
++ PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES,
++ PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES);
++}
++
++struct pqi_firmware_feature {
++ char *feature_name;
++ unsigned int feature_bit;
++ bool supported;
++ bool enabled;
++ void (*feature_status)(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_firmware_feature *firmware_feature);
++};
++
++static void pqi_firmware_feature_status(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_firmware_feature *firmware_feature)
++{
++ if (!firmware_feature->supported) {
++ dev_info(&ctrl_info->pci_dev->dev, "%s not supported by controller\n",
++ firmware_feature->feature_name);
++ return;
++ }
++
++ if (firmware_feature->enabled) {
++ dev_info(&ctrl_info->pci_dev->dev,
++ "%s enabled\n", firmware_feature->feature_name);
++ return;
++ }
++
++ dev_err(&ctrl_info->pci_dev->dev, "failed to enable %s\n",
++ firmware_feature->feature_name);
++}
++
++static inline void pqi_firmware_feature_update(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_firmware_feature *firmware_feature)
++{
++ if (firmware_feature->feature_status)
++ firmware_feature->feature_status(ctrl_info, firmware_feature);
++}
++
++static DEFINE_MUTEX(pqi_firmware_features_mutex);
++
++static struct pqi_firmware_feature pqi_firmware_features[] = {
++ {
++ .feature_name = "Online Firmware Activation",
++ .feature_bit = PQI_FIRMWARE_FEATURE_OFA,
++ .feature_status = pqi_firmware_feature_status,
++ },
++ {
++ .feature_name = "Serial Management Protocol",
++ .feature_bit = PQI_FIRMWARE_FEATURE_SMP,
++ .feature_status = pqi_firmware_feature_status,
++ },
++};
++
++static void pqi_process_firmware_features(
++ struct pqi_config_table_section_info *section_info)
++{
++ int rc;
++ struct pqi_ctrl_info *ctrl_info;
++ struct pqi_config_table_firmware_features *firmware_features;
++ void __iomem *firmware_features_iomem_addr;
++ unsigned int i;
++ unsigned int num_features_supported;
++
++ ctrl_info = section_info->ctrl_info;
++ firmware_features = section_info->section;
++ firmware_features_iomem_addr = section_info->section_iomem_addr;
++
++ for (i = 0, num_features_supported = 0;
++ i < ARRAY_SIZE(pqi_firmware_features); i++) {
++ if (pqi_is_firmware_feature_supported(firmware_features,
++ pqi_firmware_features[i].feature_bit)) {
++ pqi_firmware_features[i].supported = true;
++ num_features_supported++;
++ } else {
++ pqi_firmware_feature_update(ctrl_info,
++ &pqi_firmware_features[i]);
++ }
++ }
++
++ if (num_features_supported == 0)
++ return;
++
++ for (i = 0; i < ARRAY_SIZE(pqi_firmware_features); i++) {
++ if (!pqi_firmware_features[i].supported)
++ continue;
++ pqi_request_firmware_feature(firmware_features,
++ pqi_firmware_features[i].feature_bit);
++ }
++
++ rc = pqi_enable_firmware_features(ctrl_info, firmware_features,
++ firmware_features_iomem_addr);
++ if (rc) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "failed to enable firmware features in PQI configuration table\n");
++ for (i = 0; i < ARRAY_SIZE(pqi_firmware_features); i++) {
++ if (!pqi_firmware_features[i].supported)
++ continue;
++ pqi_firmware_feature_update(ctrl_info,
++ &pqi_firmware_features[i]);
++ }
++ return;
++ }
++
++ for (i = 0; i < ARRAY_SIZE(pqi_firmware_features); i++) {
++ if (!pqi_firmware_features[i].supported)
++ continue;
++ if (pqi_is_firmware_feature_enabled(firmware_features,
++ firmware_features_iomem_addr,
++ pqi_firmware_features[i].feature_bit))
++ pqi_firmware_features[i].enabled = true;
++ pqi_firmware_feature_update(ctrl_info,
++ &pqi_firmware_features[i]);
++ }
++}
++
++static void pqi_init_firmware_features(void)
++{
++ unsigned int i;
++
++ for (i = 0; i < ARRAY_SIZE(pqi_firmware_features); i++) {
++ pqi_firmware_features[i].supported = false;
++ pqi_firmware_features[i].enabled = false;
++ }
++}
++
++static void pqi_process_firmware_features_section(
++ struct pqi_config_table_section_info *section_info)
++{
++ mutex_lock(&pqi_firmware_features_mutex);
++ pqi_init_firmware_features();
++ pqi_process_firmware_features(section_info);
++ mutex_unlock(&pqi_firmware_features_mutex);
++}
++
+ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info)
+ {
+ u32 table_length;
+@@ -5953,8 +6186,11 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info)
+ void __iomem *table_iomem_addr;
+ struct pqi_config_table *config_table;
+ struct pqi_config_table_section_header *section;
++ struct pqi_config_table_section_info section_info;
+
+ table_length = ctrl_info->config_table_length;
++ if (table_length == 0)
++ return 0;
+
+ config_table = kmalloc(table_length, GFP_KERNEL);
+ if (!config_table) {
+@@ -5971,13 +6207,22 @@ static int pqi_process_config_table(struct pqi_ctrl_info *ctrl_info)
+ ctrl_info->config_table_offset;
+ memcpy_fromio(config_table, table_iomem_addr, table_length);
+
++ section_info.ctrl_info = ctrl_info;
+ section_offset =
+ get_unaligned_le32(&config_table->first_section_offset);
+
+ while (section_offset) {
+ section = (void *)config_table + section_offset;
+
++ section_info.section = section;
++ section_info.section_offset = section_offset;
++ section_info.section_iomem_addr =
++ table_iomem_addr + section_offset;
++
+ switch (get_unaligned_le16(&section->section_id)) {
++ case PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES:
++ pqi_process_firmware_features_section(&section_info);
++ break;
+ case PQI_CONFIG_TABLE_SECTION_HEARTBEAT:
+ if (pqi_disable_heartbeat)
+ dev_warn(&ctrl_info->pci_dev->dev,
+@@ -6122,10 +6367,6 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
+ ctrl_info->pqi_mode_enabled = true;
+ pqi_save_ctrl_mode(ctrl_info, PQI_MODE);
+
+- rc = pqi_process_config_table(ctrl_info);
+- if (rc)
+- return rc;
+-
+ rc = pqi_alloc_admin_queues(ctrl_info);
+ if (rc) {
+ dev_err(&ctrl_info->pci_dev->dev,
+@@ -6187,6 +6428,11 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
+ pqi_change_irq_mode(ctrl_info, IRQ_MODE_MSIX);
+
+ ctrl_info->controller_online = true;
++
++ rc = pqi_process_config_table(ctrl_info);
++ if (rc)
++ return rc;
++
+ pqi_start_heartbeat_timer(ctrl_info);
+
+ rc = pqi_enable_events(ctrl_info);
+
diff --git a/patches.drivers/scsi-smartpqi-add-sysfs-attributes b/patches.drivers/scsi-smartpqi-add-sysfs-attributes
new file mode 100644
index 0000000000..d8d4337340
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-add-sysfs-attributes
@@ -0,0 +1,319 @@
+From: Dave Carroll <david.carroll@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:47 -0600
+Subject: scsi: smartpqi: add sysfs attributes
+Git-commit: cd128244162c8afbf50e93b88daa02b05faa4c0a
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- add sysfs device attributes, unique_id, lunid and path_info.
+
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 3 +
+ drivers/scsi/smartpqi/smartpqi_init.c | 232 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 235 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index fcc4b937de71..a39c324dedab 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -852,6 +852,7 @@ struct pqi_scsi_dev {
+ u8 scsi3addr[8];
+ __be64 wwid;
+ u8 volume_id[16];
++ u8 unique_id[16];
+ u8 is_physical_device : 1;
+ u8 is_external_raid_device : 1;
+ u8 target_lun_valid : 1;
+@@ -898,6 +899,8 @@ struct pqi_scsi_dev {
+ #define CISS_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */
+ #define CISS_VPD_LV_BYPASS_STATUS 0xc2 /* vendor-specific page */
+ #define CISS_VPD_LV_STATUS 0xc3 /* vendor-specific page */
++#define SCSI_VPD_HEADER_SZ 4
++#define SCSI_VPD_DEVICE_ID_IDX 8 /* Index of page id in page */
+
+ #define VPD_PAGE (1 << 8)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 2a90d515b972..f6c83cb155b0 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -573,6 +573,79 @@ static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info,
+ buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT);
+ }
+
++static bool pqi_vpd_page_supported(struct pqi_ctrl_info *ctrl_info,
++ u8 *scsi3addr, u16 vpd_page)
++{
++ int rc;
++ int i;
++ int pages;
++ unsigned char *buf, bufsize;
++
++ buf = kzalloc(256, GFP_KERNEL);
++ if (!buf)
++ return false;
++
++ /* Get the size of the page list first */
++ rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
++ VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES,
++ buf, SCSI_VPD_HEADER_SZ);
++ if (rc != 0)
++ goto exit_unsupported;
++
++ pages = buf[3];
++ if ((pages + SCSI_VPD_HEADER_SZ) <= 255)
++ bufsize = pages + SCSI_VPD_HEADER_SZ;
++ else
++ bufsize = 255;
++
++ /* Get the whole VPD page list */
++ rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
++ VPD_PAGE | SCSI_VPD_SUPPORTED_PAGES,
++ buf, bufsize);
++ if (rc != 0)
++ goto exit_unsupported;
++
++ pages = buf[3];
++ for (i = 1; i <= pages; i++)
++ if (buf[3 + i] == vpd_page)
++ goto exit_supported;
++
++exit_unsupported:
++ kfree(buf);
++ return false;
++
++exit_supported:
++ kfree(buf);
++ return true;
++}
++
++static int pqi_get_device_id(struct pqi_ctrl_info *ctrl_info,
++ u8 *scsi3addr, u8 *device_id, int buflen)
++{
++ int rc;
++ unsigned char *buf;
++
++ if (!pqi_vpd_page_supported(ctrl_info, scsi3addr, SCSI_VPD_DEVICE_ID))
++ return 1; /* function not supported */
++
++ buf = kzalloc(64, GFP_KERNEL);
++ if (!buf)
++ return -ENOMEM;
++
++ rc = pqi_scsi_inquiry(ctrl_info, scsi3addr,
++ VPD_PAGE | SCSI_VPD_DEVICE_ID,
++ buf, 64);
++ if (rc == 0) {
++ if (buflen > 16)
++ buflen = 16;
++ memcpy(device_id, &buf[SCSI_VPD_DEVICE_ID_IDX], buflen);
++ }
++
++ kfree(buf);
++
++ return rc;
++}
++
+ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device,
+ struct bmic_identify_physical_device *buffer,
+@@ -1244,6 +1317,14 @@ static int pqi_get_device_info(struct pqi_ctrl_info *ctrl_info,
+ }
+ }
+
++ if (pqi_get_device_id(ctrl_info, device->scsi3addr,
++ device->unique_id, sizeof(device->unique_id)) < 0)
++ dev_warn(&ctrl_info->pci_dev->dev,
++ "Can't get device id for scsi %d:%d:%d:%d\n",
++ ctrl_info->scsi_host->host_no,
++ device->bus, device->target,
++ device->lun);
++
+ out:
+ kfree(buffer);
+
+@@ -1775,6 +1856,12 @@ static inline bool pqi_skip_device(u8 *scsi3addr)
+ return false;
+ }
+
++static inline bool pqi_expose_device(struct pqi_scsi_dev *device)
++{
++ return !device->is_physical_device ||
++ !pqi_skip_device(device->scsi3addr);
++}
++
+ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info)
+ {
+ int i;
+@@ -5722,6 +5809,145 @@ static struct device_attribute *pqi_shost_attrs[] = {
+ NULL
+ };
+
++static ssize_t pqi_unique_id_show(struct device *dev,
++ struct device_attribute *attr, char *buffer)
++{
++ struct pqi_ctrl_info *ctrl_info;
++ struct scsi_device *sdev;
++ struct pqi_scsi_dev *device;
++ unsigned long flags;
++ unsigned char uid[16];
++
++ sdev = to_scsi_device(dev);
++ ctrl_info = shost_to_hba(sdev->host);
++
++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
++
++ device = sdev->hostdata;
++ if (!device) {
++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
++ flags);
++ return -ENODEV;
++ }
++ memcpy(uid, device->unique_id, sizeof(uid));
++
++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
++
++ return snprintf(buffer, PAGE_SIZE, "%16phN", uid);
++}
++
++static ssize_t pqi_lunid_show(struct device *dev,
++ struct device_attribute *attr, char *buffer)
++{
++ struct pqi_ctrl_info *ctrl_info;
++ struct scsi_device *sdev;
++ struct pqi_scsi_dev *device;
++ unsigned long flags;
++ u8 lunid[8];
++
++ sdev = to_scsi_device(dev);
++ ctrl_info = shost_to_hba(sdev->host);
++
++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
++
++ device = sdev->hostdata;
++ if (!device) {
++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
++ flags);
++ return -ENODEV;
++ }
++ memcpy(lunid, device->scsi3addr, sizeof(lunid));
++
++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
++
++ return snprintf(buffer, PAGE_SIZE, "0x%8phN\n", lunid);
++}
++
++#define MAX_PATHS 8
++static ssize_t pqi_path_info_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct pqi_ctrl_info *ctrl_info;
++ struct scsi_device *sdev;
++ struct pqi_scsi_dev *device;
++ unsigned long flags;
++ int i;
++ int output_len = 0;
++ u8 box;
++ u8 bay;
++ u8 path_map_index = 0;
++ char *active;
++ unsigned char phys_connector[2];
++
++ sdev = to_scsi_device(dev);
++ ctrl_info = shost_to_hba(sdev->host);
++
++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags);
++
++ device = sdev->hostdata;
++ if (!device) {
++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock,
++ flags);
++ return -ENODEV;
++ }
++
++ bay = device->bay;
++ for (i = 0; i < MAX_PATHS; i++) {
++ path_map_index = 1<<i;
++ if (i == device->active_path_index)
++ active = "Active";
++ else if (device->path_map & path_map_index)
++ active = "Inactive";
++ else
++ continue;
++
++ output_len += scnprintf(buf + output_len,
++ PAGE_SIZE - output_len,
++ "[%d:%d:%d:%d] %20.20s ",
++ ctrl_info->scsi_host->host_no,
++ device->bus, device->target,
++ device->lun,
++ scsi_device_type(device->devtype));
++
++ if (device->devtype == TYPE_RAID ||
++ pqi_is_logical_device(device))
++ goto end_buffer;
++
++ memcpy(&phys_connector, &device->phys_connector[i],
++ sizeof(phys_connector));
++ if (phys_connector[0] < '0')
++ phys_connector[0] = '0';
++ if (phys_connector[1] < '0')
++ phys_connector[1] = '0';
++
++ output_len += scnprintf(buf + output_len,
++ PAGE_SIZE - output_len,
++ "PORT: %.2s ", phys_connector);
++
++ box = device->box[i];
++ if (box != 0 && box != 0xFF)
++ output_len += scnprintf(buf + output_len,
++ PAGE_SIZE - output_len,
++ "BOX: %hhu ", box);
++
++ if ((device->devtype == TYPE_DISK ||
++ device->devtype == TYPE_ZBC) &&
++ pqi_expose_device(device))
++ output_len += scnprintf(buf + output_len,
++ PAGE_SIZE - output_len,
++ "BAY: %hhu ", bay);
++
++end_buffer:
++ output_len += scnprintf(buf + output_len,
++ PAGE_SIZE - output_len,
++ "%s\n", active);
++ }
++
++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
++ return output_len;
++}
++
++
+ static ssize_t pqi_sas_address_show(struct device *dev,
+ struct device_attribute *attr, char *buffer)
+ {
+@@ -5798,12 +6024,18 @@ static ssize_t pqi_raid_level_show(struct device *dev,
+ return snprintf(buffer, PAGE_SIZE, "%s\n", raid_level);
+ }
+
++static DEVICE_ATTR(lunid, 0444, pqi_lunid_show, NULL);
++static DEVICE_ATTR(unique_id, 0444, pqi_unique_id_show, NULL);
++static DEVICE_ATTR(path_info, 0444, pqi_path_info_show, NULL);
+ static DEVICE_ATTR(sas_address, 0444, pqi_sas_address_show, NULL);
+ static DEVICE_ATTR(ssd_smart_path_enabled, 0444,
+ pqi_ssd_smart_path_enabled_show, NULL);
+ static DEVICE_ATTR(raid_level, 0444, pqi_raid_level_show, NULL);
+
+ static struct device_attribute *pqi_sdev_attrs[] = {
++ &dev_attr_lunid,
++ &dev_attr_unique_id,
++ &dev_attr_path_info,
+ &dev_attr_sas_address,
+ &dev_attr_ssd_smart_path_enabled,
+ &dev_attr_raid_level,
+
diff --git a/patches.drivers/scsi-smartpqi-allow-for-larger-raid-maps b/patches.drivers/scsi-smartpqi-allow-for-larger-raid-maps
new file mode 100644
index 0000000000..c7ab64d988
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-allow-for-larger-raid-maps
@@ -0,0 +1,123 @@
+From: Ajish Koshy <ajish.koshy@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:31 -0600
+Subject: scsi: smartpqi: allow for larger raid maps
+Git-commit: a91aaae0243b419e52e97990471208321222be33
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 59 +++++++++++++++++------------------
+ 1 file changed, 28 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 8c848e136d33..d6fb49496796 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -1115,8 +1115,6 @@ static int pqi_validate_raid_map(struct pqi_ctrl_info *ctrl_info,
+ char *err_msg;
+ u32 raid_map_size;
+ u32 r5or6_blocks_per_row;
+- unsigned int num_phys_disks;
+- unsigned int num_raid_map_entries;
+
+ raid_map_size = get_unaligned_le32(&raid_map->structure_size);
+
+@@ -1125,22 +1123,6 @@ static int pqi_validate_raid_map(struct pqi_ctrl_info *ctrl_info,
+ goto bad_raid_map;
+ }
+
+- if (raid_map_size > sizeof(*raid_map)) {
+- err_msg = "RAID map too large";
+- goto bad_raid_map;
+- }
+-
+- num_phys_disks = get_unaligned_le16(&raid_map->layout_map_count) *
+- (get_unaligned_le16(&raid_map->data_disks_per_row) +
+- get_unaligned_le16(&raid_map->metadata_disks_per_row));
+- num_raid_map_entries = num_phys_disks *
+- get_unaligned_le16(&raid_map->row_cnt);
+-
+- if (num_raid_map_entries > RAID_MAP_MAX_ENTRIES) {
+- err_msg = "invalid number of map entries in RAID map";
+- goto bad_raid_map;
+- }
+-
+ if (device->raid_level == SA_RAID_1) {
+ if (get_unaligned_le16(&raid_map->layout_map_count) != 2) {
+ err_msg = "invalid RAID-1 map";
+@@ -1179,27 +1161,45 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device)
+ {
+ int rc;
+- enum dma_data_direction dir;
+- struct pqi_raid_path_request request;
++ u32 raid_map_size;
+ struct raid_map *raid_map;
+
+ raid_map = kmalloc(sizeof(*raid_map), GFP_KERNEL);
+ if (!raid_map)
+ return -ENOMEM;
+
+- rc = pqi_build_raid_path_request(ctrl_info, &request,
+- CISS_GET_RAID_MAP, device->scsi3addr, raid_map,
+- sizeof(*raid_map), 0, &dir);
++ rc = pqi_send_scsi_raid_request(ctrl_info, CISS_GET_RAID_MAP,
++ device->scsi3addr, raid_map, sizeof(*raid_map),
++ 0, NULL, NO_TIMEOUT);
++
+ if (rc)
+ goto error;
+
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+- NULL, NO_TIMEOUT);
++ raid_map_size = get_unaligned_le32(&raid_map->structure_size);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
++ if (raid_map_size > sizeof(*raid_map)) {
+
+- if (rc)
+- goto error;
++ kfree(raid_map);
++
++ raid_map = kmalloc(raid_map_size, GFP_KERNEL);
++ if (!raid_map)
++ return -ENOMEM;
++
++ rc = pqi_send_scsi_raid_request(ctrl_info, CISS_GET_RAID_MAP,
++ device->scsi3addr, raid_map, raid_map_size,
++ 0, NULL, NO_TIMEOUT);
++ if (rc)
++ goto error;
++
++ if (get_unaligned_le32(&raid_map->structure_size)
++ != raid_map_size) {
++ dev_warn(&ctrl_info->pci_dev->dev,
++ "Requested %d bytes, received %d bytes",
++ raid_map_size,
++ get_unaligned_le32(&raid_map->structure_size));
++ goto error;
++ }
++ }
+
+ rc = pqi_validate_raid_map(ctrl_info, device, raid_map);
+ if (rc)
+@@ -2459,9 +2459,6 @@ static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
+ (map_row * total_disks_per_row) + first_column;
+ }
+
+- if (unlikely(map_index >= RAID_MAP_MAX_ENTRIES))
+- return PQI_RAID_BYPASS_INELIGIBLE;
+-
+ aio_handle = raid_map->disk_data[map_index].aio_handle;
+ disk_block = get_unaligned_le64(&raid_map->disk_starting_blk) +
+ first_row * strip_size +
+
diff --git a/patches.drivers/scsi-smartpqi-bump-driver-version b/patches.drivers/scsi-smartpqi-bump-driver-version
new file mode 100644
index 0000000000..f8fd5bb61a
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-bump-driver-version
@@ -0,0 +1,36 @@
+From: Don Brace <don.brace@microsemi.com>
+Date: Fri, 7 Dec 2018 16:30:12 -0600
+Subject: scsi: smartpqi: bump driver version
+Git-commit: f7cb8ac6e776158fab003d8dc6b7f564f005f502
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Gerry Morong <gerry.morong@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 96e171038eb6..4e384e0fcaa9 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -40,11 +40,11 @@
+ #define BUILD_TIMESTAMP
+ #endif
+
+-#define DRIVER_VERSION "1.1.4-130"
++#define DRIVER_VERSION "1.2.4-065"
+ #define DRIVER_MAJOR 1
+-#define DRIVER_MINOR 1
++#define DRIVER_MINOR 2
+ #define DRIVER_RELEASE 4
+-#define DRIVER_REVISION 130
++#define DRIVER_REVISION 65
+
+ #define DRIVER_NAME "Microsemi PQI Driver (v" \
+ DRIVER_VERSION BUILD_TIMESTAMP ")"
+
diff --git a/patches.drivers/scsi-smartpqi-bump-driver-version-171f1887 b/patches.drivers/scsi-smartpqi-bump-driver-version-171f1887
new file mode 100644
index 0000000000..d6ebf29a9f
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-bump-driver-version-171f1887
@@ -0,0 +1,39 @@
+From: Don Brace <don.brace@microsemi.com>
+Date: Thu, 14 Mar 2019 16:58:16 -0500
+Subject: scsi: smartpqi: bump driver version
+Git-commit: 171f1887995b4f430962147ad42ec35631cf2525
+Patch-mainline: v5.2-rc1
+References: bsc#1133547
+
+Reviewed-by: Gerry Morong <gerry.morong@microsemi.com>
+Reviewed-by: David Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index e8b9ff19359c..06344b5d1126 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -33,11 +33,11 @@
+ #define BUILD_TIMESTAMP
+ #endif
+
+-#define DRIVER_VERSION "1.2.4-070"
++#define DRIVER_VERSION "1.2.6-015"
+ #define DRIVER_MAJOR 1
+ #define DRIVER_MINOR 2
+-#define DRIVER_RELEASE 4
+-#define DRIVER_REVISION 70
++#define DRIVER_RELEASE 6
++#define DRIVER_REVISION 15
+
+ #define DRIVER_NAME "Microsemi PQI Driver (v" \
+ DRIVER_VERSION BUILD_TIMESTAMP ")"
+
diff --git a/patches.drivers/scsi-smartpqi-call-pqi_free_interrupts-in-pqi_shutdown b/patches.drivers/scsi-smartpqi-call-pqi_free_interrupts-in-pqi_shutdown
new file mode 100644
index 0000000000..7c8297ed70
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-call-pqi_free_interrupts-in-pqi_shutdown
@@ -0,0 +1,63 @@
+From: Yanjiang Jin <yanjiang.jin@hxt-semitech.com>
+Date: Thu, 20 Dec 2018 16:32:35 +0800
+Subject: scsi: smartpqi: call pqi_free_interrupts() in pqi_shutdown()
+Git-commit: e57b2945aa654e48f85a41e8917793c64ecb9de8
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+We must free all irqs during shutdown, else kexec's 2nd kernel would hang
+in pqi_wait_for_completion_io() as below:
+
+Call trace:
+
+ pqi_wait_for_completion_io
+ pqi_submit_raid_request_synchronous.constprop.78+0x23c/0x310 [smartpqi]
+ pqi_configure_events+0xec/0x1f8 [smartpqi]
+ pqi_ctrl_init+0x814/0xca0 [smartpqi]
+ pqi_pci_probe+0x400/0x46c [smartpqi]
+ local_pci_probe+0x48/0xb0
+ pci_device_probe+0x14c/0x1b0
+ really_probe+0x218/0x3fc
+ driver_probe_device+0x70/0x140
+ __driver_attach+0x11c/0x134
+ bus_for_each_dev+0x70/0xc8
+ driver_attach+0x30/0x38
+ bus_add_driver+0x1f0/0x294
+ driver_register+0x74/0x12c
+ __pci_register_driver+0x64/0x70
+ pqi_init+0xd0/0x10000 [smartpqi]
+ do_one_initcall+0x60/0x1d8
+ do_init_module+0x64/0x1f8
+ load_module+0x10ec/0x1350
+ __se_sys_finit_module+0xd4/0x100
+ __arm64_sys_finit_module+0x28/0x34
+ el0_svc_handler+0x104/0x160
+ el0_svc+0x8/0xc
+
+This happens only in the following combinations:
+
+1. smartpqi is built as module, not built-in;
+2. We have a disk connected to smartpqi card;
+3. Both kexec's 1st and 2nd kernels use this disk as Rootfs' mount point.
+
+Signed-off-by: Yanjiang Jin <yanjiang.jin@hxt-semitech.com>
+Acked-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 39f8cf8449d5..34693f535a46 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -7812,6 +7812,7 @@ static void pqi_shutdown(struct pci_dev *pci_dev)
+ * storage.
+ */
+ rc = pqi_flush_cache(ctrl_info, SHUTDOWN);
++ pqi_free_interrupts(ctrl_info);
+ pqi_reset(ctrl_info);
+ if (rc == 0)
+ return;
+
diff --git a/patches.drivers/scsi-smartpqi-check-for-null-device-pointers b/patches.drivers/scsi-smartpqi-check-for-null-device-pointers
new file mode 100644
index 0000000000..e37a49f393
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-check-for-null-device-pointers
@@ -0,0 +1,181 @@
+From: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:24 -0600
+Subject: scsi: smartpqi: check for null device pointers
+Git-commit: 1e46731efd9c9322cb4699f845c739d2ea68555c
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- wait on all outstanding I/O to complete before the device is removed.
+
+- check for null device pointers in IO entry/completion functions.
+
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 2 ++
+ drivers/scsi/smartpqi/smartpqi_init.c | 65 +++++++++++++++++++++++++++++++++--
+ 2 files changed, 64 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index a39c324dedab..4f52b5be3693 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -862,6 +862,7 @@ struct pqi_scsi_dev {
+ u8 volume_offline : 1;
+ bool aio_enabled; /* only valid for physical disks */
+ bool in_reset;
++ bool in_remove;
+ bool device_offline;
+ u8 vendor[8]; /* bytes 8-15 of inquiry data */
+ u8 model[16]; /* bytes 16-31 of inquiry data */
+@@ -1063,6 +1064,7 @@ struct pqi_ctrl_info {
+ struct mutex lun_reset_mutex;
+ bool controller_online;
+ bool block_requests;
++ bool in_shutdown;
+ u8 inbound_spanning_supported : 1;
+ u8 outbound_spanning_supported : 1;
+ u8 pqi_mode_enabled : 1;
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 3678bd7ac8b7..8c848e136d33 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -74,6 +74,8 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
+ struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
+ unsigned int cdb_length, struct pqi_queue_group *queue_group,
+ struct pqi_encryption_info *encryption_info, bool raid_bypass);
++static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_scsi_dev *device, unsigned long timeout_secs);
+
+ /* for flags argument to pqi_submit_raid_request_synchronous() */
+ #define PQI_SYNC_FLAGS_INTERRUPTABLE 0x1
+@@ -317,6 +319,17 @@ static inline bool pqi_device_in_reset(struct pqi_scsi_dev *device)
+ return device->in_reset;
+ }
+
++static inline void pqi_device_remove_start(struct pqi_scsi_dev *device)
++{
++ device->in_remove = true;
++}
++
++static inline bool pqi_device_in_remove(struct pqi_ctrl_info *ctrl_info,
++ struct pqi_scsi_dev *device)
++{
++ return device->in_remove & !ctrl_info->in_shutdown;
++}
++
+ static inline void pqi_schedule_rescan_worker_with_delay(
+ struct pqi_ctrl_info *ctrl_info, unsigned long delay)
+ {
+@@ -1487,9 +1500,24 @@ static int pqi_add_device(struct pqi_ctrl_info *ctrl_info,
+ return rc;
+ }
+
++#define PQI_PENDING_IO_TIMEOUT_SECS 20
++
+ static inline void pqi_remove_device(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device)
+ {
++ int rc;
++
++ pqi_device_remove_start(device);
++
++ rc = pqi_device_wait_for_pending_io(ctrl_info, device,
++ PQI_PENDING_IO_TIMEOUT_SECS);
++ if (rc)
++ dev_err(&ctrl_info->pci_dev->dev,
++ "scsi %d:%d:%d:%d removing device with %d outstanding commands\n",
++ ctrl_info->scsi_host->host_no, device->bus,
++ device->target, device->lun,
++ atomic_read(&device->scsi_cmds_outstanding));
++
+ if (pqi_is_logical_device(device))
+ scsi_remove_device(device->sdev);
+ else
+@@ -5042,7 +5070,17 @@ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd)
+ {
+ struct pqi_scsi_dev *device;
+
++ if (!scmd->device) {
++ set_host_byte(scmd, DID_NO_CONNECT);
++ return;
++ }
++
+ device = scmd->device->hostdata;
++ if (!device) {
++ set_host_byte(scmd, DID_NO_CONNECT);
++ return;
++ }
++
+ atomic_dec(&device->scsi_cmds_outstanding);
+ }
+
+@@ -5059,9 +5097,16 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost,
+ device = scmd->device->hostdata;
+ ctrl_info = shost_to_hba(shost);
+
++ if (!device) {
++ set_host_byte(scmd, DID_NO_CONNECT);
++ pqi_scsi_done(scmd);
++ return 0;
++ }
++
+ atomic_inc(&device->scsi_cmds_outstanding);
+
+- if (pqi_ctrl_offline(ctrl_info)) {
++ if (pqi_ctrl_offline(ctrl_info) || pqi_device_in_remove(ctrl_info,
++ device)) {
+ set_host_byte(scmd, DID_NO_CONNECT);
+ pqi_scsi_done(scmd);
+ return 0;
+@@ -5214,12 +5259,23 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info,
+ }
+
+ static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info,
+- struct pqi_scsi_dev *device)
++ struct pqi_scsi_dev *device, unsigned long timeout_secs)
+ {
++ unsigned long timeout;
++
++ timeout = (timeout_secs * HZ) + jiffies;
++
+ while (atomic_read(&device->scsi_cmds_outstanding)) {
+ pqi_check_ctrl_health(ctrl_info);
+ if (pqi_ctrl_offline(ctrl_info))
+ return -ENXIO;
++ if (timeout_secs != NO_TIMEOUT) {
++ if (time_after(jiffies, timeout)) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "timed out waiting for pending IO\n");
++ return -ETIMEDOUT;
++ }
++ }
+ usleep_range(1000, 2000);
+ }
+
+@@ -5345,7 +5401,8 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
+ msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS);
+ }
+ if (rc == 0)
+- rc = pqi_device_wait_for_pending_io(ctrl_info, device);
++ rc = pqi_device_wait_for_pending_io(ctrl_info,
++ device, NO_TIMEOUT);
+
+ return rc == 0 ? SUCCESS : FAILED;
+ }
+@@ -7188,6 +7245,8 @@ static void pqi_pci_remove(struct pci_dev *pci_dev)
+ if (!ctrl_info)
+ return;
+
++ ctrl_info->in_shutdown = true;
++
+ pqi_remove_ctrl(ctrl_info);
+ }
+
+
diff --git a/patches.drivers/scsi-smartpqi-correct-host-serial-num-for-ssa b/patches.drivers/scsi-smartpqi-correct-host-serial-num-for-ssa
new file mode 100644
index 0000000000..fa5f4a85ae
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-correct-host-serial-num-for-ssa
@@ -0,0 +1,44 @@
+From: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:29 -0600
+Subject: scsi: smartpqi: correct host serial num for ssa
+Git-commit: b2346b5030cf9458f30a84028d9fe904b8c942a7
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 591787b46333..033e8a028812 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -645,6 +645,7 @@ struct bmic_host_wellness_driver_version {
+ u8 driver_version_tag[2];
+ __le16 driver_version_length;
+ char driver_version[32];
++ u8 dont_write_tag[2];
+ u8 end_tag[2];
+ };
+
+@@ -674,6 +675,8 @@ static int pqi_write_driver_version_to_host_wellness(
+ strncpy(buffer->driver_version, "Linux " DRIVER_VERSION,
+ sizeof(buffer->driver_version) - 1);
+ buffer->driver_version[sizeof(buffer->driver_version) - 1] = '\0';
++ buffer->dont_write_tag[0] = 'D';
++ buffer->dont_write_tag[1] = 'W';
+ buffer->end_tag[0] = 'Z';
+ buffer->end_tag[1] = 'Z';
+
+
diff --git a/patches.drivers/scsi-smartpqi-correct-lun-reset-issues b/patches.drivers/scsi-smartpqi-correct-lun-reset-issues
new file mode 100644
index 0000000000..993aa82b48
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-correct-lun-reset-issues
@@ -0,0 +1,77 @@
+From: Kevin Barnett <kevin.barnett@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:51 -0600
+Subject: scsi: smartpqi: correct lun reset issues
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Git-commit: 2ba55c9851d74eb015a554ef69ddf2ef061d5780
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Problem:
+The Linux kernel takes a logical volume offline after a LUN reset. This is
+generally accompanied by this message in the dmesg output:
+
+Device offlined - not ready after error recovery
+
+Root Cause:
+The root cause is a "quirk" in the timeout handling in the Linux SCSI
+layer. The Linux kernel places a 30-second timeout on most media access
+commands (reads and writes) that it send to device drivers. When a media
+access command times out, the Linux kernel goes into error recovery mode
+for the LUN that was the target of the command that timed out. Every
+command that timed out is kept on a list inside of the Linux kernel to be
+retried later. The kernel attempts to recover the command(s) that timed out
+by issuing a LUN reset followed by a TEST UNIT READY. If the LUN reset and
+TEST UNIT READY commands are successful, the kernel retries the command(s)
+that timed out.
+
+Each SCSI command issued by the kernel has a result field associated with
+it. This field indicates the final result of the command (success or
+error). When a command times out, the kernel places a value in this result
+field indicating that the command timed out.
+
+The "quirk" is that after the LUN reset and TEST UNIT READY commands are
+completed, the kernel checks each command on the timed-out command list
+before retrying it. If the result field is still "timed out", the kernel
+treats that command as not having been successfully recovered for a
+retry. If the number of commands that are in this state are greater than
+two, the kernel takes the LUN offline.
+
+Fix:
+When our RAIDStack receives a LUN reset, it simply waits until all
+outstanding commands complete. Generally, all of these outstanding commands
+complete successfully. Therefore, the fix in the smartpqi driver is to
+always set the command result field to indicate success when a request
+completes successfully. This normally isn’t necessary because the result
+field is always initialized to success when the command is submitted to the
+driver. So when the command completes successfully, the result field is
+left untouched. But in this case, the kernel changes the result field
+behind the driver’s back and then expects the field to be changed by the
+driver as the commands that timed-out complete.
+
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index a2730265799e..509a081a6f17 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -2841,6 +2841,9 @@ static unsigned int pqi_process_io_intr(struct pqi_ctrl_info *ctrl_info,
+ switch (response->header.iu_type) {
+ case PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS:
+ case PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS:
++ if (io_request->scmd)
++ io_request->scmd->result = 0;
++ /* fall through */
+ case PQI_RESPONSE_IU_GENERAL_MANAGEMENT:
+ break;
+ case PQI_RESPONSE_IU_VENDOR_GENERAL:
+
diff --git a/patches.drivers/scsi-smartpqi-correct-volume-status b/patches.drivers/scsi-smartpqi-correct-volume-status
new file mode 100644
index 0000000000..985ff923ca
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-correct-volume-status
@@ -0,0 +1,41 @@
+From: Dave Carroll <david.carroll@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:45 -0600
+Subject: scsi: smartpqi: correct volume status
+Git-commit: 7ff44499bafbd376115f0bb6b578d980f56ee13b
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- fix race condition when a unit is deleted after an RLL,
+ and before we have gotten the LV_STATUS page of the unit.
+ - In this case we will get a standard inquiry, rather than
+ the desired page. This will result in a unit presented
+ which no longer exists.
+ - If we ask for LV_STATUS, insure we get LV_STATUS
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index f4080ac832dd..a2730265799e 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -1270,6 +1270,9 @@ static void pqi_get_volume_status(struct pqi_ctrl_info *ctrl_info,
+ if (rc)
+ goto out;
+
++ if (vpd->page_code != CISS_VPD_LV_STATUS)
++ goto out;
++
+ page_length = offsetof(struct ciss_vpd_logical_volume_status,
+ volume_status) + vpd->page_length;
+ if (page_length < sizeof(*vpd))
+
diff --git a/patches.drivers/scsi-smartpqi-do-not-offline-disks-for-transient-did-no-connect-conditions b/patches.drivers/scsi-smartpqi-do-not-offline-disks-for-transient-did-no-connect-conditions
new file mode 100644
index 0000000000..85a1333252
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-do-not-offline-disks-for-transient-did-no-connect-conditions
@@ -0,0 +1,45 @@
+From: Dave Carroll <david.carroll@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:37 -0600
+Subject: scsi: smartpqi: do not offline disks for transient did no connect
+ conditions
+Git-commit: a9a681017c3b43b9d9754dd87bebe5e0e244fe08
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index d6fb49496796..f4080ac832dd 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -1686,6 +1686,7 @@ static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
+ new_device->raid_bypass_configured;
+ existing_device->raid_bypass_enabled =
+ new_device->raid_bypass_enabled;
++ existing_device->device_offline = false;
+
+ /* To prevent this from being freed later. */
+ new_device->raid_map = NULL;
+@@ -2589,10 +2590,9 @@ static inline void pqi_take_device_offline(struct scsi_device *sdev, char *path)
+ return;
+
+ device->device_offline = true;
+- scsi_device_set_state(sdev, SDEV_OFFLINE);
+ ctrl_info = shost_to_hba(sdev->host);
+ pqi_schedule_rescan_worker(ctrl_info);
+- dev_err(&ctrl_info->pci_dev->dev, "offlined %s scsi %d:%d:%d:%d\n",
++ dev_err(&ctrl_info->pci_dev->dev, "re-scanning %s scsi %d:%d:%d:%d\n",
+ path, ctrl_info->scsi_host->host_no, device->bus,
+ device->target, device->lun);
+ }
+
diff --git a/patches.drivers/scsi-smartpqi-enhance-numa-node-detection b/patches.drivers/scsi-smartpqi-enhance-numa-node-detection
new file mode 100644
index 0000000000..ee15a4e086
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-enhance-numa-node-detection
@@ -0,0 +1,52 @@
+From: Sagar Biradar <sagar.biradar@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:12 -0600
+Subject: scsi: smartpqi: enhance numa node detection
+Git-commit: 62dc51fb946697c896e47df7187862c310a3d21c
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- set pci_dev->dev to 0 only if the node is NO_NUMA_NODE.
+ If not, do not reset the value but retain it.
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Sagar Biradar <sagar.biradar@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 273daa2c2b68..ed4dd71426be 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -7130,7 +7130,7 @@ static int pqi_pci_probe(struct pci_dev *pci_dev,
+ const struct pci_device_id *id)
+ {
+ int rc;
+- int node;
++ int node, cp_node;
+ struct pqi_ctrl_info *ctrl_info;
+
+ pqi_print_ctrl_info(pci_dev, id);
+@@ -7148,8 +7148,12 @@ static int pqi_pci_probe(struct pci_dev *pci_dev,
+ "controller device ID matched using wildcards\n");
+
+ node = dev_to_node(&pci_dev->dev);
+- if (node == NUMA_NO_NODE)
+- set_dev_node(&pci_dev->dev, 0);
++ if (node == NUMA_NO_NODE) {
++ cp_node = cpu_to_node(0);
++ if (cp_node == NUMA_NO_NODE)
++ cp_node = 0;
++ set_dev_node(&pci_dev->dev, cp_node);
++ }
+
+ ctrl_info = pqi_alloc_ctrl_info(node);
+ if (!ctrl_info) {
+
diff --git a/patches.drivers/scsi-smartpqi-fix-build-warnings b/patches.drivers/scsi-smartpqi-fix-build-warnings
new file mode 100644
index 0000000000..03ad0858e8
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-fix-build-warnings
@@ -0,0 +1,48 @@
+From: Don Brace <don.brace@microsemi.com>
+Date: Thu, 20 Dec 2018 19:32:12 -0500
+Subject: scsi: smartpqi: fix build warnings
+Git-commit: e52c9e0710d2f5d54a521d620a230ac2ae646dc7
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Fix kbuild warning and fallout from linux-next -Wimplicit-fallthrough.
+
+[mkp: added fall through statements]
+
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index bfd2dd3496da..39f8cf8449d5 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -476,6 +476,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+ break;
+ case BMIC_SENSE_DIAG_OPTIONS:
+ cdb_length = 0;
++ /* fall through */
+ case BMIC_IDENTIFY_CONTROLLER:
+ case BMIC_IDENTIFY_PHYSICAL_DEVICE:
+ request->data_direction = SOP_READ_FLAG;
+@@ -485,6 +486,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+ break;
+ case BMIC_SET_DIAG_OPTIONS:
+ cdb_length = 0;
++ /* fall through */
+ case BMIC_WRITE_HOST_WELLNESS:
+ request->data_direction = SOP_WRITE_FLAG;
+ cdb[0] = BMIC_WRITE;
+@@ -7468,7 +7470,7 @@ static int pqi_ofa_alloc_mem(struct pqi_ctrl_info *ctrl_info,
+ dev = &ctrl_info->pci_dev->dev;
+
+ sg_count = (total_size + chunk_size - 1);
+- do_div(sg_count, chunk_size);
++ sg_count /= chunk_size;
+
+ ofap = ctrl_info->pqi_ofa_mem_virt_addr;
+
+
diff --git a/patches.drivers/scsi-smartpqi-fix-disk-name-mount-point b/patches.drivers/scsi-smartpqi-fix-disk-name-mount-point
new file mode 100644
index 0000000000..0df94b0ad2
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-fix-disk-name-mount-point
@@ -0,0 +1,40 @@
+From: Murthy Bhat <murthy.bhat@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:59 -0600
+Subject: scsi: smartpqi: fix disk name mount point
+Git-commit: 5995b236c10a0af748ae7f4e4819307cf6bc3140
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- fix a formatting issue.
+
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index b0d00157a667..74bd8d90c615 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5833,7 +5833,12 @@ static ssize_t pqi_unique_id_show(struct device *dev,
+
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+
+- return snprintf(buffer, PAGE_SIZE, "%16phN", uid);
++ return snprintf(buffer, PAGE_SIZE,
++ "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n",
++ uid[0], uid[1], uid[2], uid[3],
++ uid[4], uid[5], uid[6], uid[7],
++ uid[8], uid[9], uid[10], uid[11],
++ uid[12], uid[13], uid[14], uid[15]);
+ }
+
+ static ssize_t pqi_lunid_show(struct device *dev,
+
diff --git a/patches.drivers/scsi-smartpqi-fully-convert-to-the-generic-dma-api b/patches.drivers/scsi-smartpqi-fully-convert-to-the-generic-dma-api
new file mode 100644
index 0000000000..b802755331
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-fully-convert-to-the-generic-dma-api
@@ -0,0 +1,389 @@
+From: Christoph Hellwig <hch@lst.de>
+Date: Thu, 11 Oct 2018 09:47:59 +0200
+Subject: scsi: smartpqi: fully convert to the generic DMA API
+Git-commit: 6917a9cc28181b37d142f1c5813a6888f41572e7
+Patch-mainline: v4.20-rc1
+References: bsc#1133547
+
+The driver is currently using an odd mix of legacy PCI DMA API and
+generic DMA API calls, switch it over to the generic API entirely.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Tested-by: Don Brace <don.brace@microchip.com>
+Acked-by: Don Brace <don.brace@microchip.com>
+Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 100 ++++++++++++++--------------------
+ drivers/scsi/smartpqi/smartpqi_sis.c | 11 ++--
+ 2 files changed, 47 insertions(+), 64 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 2112ea6723c6..a25a07a0b7f0 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -349,16 +349,16 @@ static inline u32 pqi_read_heartbeat_counter(struct pqi_ctrl_info *ctrl_info)
+
+ static int pqi_map_single(struct pci_dev *pci_dev,
+ struct pqi_sg_descriptor *sg_descriptor, void *buffer,
+- size_t buffer_length, int data_direction)
++ size_t buffer_length, enum dma_data_direction data_direction)
+ {
+ dma_addr_t bus_address;
+
+- if (!buffer || buffer_length == 0 || data_direction == PCI_DMA_NONE)
++ if (!buffer || buffer_length == 0 || data_direction == DMA_NONE)
+ return 0;
+
+- bus_address = pci_map_single(pci_dev, buffer, buffer_length,
++ bus_address = dma_map_single(&pci_dev->dev, buffer, buffer_length,
+ data_direction);
+- if (pci_dma_mapping_error(pci_dev, bus_address))
++ if (dma_mapping_error(&pci_dev->dev, bus_address))
+ return -ENOMEM;
+
+ put_unaligned_le64((u64)bus_address, &sg_descriptor->address);
+@@ -370,15 +370,15 @@ static int pqi_map_single(struct pci_dev *pci_dev,
+
+ static void pqi_pci_unmap(struct pci_dev *pci_dev,
+ struct pqi_sg_descriptor *descriptors, int num_descriptors,
+- int data_direction)
++ enum dma_data_direction data_direction)
+ {
+ int i;
+
+- if (data_direction == PCI_DMA_NONE)
++ if (data_direction == DMA_NONE)
+ return;
+
+ for (i = 0; i < num_descriptors; i++)
+- pci_unmap_single(pci_dev,
++ dma_unmap_single(&pci_dev->dev,
+ (dma_addr_t)get_unaligned_le64(&descriptors[i].address),
+ get_unaligned_le32(&descriptors[i].length),
+ data_direction);
+@@ -387,10 +387,9 @@ static void pqi_pci_unmap(struct pci_dev *pci_dev,
+ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_raid_path_request *request, u8 cmd,
+ u8 *scsi3addr, void *buffer, size_t buffer_length,
+- u16 vpd_page, int *pci_direction)
++ u16 vpd_page, enum dma_data_direction *dir)
+ {
+ u8 *cdb;
+- int pci_dir;
+
+ memset(request, 0, sizeof(*request));
+
+@@ -458,23 +457,21 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+
+ switch (request->data_direction) {
+ case SOP_READ_FLAG:
+- pci_dir = PCI_DMA_FROMDEVICE;
++ *dir = DMA_FROM_DEVICE;
+ break;
+ case SOP_WRITE_FLAG:
+- pci_dir = PCI_DMA_TODEVICE;
++ *dir = DMA_TO_DEVICE;
+ break;
+ case SOP_NO_DIRECTION_FLAG:
+- pci_dir = PCI_DMA_NONE;
++ *dir = DMA_NONE;
+ break;
+ default:
+- pci_dir = PCI_DMA_BIDIRECTIONAL;
++ *dir = DMA_BIDIRECTIONAL;
+ break;
+ }
+
+- *pci_direction = pci_dir;
+-
+ return pqi_map_single(ctrl_info->pci_dev, &request->sg_descriptors[0],
+- buffer, buffer_length, pci_dir);
++ buffer, buffer_length, *dir);
+ }
+
+ static inline void pqi_reinit_io_request(struct pqi_io_request *io_request)
+@@ -516,21 +513,19 @@ static int pqi_identify_controller(struct pqi_ctrl_info *ctrl_info,
+ struct bmic_identify_controller *buffer)
+ {
+ int rc;
+- int pci_direction;
++ enum dma_data_direction dir;
+ struct pqi_raid_path_request request;
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+ BMIC_IDENTIFY_CONTROLLER, RAID_CTLR_LUNID, buffer,
+- sizeof(*buffer), 0, &pci_direction);
++ sizeof(*buffer), 0, &dir);
+ if (rc)
+ return rc;
+
+ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+ NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
+-
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+ return rc;
+ }
+
+@@ -538,21 +533,19 @@ static int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info,
+ u8 *scsi3addr, u16 vpd_page, void *buffer, size_t buffer_length)
+ {
+ int rc;
+- int pci_direction;
++ enum dma_data_direction dir;
+ struct pqi_raid_path_request request;
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+ INQUIRY, scsi3addr, buffer, buffer_length, vpd_page,
+- &pci_direction);
++ &dir);
+ if (rc)
+ return rc;
+
+ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+ NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
+-
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+ return rc;
+ }
+
+@@ -562,13 +555,13 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info,
+ size_t buffer_length)
+ {
+ int rc;
+- int pci_direction;
++ enum dma_data_direction dir;
+ u16 bmic_device_index;
+ struct pqi_raid_path_request request;
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+ BMIC_IDENTIFY_PHYSICAL_DEVICE, RAID_CTLR_LUNID, buffer,
+- buffer_length, 0, &pci_direction);
++ buffer_length, 0, &dir);
+ if (rc)
+ return rc;
+
+@@ -579,9 +572,7 @@ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info,
+ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
+ 0, NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
+-
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+ return rc;
+ }
+
+@@ -590,8 +581,8 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
+ {
+ int rc;
+ struct pqi_raid_path_request request;
+- int pci_direction;
+ struct bmic_flush_cache *flush_cache;
++ enum dma_data_direction dir;
+
+ /*
+ * Don't bother trying to flush the cache if the controller is
+@@ -608,16 +599,14 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+ SA_FLUSH_CACHE, RAID_CTLR_LUNID, flush_cache,
+- sizeof(*flush_cache), 0, &pci_direction);
++ sizeof(*flush_cache), 0, &dir);
+ if (rc)
+ goto out;
+
+ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
+ 0, NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
+-
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+ out:
+ kfree(flush_cache);
+
+@@ -629,20 +618,18 @@ static int pqi_write_host_wellness(struct pqi_ctrl_info *ctrl_info,
+ {
+ int rc;
+ struct pqi_raid_path_request request;
+- int pci_direction;
++ enum dma_data_direction dir;
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+ BMIC_WRITE_HOST_WELLNESS, RAID_CTLR_LUNID, buffer,
+- buffer_length, 0, &pci_direction);
++ buffer_length, 0, &dir);
+ if (rc)
+ return rc;
+
+ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
+ 0, NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
+-
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+ return rc;
+ }
+
+@@ -793,20 +780,18 @@ static int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd,
+ void *buffer, size_t buffer_length)
+ {
+ int rc;
+- int pci_direction;
++ enum dma_data_direction dir;
+ struct pqi_raid_path_request request;
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+- cmd, RAID_CTLR_LUNID, buffer, buffer_length, 0, &pci_direction);
++ cmd, RAID_CTLR_LUNID, buffer, buffer_length, 0, &dir);
+ if (rc)
+ return rc;
+
+ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+ NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
+-
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+ return rc;
+ }
+
+@@ -1089,7 +1074,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device)
+ {
+ int rc;
+- int pci_direction;
++ enum dma_data_direction dir;
+ struct pqi_raid_path_request request;
+ struct raid_map *raid_map;
+
+@@ -1099,15 +1084,14 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info,
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+ CISS_GET_RAID_MAP, device->scsi3addr, raid_map,
+- sizeof(*raid_map), 0, &pci_direction);
++ sizeof(*raid_map), 0, &dir);
+ if (rc)
+ goto error;
+
+ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+ NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+
+ if (rc)
+ goto error;
+@@ -3822,7 +3806,7 @@ static int pqi_report_device_capability(struct pqi_ctrl_info *ctrl_info)
+ rc = pqi_map_single(ctrl_info->pci_dev,
+ &request.data.report_device_capability.sg_descriptor,
+ capability, sizeof(*capability),
+- PCI_DMA_FROMDEVICE);
++ DMA_FROM_DEVICE);
+ if (rc)
+ goto out;
+
+@@ -3831,7 +3815,7 @@ static int pqi_report_device_capability(struct pqi_ctrl_info *ctrl_info)
+
+ pqi_pci_unmap(ctrl_info->pci_dev,
+ &request.data.report_device_capability.sg_descriptor, 1,
+- PCI_DMA_FROMDEVICE);
++ DMA_FROM_DEVICE);
+
+ if (rc)
+ goto out;
+@@ -4158,7 +4142,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info,
+ rc = pqi_map_single(ctrl_info->pci_dev,
+ request.data.report_event_configuration.sg_descriptors,
+ event_config, PQI_REPORT_EVENT_CONFIG_BUFFER_LENGTH,
+- PCI_DMA_FROMDEVICE);
++ DMA_FROM_DEVICE);
+ if (rc)
+ goto out;
+
+@@ -4167,7 +4151,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info,
+
+ pqi_pci_unmap(ctrl_info->pci_dev,
+ request.data.report_event_configuration.sg_descriptors, 1,
+- PCI_DMA_FROMDEVICE);
++ DMA_FROM_DEVICE);
+
+ if (rc)
+ goto out;
+@@ -4194,7 +4178,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info,
+ rc = pqi_map_single(ctrl_info->pci_dev,
+ request.data.report_event_configuration.sg_descriptors,
+ event_config, PQI_REPORT_EVENT_CONFIG_BUFFER_LENGTH,
+- PCI_DMA_TODEVICE);
++ DMA_TO_DEVICE);
+ if (rc)
+ goto out;
+
+@@ -4203,7 +4187,7 @@ static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info,
+
+ pqi_pci_unmap(ctrl_info->pci_dev,
+ request.data.report_event_configuration.sg_descriptors, 1,
+- PCI_DMA_TODEVICE);
++ DMA_TO_DEVICE);
+
+ out:
+ kfree(event_config);
+@@ -5534,7 +5518,7 @@ static int pqi_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg)
+
+ rc = pqi_map_single(ctrl_info->pci_dev,
+ &request.sg_descriptors[0], kernel_buffer,
+- iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
++ iocommand.buf_size, DMA_BIDIRECTIONAL);
+ if (rc)
+ goto out;
+
+@@ -5548,7 +5532,7 @@ static int pqi_passthru_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg)
+
+ if (iocommand.buf_size > 0)
+ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- PCI_DMA_BIDIRECTIONAL);
++ DMA_BIDIRECTIONAL);
+
+ memset(&iocommand.error_info, 0, sizeof(iocommand.error_info));
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
+index 5141bd4c9f06..ea91658c7060 100644
+--- a/drivers/scsi/smartpqi/smartpqi_sis.c
++++ b/drivers/scsi/smartpqi/smartpqi_sis.c
+@@ -316,9 +316,9 @@ int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
+ put_unaligned_le32(ctrl_info->max_io_slots,
+ &base_struct->error_buffer_num_elements);
+
+- bus_address = pci_map_single(ctrl_info->pci_dev, base_struct,
+- sizeof(*base_struct), PCI_DMA_TODEVICE);
+- if (pci_dma_mapping_error(ctrl_info->pci_dev, bus_address)) {
++ bus_address = dma_map_single(&ctrl_info->pci_dev->dev, base_struct,
++ sizeof(*base_struct), DMA_TO_DEVICE);
++ if (dma_mapping_error(&ctrl_info->pci_dev->dev, bus_address)) {
+ rc = -ENOMEM;
+ goto out;
+ }
+@@ -331,9 +331,8 @@ int sis_init_base_struct_addr(struct pqi_ctrl_info *ctrl_info)
+ rc = sis_send_sync_cmd(ctrl_info, SIS_CMD_INIT_BASE_STRUCT_ADDRESS,
+ &params);
+
+- pci_unmap_single(ctrl_info->pci_dev, bus_address, sizeof(*base_struct),
+- PCI_DMA_TODEVICE);
+-
++ dma_unmap_single(&ctrl_info->pci_dev->dev, bus_address,
++ sizeof(*base_struct), DMA_TO_DEVICE);
+ out:
+ kfree(base_struct_unaligned);
+
+
diff --git a/patches.drivers/scsi-smartpqi-increase-fw-status-register-read-timeout b/patches.drivers/scsi-smartpqi-increase-fw-status-register-read-timeout
new file mode 100644
index 0000000000..d3af59ae06
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-increase-fw-status-register-read-timeout
@@ -0,0 +1,44 @@
+From: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Date: Tue, 18 Dec 2018 17:39:01 -0600
+Subject: scsi: smartpqi: increase fw status register read timeout
+Git-commit: 65111785acccb836ec75263b03b0e33f21e74f47
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Problem:
+ - during the driver initialization, driver will poll fw
+ for KERNEL_UP in a 30 seconds timeout.
+
+ - if the firmware is not ready after 30 seconds,
+ driver will not be loaded.
+
+Fix:
+ - change timeout from 30 seconds to 3 minutes.
+
+Reported-by: Feng Li <lifeng1519@gmail.com>
+Reviewed-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Reviewed-by: Murthy Bhat <Murthy.Bhat@microsemi.com>
+Reviewed-by: Dave Carroll <david.carroll@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_sis.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
+index ea91658c7060..9d3043df22af 100644
+--- a/drivers/scsi/smartpqi/smartpqi_sis.c
++++ b/drivers/scsi/smartpqi/smartpqi_sis.c
+@@ -59,7 +59,7 @@
+
+ #define SIS_CTRL_KERNEL_UP 0x80
+ #define SIS_CTRL_KERNEL_PANIC 0x100
+-#define SIS_CTRL_READY_TIMEOUT_SECS 30
++#define SIS_CTRL_READY_TIMEOUT_SECS 180
+ #define SIS_CTRL_READY_RESUME_TIMEOUT_SECS 90
+ #define SIS_CTRL_READY_POLL_INTERVAL_MSECS 10
+
+
diff --git a/patches.drivers/scsi-smartpqi-increase-lun-reset-timeout b/patches.drivers/scsi-smartpqi-increase-lun-reset-timeout
new file mode 100644
index 0000000000..20086c4a41
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-increase-lun-reset-timeout
@@ -0,0 +1,68 @@
+From: Kevin Barnett <kevin.barnett@microsemi.com>
+Date: Thu, 14 Mar 2019 16:57:49 -0500
+Subject: scsi: smartpqi: increase LUN reset timeout
+Git-commit: 429fab70591e19fed7d490b6889470d71ea46236
+Patch-mainline: v5.2-rc1
+References: bsc#1133547
+
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: David Carroll <david.carroll@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 75ec43aa8df3..b7a815450b78 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5660,9 +5660,11 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info,
+ return rc;
+ }
+
++/* Performs a reset at the LUN level. */
++
+ #define PQI_LUN_RESET_RETRIES 3
+ #define PQI_LUN_RESET_RETRY_INTERVAL_MSECS 10000
+-/* Performs a reset at the LUN level. */
++#define PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS 120
+
+ static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
+ struct pqi_scsi_dev *device)
+@@ -5673,12 +5675,12 @@ static int _pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
+
+ for (retries = 0;;) {
+ rc = pqi_lun_reset(ctrl_info, device);
+- if (rc != -EAGAIN ||
+- ++retries > PQI_LUN_RESET_RETRIES)
++ if (rc != -EAGAIN || ++retries > PQI_LUN_RESET_RETRIES)
+ break;
+ msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS);
+ }
+- timeout_secs = rc ? PQI_LUN_RESET_TIMEOUT_SECS : NO_TIMEOUT;
++
++ timeout_secs = rc ? PQI_LUN_RESET_PENDING_IO_TIMEOUT_SECS : NO_TIMEOUT;
+
+ rc |= pqi_device_wait_for_pending_io(ctrl_info, device, timeout_secs);
+
+@@ -5707,6 +5709,7 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
+ pqi_device_reset_done(device);
+
+ mutex_unlock(&ctrl_info->lun_reset_mutex);
++
+ return rc;
+ }
+
+@@ -5737,6 +5740,7 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
+ pqi_wait_until_ofa_finished(ctrl_info);
+
+ rc = pqi_device_reset(ctrl_info, device);
++
+ out:
+ dev_err(&ctrl_info->pci_dev->dev,
+ "reset of scsi %d:%d:%d:%d: %s\n",
+
diff --git a/patches.drivers/scsi-smartpqi-refactor-sending-controller-raid-requests b/patches.drivers/scsi-smartpqi-refactor-sending-controller-raid-requests
new file mode 100644
index 0000000000..91af654147
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-refactor-sending-controller-raid-requests
@@ -0,0 +1,237 @@
+From: Dave Carroll <david.carroll@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:41 -0600
+Subject: scsi: smartpqi: refactor sending controller raid requests
+Git-commit: 02133b68d51d09bd91b0d2c1fa5318e2f23e4559
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+Clean up the common code which creates a raid path request for the
+controller LUNID and sends it synchronously, into a common routine;
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 134 ++++++++++++----------------------
+ 1 file changed, 46 insertions(+), 88 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 07206d572022..2a90d515b972 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -519,44 +519,58 @@ static void pqi_free_io_request(struct pqi_io_request *io_request)
+ atomic_dec(&io_request->refcount);
+ }
+
+-static int pqi_identify_controller(struct pqi_ctrl_info *ctrl_info,
+- struct bmic_identify_controller *buffer)
++static int pqi_send_scsi_raid_request(struct pqi_ctrl_info *ctrl_info, u8 cmd,
++ u8 *scsi3addr, void *buffer, size_t buffer_length, u16 vpd_page,
++ struct pqi_raid_error_info *error_info,
++ unsigned long timeout_msecs)
+ {
+ int rc;
+ enum dma_data_direction dir;
+ struct pqi_raid_path_request request;
+
+ rc = pqi_build_raid_path_request(ctrl_info, &request,
+- BMIC_IDENTIFY_CONTROLLER, RAID_CTLR_LUNID, buffer,
+- sizeof(*buffer), 0, &dir);
++ cmd, scsi3addr, buffer,
++ buffer_length, vpd_page, &dir);
+ if (rc)
+ return rc;
+
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+- NULL, NO_TIMEOUT);
++ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
++ 0, error_info, timeout_msecs);
+
+ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+ return rc;
+ }
+
+-static int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info,
+- u8 *scsi3addr, u16 vpd_page, void *buffer, size_t buffer_length)
++/* Helper functions for pqi_send_scsi_raid_request */
++
++static inline int pqi_send_ctrl_raid_request(struct pqi_ctrl_info *ctrl_info,
++ u8 cmd, void *buffer, size_t buffer_length)
+ {
+- int rc;
+- enum dma_data_direction dir;
+- struct pqi_raid_path_request request;
++ return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID,
++ buffer, buffer_length, 0, NULL, NO_TIMEOUT);
++}
+
+- rc = pqi_build_raid_path_request(ctrl_info, &request,
+- INQUIRY, scsi3addr, buffer, buffer_length, vpd_page,
+- &dir);
+- if (rc)
+- return rc;
++static inline int pqi_send_ctrl_raid_with_error(struct pqi_ctrl_info *ctrl_info,
++ u8 cmd, void *buffer, size_t buffer_length,
++ struct pqi_raid_error_info *error_info)
++{
++ return pqi_send_scsi_raid_request(ctrl_info, cmd, RAID_CTLR_LUNID,
++ buffer, buffer_length, 0, error_info, NO_TIMEOUT);
++}
+
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+- NULL, NO_TIMEOUT);
+
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+- return rc;
++static inline int pqi_identify_controller(struct pqi_ctrl_info *ctrl_info,
++ struct bmic_identify_controller *buffer)
++{
++ return pqi_send_ctrl_raid_request(ctrl_info, BMIC_IDENTIFY_CONTROLLER,
++ buffer, sizeof(*buffer));
++}
++
++static inline int pqi_scsi_inquiry(struct pqi_ctrl_info *ctrl_info,
++ u8 *scsi3addr, u16 vpd_page, void *buffer, size_t buffer_length)
++{
++ return pqi_send_scsi_raid_request(ctrl_info, INQUIRY, scsi3addr,
++ buffer, buffer_length, vpd_page, NULL, NO_TIMEOUT);
+ }
+
+ static int pqi_identify_physical_device(struct pqi_ctrl_info *ctrl_info,
+@@ -590,9 +604,7 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
+ enum bmic_flush_cache_shutdown_event shutdown_event)
+ {
+ int rc;
+- struct pqi_raid_path_request request;
+ struct bmic_flush_cache *flush_cache;
+- enum dma_data_direction dir;
+
+ /*
+ * Don't bother trying to flush the cache if the controller is
+@@ -607,17 +619,9 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
+
+ flush_cache->shutdown_event = shutdown_event;
+
+- rc = pqi_build_raid_path_request(ctrl_info, &request,
+- SA_FLUSH_CACHE, RAID_CTLR_LUNID, flush_cache,
+- sizeof(*flush_cache), 0, &dir);
+- if (rc)
+- goto out;
++ rc = pqi_send_ctrl_raid_request(ctrl_info, SA_FLUSH_CACHE, flush_cache,
++ sizeof(*flush_cache));
+
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
+- 0, NULL, NO_TIMEOUT);
+-
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+-out:
+ kfree(flush_cache);
+
+ return rc;
+@@ -629,66 +633,32 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
+ static int pqi_set_diag_rescan(struct pqi_ctrl_info *ctrl_info)
+ {
+ int rc;
+- struct pqi_raid_path_request request;
+ struct bmic_diag_options *diag;
+- enum dma_data_direction pci_direction;
+
+ diag = kzalloc(sizeof(*diag), GFP_KERNEL);
+ if (!diag)
+ return -ENOMEM;
+
+- rc = pqi_build_raid_path_request(ctrl_info, &request,
+- BMIC_SENSE_DIAG_OPTIONS, RAID_CTLR_LUNID, diag,
+- sizeof(*diag), 0, &pci_direction);
+- if (rc)
+- goto out;
+-
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
+- 0, NULL, NO_TIMEOUT);
+-
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
+-
++ rc = pqi_send_ctrl_raid_request(ctrl_info, BMIC_SENSE_DIAG_OPTIONS,
++ diag, sizeof(*diag));
+ if (rc)
+ goto out;
+
+ diag->options |= cpu_to_le32(PQI_FETCH_PTRAID_DATA);
+
+- rc = pqi_build_raid_path_request(ctrl_info, &request,
+- BMIC_SET_DIAG_OPTIONS, RAID_CTLR_LUNID, diag,
+- sizeof(*diag), 0, &pci_direction);
+- if (rc)
+- goto out;
+-
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
+- 0, NULL, NO_TIMEOUT);
+-
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
+- pci_direction);
++ rc = pqi_send_ctrl_raid_request(ctrl_info, BMIC_SET_DIAG_OPTIONS,
++ diag, sizeof(*diag));
+ out:
+ kfree(diag);
+
+ return rc;
+ }
+
+-static int pqi_write_host_wellness(struct pqi_ctrl_info *ctrl_info,
++static inline int pqi_write_host_wellness(struct pqi_ctrl_info *ctrl_info,
+ void *buffer, size_t buffer_length)
+ {
+- int rc;
+- struct pqi_raid_path_request request;
+- enum dma_data_direction dir;
+-
+- rc = pqi_build_raid_path_request(ctrl_info, &request,
+- BMIC_WRITE_HOST_WELLNESS, RAID_CTLR_LUNID, buffer,
+- buffer_length, 0, &dir);
+- if (rc)
+- return rc;
+-
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
+- 0, NULL, NO_TIMEOUT);
+-
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+- return rc;
++ return pqi_send_ctrl_raid_request(ctrl_info, BMIC_WRITE_HOST_WELLNESS,
++ buffer, buffer_length);
+ }
+
+ #pragma pack(1)
+@@ -837,23 +807,11 @@ static inline void pqi_cancel_update_time_worker(
+ cancel_delayed_work_sync(&ctrl_info->update_time_work);
+ }
+
+-static int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd,
++static inline int pqi_report_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd,
+ void *buffer, size_t buffer_length)
+ {
+- int rc;
+- enum dma_data_direction dir;
+- struct pqi_raid_path_request request;
+-
+- rc = pqi_build_raid_path_request(ctrl_info, &request,
+- cmd, RAID_CTLR_LUNID, buffer, buffer_length, 0, &dir);
+- if (rc)
+- return rc;
+-
+- rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header, 0,
+- NULL, NO_TIMEOUT);
+-
+- pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1, dir);
+- return rc;
++ return pqi_send_ctrl_raid_request(ctrl_info, cmd, buffer,
++ buffer_length);
+ }
+
+ static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd,
+
diff --git a/patches.drivers/scsi-smartpqi-reporting-logical-unit-failure b/patches.drivers/scsi-smartpqi-reporting-logical-unit-failure
new file mode 100644
index 0000000000..afb356cfbf
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-reporting-logical-unit-failure
@@ -0,0 +1,42 @@
+From: Erwan Velu <e.velu@criteo.com>
+Date: Fri, 1 Mar 2019 17:08:06 +0100
+Subject: scsi: smartpqi: Reporting 'logical unit failure'
+Git-commit: 441b7195e2812f2d7a9dafe02f052f642957bd8f
+Patch-mainline: v5.1-rc1
+References: bsc#1133547
+
+When the HARDWARE_ERROR/0x3e/0x1 case is triggered, the logical volume
+is offlined. When reading the kernel log, the reason why the device
+got offlined isn't reported to the user. This situation makes it
+difficult for admins to root cause.
+
+Log a message when this condition occurs.
+
+[mkp: tweaked commit message]
+
+Signed-off-by: Erwan Velu <e.velu@criteo.com>
+Acked-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index f6eaea2eadd1..c7b023683575 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -2764,6 +2764,12 @@ static void pqi_process_raid_io_error(struct pqi_io_request *io_request)
+ sshdr.sense_key == HARDWARE_ERROR &&
+ sshdr.asc == 0x3e &&
+ sshdr.ascq == 0x1) {
++ struct pqi_ctrl_info *ctrl_info = shost_to_hba(scmd->device->host);
++ struct pqi_scsi_dev *device = scmd->device->hostdata;
++
++ if (printk_ratelimit())
++ scmd_printk(KERN_ERR, scmd, "received 'logical unit failure' from controller for scsi %d:%d:%d:%d\n",
++ ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun);
+ pqi_take_device_offline(scmd->device, "RAID");
+ host_byte = DID_NO_CONNECT;
+ }
+
diff --git a/patches.drivers/scsi-smartpqi-turn-off-lun-data-caching-for-ptraid b/patches.drivers/scsi-smartpqi-turn-off-lun-data-caching-for-ptraid
new file mode 100644
index 0000000000..92dfc44ecb
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-turn-off-lun-data-caching-for-ptraid
@@ -0,0 +1,195 @@
+From: Dave Carroll <david.carroll@microsemi.com>
+Date: Fri, 7 Dec 2018 16:28:35 -0600
+Subject: scsi: smartpqi: turn off lun data caching for ptraid
+Git-commit: 171c28653a2d9201e130863eb2408f404e4d6ed7
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- allow update the luns for PTRAID devices.
+
+Reviewed-by: Ajish Koshy <ajish.koshy@microsemi.com>
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Justin Lindley <justin.lindley@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 6 +++
+ drivers/scsi/smartpqi/smartpqi_init.c | 79 ++++++++++++++++++++++++++++++++---
+ 2 files changed, 79 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index 646982e45904..fcc4b937de71 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -1126,6 +1126,8 @@ enum pqi_ctrl_mode {
+ #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
+ #define BMIC_WRITE_HOST_WELLNESS 0xa5
+ #define BMIC_FLUSH_CACHE 0xc2
++#define BMIC_SET_DIAG_OPTIONS 0xf4
++#define BMIC_SENSE_DIAG_OPTIONS 0xf5
+
+ #define SA_FLUSH_CACHE 0x1
+
+@@ -1250,6 +1252,10 @@ enum bmic_flush_cache_shutdown_event {
+ RESTART = 4
+ };
+
++struct bmic_diag_options {
++ __le32 options;
++};
++
+ #pragma pack()
+
+ int pqi_add_sas_host(struct Scsi_Host *shost, struct pqi_ctrl_info *ctrl_info);
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 033e8a028812..07206d572022 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -395,6 +395,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+ u16 vpd_page, enum dma_data_direction *dir)
+ {
+ u8 *cdb;
++ size_t cdb_length = buffer_length;
+
+ memset(request, 0, sizeof(*request));
+
+@@ -417,7 +418,7 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+ cdb[1] = 0x1;
+ cdb[2] = (u8)vpd_page;
+ }
+- cdb[4] = (u8)buffer_length;
++ cdb[4] = (u8)cdb_length;
+ break;
+ case CISS_REPORT_LOG:
+ case CISS_REPORT_PHYS:
+@@ -427,32 +428,36 @@ static int pqi_build_raid_path_request(struct pqi_ctrl_info *ctrl_info,
+ cdb[1] = CISS_REPORT_PHYS_EXTENDED;
+ else
+ cdb[1] = CISS_REPORT_LOG_EXTENDED;
+- put_unaligned_be32(buffer_length, &cdb[6]);
++ put_unaligned_be32(cdb_length, &cdb[6]);
+ break;
+ case CISS_GET_RAID_MAP:
+ request->data_direction = SOP_READ_FLAG;
+ cdb[0] = CISS_READ;
+ cdb[1] = CISS_GET_RAID_MAP;
+- put_unaligned_be32(buffer_length, &cdb[6]);
++ put_unaligned_be32(cdb_length, &cdb[6]);
+ break;
+ case SA_FLUSH_CACHE:
+ request->data_direction = SOP_WRITE_FLAG;
+ cdb[0] = BMIC_WRITE;
+ cdb[6] = BMIC_FLUSH_CACHE;
+- put_unaligned_be16(buffer_length, &cdb[7]);
++ put_unaligned_be16(cdb_length, &cdb[7]);
+ break;
++ case BMIC_SENSE_DIAG_OPTIONS:
++ cdb_length = 0;
+ case BMIC_IDENTIFY_CONTROLLER:
+ case BMIC_IDENTIFY_PHYSICAL_DEVICE:
+ request->data_direction = SOP_READ_FLAG;
+ cdb[0] = BMIC_READ;
+ cdb[6] = cmd;
+- put_unaligned_be16(buffer_length, &cdb[7]);
++ put_unaligned_be16(cdb_length, &cdb[7]);
+ break;
++ case BMIC_SET_DIAG_OPTIONS:
++ cdb_length = 0;
+ case BMIC_WRITE_HOST_WELLNESS:
+ request->data_direction = SOP_WRITE_FLAG;
+ cdb[0] = BMIC_WRITE;
+ cdb[6] = cmd;
+- put_unaligned_be16(buffer_length, &cdb[7]);
++ put_unaligned_be16(cdb_length, &cdb[7]);
+ break;
+ default:
+ dev_err(&ctrl_info->pci_dev->dev, "unknown command 0x%c\n",
+@@ -618,6 +623,54 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info,
+ return rc;
+ }
+
++
++#define PQI_FETCH_PTRAID_DATA (1UL<<31)
++
++static int pqi_set_diag_rescan(struct pqi_ctrl_info *ctrl_info)
++{
++ int rc;
++ struct pqi_raid_path_request request;
++ struct bmic_diag_options *diag;
++ enum dma_data_direction pci_direction;
++
++ diag = kzalloc(sizeof(*diag), GFP_KERNEL);
++ if (!diag)
++ return -ENOMEM;
++
++ rc = pqi_build_raid_path_request(ctrl_info, &request,
++ BMIC_SENSE_DIAG_OPTIONS, RAID_CTLR_LUNID, diag,
++ sizeof(*diag), 0, &pci_direction);
++ if (rc)
++ goto out;
++
++ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
++ 0, NULL, NO_TIMEOUT);
++
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
++ pci_direction);
++
++ if (rc)
++ goto out;
++
++ diag->options |= cpu_to_le32(PQI_FETCH_PTRAID_DATA);
++
++ rc = pqi_build_raid_path_request(ctrl_info, &request,
++ BMIC_SET_DIAG_OPTIONS, RAID_CTLR_LUNID, diag,
++ sizeof(*diag), 0, &pci_direction);
++ if (rc)
++ goto out;
++
++ rc = pqi_submit_raid_request_synchronous(ctrl_info, &request.header,
++ 0, NULL, NO_TIMEOUT);
++
++ pqi_pci_unmap(ctrl_info->pci_dev, request.sg_descriptors, 1,
++ pci_direction);
++out:
++ kfree(diag);
++
++ return rc;
++}
++
+ static int pqi_write_host_wellness(struct pqi_ctrl_info *ctrl_info,
+ void *buffer, size_t buffer_length)
+ {
+@@ -6476,6 +6529,13 @@ static int pqi_ctrl_init(struct pqi_ctrl_info *ctrl_info)
+ return rc;
+ }
+
++ rc = pqi_set_diag_rescan(ctrl_info);
++ if (rc) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "error enabling multi-lun rescan\n");
++ return rc;
++ }
++
+ rc = pqi_write_driver_version_to_host_wellness(ctrl_info);
+ if (rc) {
+ dev_err(&ctrl_info->pci_dev->dev,
+@@ -6582,6 +6642,13 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info)
+ return rc;
+ }
+
++ rc = pqi_set_diag_rescan(ctrl_info);
++ if (rc) {
++ dev_err(&ctrl_info->pci_dev->dev,
++ "error enabling multi-lun rescan\n");
++ return rc;
++ }
++
+ rc = pqi_write_driver_version_to_host_wellness(ctrl_info);
+ if (rc) {
+ dev_err(&ctrl_info->pci_dev->dev,
+
diff --git a/patches.drivers/scsi-smartpqi-update-copyright b/patches.drivers/scsi-smartpqi-update-copyright
new file mode 100644
index 0000000000..8a5ad44edc
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-update-copyright
@@ -0,0 +1,134 @@
+From: Don Brace <don.brace@microsemi.com>
+Date: Thu, 14 Mar 2019 16:58:02 -0500
+Subject: scsi: smartpqi: update copyright
+Git-commit: 2f4c4b92dbd8b8890f78cc8748850449a3592bc5
+Patch-mainline: v5.2-rc1
+References: bsc#1133547
+
+Reviewed-by: Gerry Morong <gerry.morong@microsemi.com>
+Reviewed-by: Scott Benesh <scott.benesh@microsemi.com>
+Reviewed-by: Scott Teel <scott.teel@microsemi.com>
+Reviewed-by: David Carroll <david.carroll@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi.h | 5 +++--
+ drivers/scsi/smartpqi/smartpqi_init.c | 5 +++--
+ drivers/scsi/smartpqi/smartpqi_sas_transport.c | 5 +++--
+ drivers/scsi/smartpqi/smartpqi_sis.c | 5 +++--
+ drivers/scsi/smartpqi/smartpqi_sis.h | 5 +++--
+ 5 files changed, 15 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
+index af962368818b..3ceaba9b24d9 100644
+--- a/drivers/scsi/smartpqi/smartpqi.h
++++ b/drivers/scsi/smartpqi/smartpqi.h
+@@ -1,6 +1,7 @@
+ /*
+ * driver for Microsemi PQI-based storage controllers
+- * Copyright (c) 2016-2017 Microsemi Corporation
++ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
++ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -12,7 +13,7 @@
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more details.
+ *
+- * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
++ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 6f6b26bfd88b..1cd151c40671 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -1,6 +1,7 @@
+ /*
+ * driver for Microsemi PQI-based storage controllers
+- * Copyright (c) 2016-2017 Microsemi Corporation
++ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
++ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -12,7 +13,7 @@
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more details.
+ *
+- * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
++ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+index 0e4ef215115f..4c4c6b1cd1e6 100644
+--- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c
++++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c
+@@ -1,6 +1,7 @@
+ /*
+ * driver for Microsemi PQI-based storage controllers
+- * Copyright (c) 2016-2017 Microsemi Corporation
++ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
++ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -12,7 +13,7 @@
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more details.
+ *
+- * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
++ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_sis.c b/drivers/scsi/smartpqi/smartpqi_sis.c
+index dcd11c6418cc..fa365d02f88d 100644
+--- a/drivers/scsi/smartpqi/smartpqi_sis.c
++++ b/drivers/scsi/smartpqi/smartpqi_sis.c
+@@ -1,6 +1,7 @@
+ /*
+ * driver for Microsemi PQI-based storage controllers
+- * Copyright (c) 2016-2017 Microsemi Corporation
++ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
++ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -12,7 +13,7 @@
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more details.
+ *
+- * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
++ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_sis.h b/drivers/scsi/smartpqi/smartpqi_sis.h
+index d018cb9c3f82..eea3dd9d4ac9 100644
+--- a/drivers/scsi/smartpqi/smartpqi_sis.h
++++ b/drivers/scsi/smartpqi/smartpqi_sis.h
+@@ -1,6 +1,7 @@
+ /*
+ * driver for Microsemi PQI-based storage controllers
+- * Copyright (c) 2016-2017 Microsemi Corporation
++ * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
++ * Copyright (c) 2016-2018 Microsemi Corporation
+ * Copyright (c) 2016 PMC-Sierra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+@@ -12,7 +13,7 @@
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for more details.
+ *
+- * Questions/Comments/Bugfixes to esc.storagedev@microsemi.com
++ * Questions/Comments/Bugfixes to storagedev@microchip.com
+ *
+ */
+
+
diff --git a/patches.drivers/scsi-smartpqi-update-driver-version b/patches.drivers/scsi-smartpqi-update-driver-version
new file mode 100644
index 0000000000..e88c088f98
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-update-driver-version
@@ -0,0 +1,38 @@
+From: Don Brace <don.brace@microsemi.com>
+Date: Tue, 18 Dec 2018 17:39:13 -0600
+Subject: scsi: smartpqi: update driver version
+Git-commit: 1923f851eb0baa79d11cd0574c6100c2de840d75
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- need to bump up the driver version because
+ of the OFA patch and the fw status register
+ read timeout patch.
+
+Reviewed-by: Gerry Morong <gerry.morong@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index c2d09eb8a528..bfd2dd3496da 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -40,11 +40,11 @@
+ #define BUILD_TIMESTAMP
+ #endif
+
+-#define DRIVER_VERSION "1.2.4-065"
++#define DRIVER_VERSION "1.2.4-070"
+ #define DRIVER_MAJOR 1
+ #define DRIVER_MINOR 2
+ #define DRIVER_RELEASE 4
+-#define DRIVER_REVISION 65
++#define DRIVER_REVISION 70
+
+ #define DRIVER_NAME "Microsemi PQI Driver (v" \
+ DRIVER_VERSION BUILD_TIMESTAMP ")"
+
diff --git a/patches.drivers/scsi-smartpqi-wake-up-drives-after-os-resumes-from-suspend b/patches.drivers/scsi-smartpqi-wake-up-drives-after-os-resumes-from-suspend
new file mode 100644
index 0000000000..c5747e76b1
--- /dev/null
+++ b/patches.drivers/scsi-smartpqi-wake-up-drives-after-os-resumes-from-suspend
@@ -0,0 +1,37 @@
+From: Dave Carroll <david.carroll@microsemi.com>
+Date: Fri, 7 Dec 2018 16:29:05 -0600
+Subject: scsi: smartpqi: wake up drives after os resumes from suspend
+Git-commit: 2b447f811c1f7f30e4caa5a817d0c95d06aff874
+Patch-mainline: v5.0-rc1
+References: bsc#1133547
+
+- set allow_restart option during scsi_device init.
+
+ This allows the kernel to send a START/STOP Unit command to the drive if
+ it encounters a 4/2 check condition in sense data.
+
+Reviewed-by: Murthy Bhat <murthy.bhat@microsemi.com>
+Reviewed-by: Mahesh Rajashekhara <mahesh.rajashekhara@microsemi.com>
+Reviewed-by: Kevin Barnett <kevin.barnett@microsemi.com>
+Signed-off-by: Dave Carroll <david.carroll@microsemi.com>
+Signed-off-by: Don Brace <don.brace@microsemi.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Acked-by: Lee Duncan <lduncan@suse.com>
+---
+ drivers/scsi/smartpqi/smartpqi_init.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
+index 74bd8d90c615..273daa2c2b68 100644
+--- a/drivers/scsi/smartpqi/smartpqi_init.c
++++ b/drivers/scsi/smartpqi/smartpqi_init.c
+@@ -5434,6 +5434,8 @@ static int pqi_slave_alloc(struct scsi_device *sdev)
+ }
+ if (pqi_is_logical_device(device))
+ pqi_disable_write_same(sdev);
++ else
++ sdev->allow_restart = 1;
+ }
+
+ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags);
+
diff --git a/patches.drivers/serial-fix-race-between-flush_to_ldisc-and-tty_open.patch b/patches.drivers/serial-fix-race-between-flush_to_ldisc-and-tty_open.patch
index 8730ce5efd..d8580a7a50 100644
--- a/patches.drivers/serial-fix-race-between-flush_to_ldisc-and-tty_open.patch
+++ b/patches.drivers/serial-fix-race-between-flush_to_ldisc-and-tty_open.patch
@@ -73,9 +73,9 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
port = uart_port_lock(state, flags);
__uart_start(tty);
uart_port_unlock(port, flags);
-@@ -2403,6 +2406,9 @@ static void uart_poll_put_char(struct tt
- struct uart_state *state = drv->state + line;
+@@ -719,6 +722,9 @@ static void uart_unthrottle(struct tty_s
struct uart_port *port;
+ upstat_t mask = 0;
+ if (!state)
+ return;
diff --git a/patches.drivers/soc-fsl-qe-Fix-an-error-code-in-qe_pin_request.patch b/patches.drivers/soc-fsl-qe-Fix-an-error-code-in-qe_pin_request.patch
new file mode 100644
index 0000000000..386aed57b4
--- /dev/null
+++ b/patches.drivers/soc-fsl-qe-Fix-an-error-code-in-qe_pin_request.patch
@@ -0,0 +1,38 @@
+From 5674a92ca4b7e5a6a19231edd10298d30324cd27 Mon Sep 17 00:00:00 2001
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Thu, 28 Mar 2019 17:18:41 +0300
+Subject: [PATCH] soc/fsl/qe: Fix an error code in qe_pin_request()
+Git-commit: 5674a92ca4b7e5a6a19231edd10298d30324cd27
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+We forgot to set "err" on this error path.
+
+Fixes: 1a2d397a6eb5 ("gpio/powerpc: Eliminate duplication of of_get_named_gpio_flags()")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/soc/fsl/qe/gpio.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c
+index 819bed0f5667..51b3a47b5a55 100644
+--- a/drivers/soc/fsl/qe/gpio.c
++++ b/drivers/soc/fsl/qe/gpio.c
+@@ -179,8 +179,10 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
+ if (err < 0)
+ goto err0;
+ gc = gpio_to_chip(err);
+- if (WARN_ON(!gc))
++ if (WARN_ON(!gc)) {
++ err = -ENODEV;
+ goto err0;
++ }
+
+ if (!of_device_is_compatible(gc->of_node, "fsl,mpc8323-qe-pario-bank")) {
+ pr_debug("%s: tried to get a non-qe pin\n", __func__);
+--
+2.16.4
+
diff --git a/patches.drivers/spi-Micrel-eth-switch-declare-missing-of-table.patch b/patches.drivers/spi-Micrel-eth-switch-declare-missing-of-table.patch
new file mode 100644
index 0000000000..2a1715bd58
--- /dev/null
+++ b/patches.drivers/spi-Micrel-eth-switch-declare-missing-of-table.patch
@@ -0,0 +1,65 @@
+From 2f23a2a768bee7ad2ff1e9527c3f7e279e794a46 Mon Sep 17 00:00:00 2001
+From: Daniel Gomez <dagmcr@gmail.com>
+Date: Mon, 22 Apr 2019 21:08:03 +0200
+Subject: [PATCH] spi: Micrel eth switch: declare missing of table
+Git-commit: 2f23a2a768bee7ad2ff1e9527c3f7e279e794a46
+Patch-mainline: v5.1-rc7
+References: bsc#1051510
+
+Add missing <of_device_id> table for SPI driver relying on SPI
+device match since compatible is in a DT binding or in a DTS.
+
+Before this patch:
+modinfo drivers/net/phy/spi_ks8995.ko | grep alias
+Alias: spi:ksz8795
+Alias: spi:ksz8864
+Alias: spi:ks8995
+
+After this patch:
+modinfo drivers/net/phy/spi_ks8995.ko | grep alias
+Alias: of:N*T*Cmicrel,ksz8795C*
+Alias: of:N*T*Cmicrel,ksz8795
+Alias: of:N*T*Cmicrel,ksz8864C*
+Alias: of:N*T*Cmicrel,ksz8864
+Alias: of:N*T*Cmicrel,ks8995C*
+Alias: of:N*T*Cmicrel,ks8995
+
+Reported-by: Javier Martinez Canillas <javier@dowhile0.org>
+Signed-off-by: Daniel Gomez <dagmcr@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/net/phy/spi_ks8995.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c
+index 92b64e254b44..7475cef17cf7 100644
+--- a/drivers/net/phy/spi_ks8995.c
++++ b/drivers/net/phy/spi_ks8995.c
+@@ -159,6 +159,14 @@ static const struct spi_device_id ks8995_id[] = {
+ };
+ MODULE_DEVICE_TABLE(spi, ks8995_id);
+
++static const struct of_device_id ks8895_spi_of_match[] = {
++ { .compatible = "micrel,ks8995" },
++ { .compatible = "micrel,ksz8864" },
++ { .compatible = "micrel,ksz8795" },
++ { },
++ };
++MODULE_DEVICE_TABLE(of, ks8895_spi_of_match);
++
+ static inline u8 get_chip_id(u8 val)
+ {
+ return (val >> ID1_CHIPID_S) & ID1_CHIPID_M;
+@@ -526,6 +534,7 @@ static int ks8995_remove(struct spi_device *spi)
+ static struct spi_driver ks8995_driver = {
+ .driver = {
+ .name = "spi-ks8995",
++ .of_match_table = of_match_ptr(ks8895_spi_of_match),
+ },
+ .probe = ks8995_probe,
+ .remove = ks8995_remove,
+--
+2.16.4
+
diff --git a/patches.drivers/spi-ST-ST95HF-NFC-declare-missing-of-table.patch b/patches.drivers/spi-ST-ST95HF-NFC-declare-missing-of-table.patch
new file mode 100644
index 0000000000..2cc18f34ea
--- /dev/null
+++ b/patches.drivers/spi-ST-ST95HF-NFC-declare-missing-of-table.patch
@@ -0,0 +1,57 @@
+From d04830531d0c4a99c897a44038e5da3d23331d2f Mon Sep 17 00:00:00 2001
+From: Daniel Gomez <dagmcr@gmail.com>
+Date: Mon, 22 Apr 2019 21:08:04 +0200
+Subject: [PATCH] spi: ST ST95HF NFC: declare missing of table
+Git-commit: d04830531d0c4a99c897a44038e5da3d23331d2f
+Patch-mainline: v5.1-rc7
+References: bsc#1051510
+
+Add missing <of_device_id> table for SPI driver relying on SPI
+device match since compatible is in a DT binding or in a DTS.
+
+Before this patch:
+modinfo drivers/nfc/st95hf/st95hf.ko | grep alias
+Alias: spi:st95hf
+
+After this patch:
+modinfo drivers/nfc/st95hf/st95hf.ko | grep alias
+Alias: of:N*T*Cst,st95hfC*
+Alias: of:N*T*Cst,st95hf
+
+Reported-by: Javier Martinez Canillas <javier@dowhile0.org>
+Signed-off-by: Daniel Gomez <dagmcr@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/nfc/st95hf/core.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/nfc/st95hf/core.c b/drivers/nfc/st95hf/core.c
+index 2b26f762fbc3..01acb6e53365 100644
+--- a/drivers/nfc/st95hf/core.c
++++ b/drivers/nfc/st95hf/core.c
+@@ -1074,6 +1074,12 @@ static const struct spi_device_id st95hf_id[] = {
+ };
+ MODULE_DEVICE_TABLE(spi, st95hf_id);
+
++static const struct of_device_id st95hf_spi_of_match[] = {
++ { .compatible = "st,st95hf" },
++ { },
++};
++MODULE_DEVICE_TABLE(of, st95hf_spi_of_match);
++
+ static int st95hf_probe(struct spi_device *nfc_spi_dev)
+ {
+ int ret;
+@@ -1260,6 +1266,7 @@ static struct spi_driver st95hf_driver = {
+ .driver = {
+ .name = "st95hf",
+ .owner = THIS_MODULE,
++ .of_match_table = of_match_ptr(st95hf_spi_of_match),
+ },
+ .id_table = st95hf_id,
+ .probe = st95hf_probe,
+--
+2.16.4
+
diff --git a/patches.drivers/thermal-cpu_cooling-Actually-trace-CPU-load-in-therm.patch b/patches.drivers/thermal-cpu_cooling-Actually-trace-CPU-load-in-therm.patch
new file mode 100644
index 0000000000..2f43967f7e
--- /dev/null
+++ b/patches.drivers/thermal-cpu_cooling-Actually-trace-CPU-load-in-therm.patch
@@ -0,0 +1,58 @@
+From bf45ac18b78038e43af3c1a273cae4ab5704d2ce Mon Sep 17 00:00:00 2001
+From: Matthias Kaehlcke <mka@chromium.org>
+Date: Thu, 2 May 2019 11:32:38 -0700
+Subject: [PATCH] thermal: cpu_cooling: Actually trace CPU load in thermal_power_cpu_get_power
+Git-commit: bf45ac18b78038e43af3c1a273cae4ab5704d2ce
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+The CPU load values passed to the thermal_power_cpu_get_power
+tracepoint are zero for all CPUs, unless, unless the
+thermal_power_cpu_limit tracepoint is enabled too:
+
+ irq/41-rockchip-98 [000] .... 290.972410: thermal_power_cpu_get_power:
+ cpus=0000000f freq=1800000 load={{0x0,0x0,0x0,0x0}} dynamic_power=4815
+
+vs
+
+ irq/41-rockchip-96 [000] .... 95.773585: thermal_power_cpu_get_power:
+ cpus=0000000f freq=1800000 load={{0x56,0x64,0x64,0x5e}} dynamic_power=4959
+ irq/41-rockchip-96 [000] .... 95.773596: thermal_power_cpu_limit:
+ cpus=0000000f freq=408000 cdev_state=10 power=416
+
+There seems to be no good reason for omitting the CPU load information
+depending on another tracepoint. My guess is that the intention was to
+check whether thermal_power_cpu_get_power is (still) enabled, however
+'load_cpu != NULL' already indicates that it was at least enabled when
+cpufreq_get_requested_power() was entered, there seems little gain
+from omitting the assignment if the tracepoint was just disabled, so
+just remove the check.
+
+Fixes: 6828a4711f99 ("thermal: add trace events to the power allocator governor")
+Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
+Reviewed-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Acked-by: Javi Merino <javi.merino@kernel.org>
+Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
+Signed-off-by: Eduardo Valentin <edubezval@gmail.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/thermal/cpu_cooling.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
+index 9b014d0e8e70..4c5db59a619b 100644
+--- a/drivers/thermal/cpu_cooling.c
++++ b/drivers/thermal/cpu_cooling.c
+@@ -444,7 +444,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
+ load = 0;
+
+ total_load += load;
+- if (trace_thermal_power_cpu_limit_enabled() && load_cpu)
++ if (load_cpu)
+ load_cpu[i] = load;
+
+ i++;
+--
+2.16.4
+
diff --git a/patches.drm/drm-amd-display-If-one-stream-full-updates-full-upda.patch b/patches.drm/drm-amd-display-If-one-stream-full-updates-full-upda.patch
new file mode 100644
index 0000000000..a2b9588e2a
--- /dev/null
+++ b/patches.drm/drm-amd-display-If-one-stream-full-updates-full-upda.patch
@@ -0,0 +1,122 @@
+From c238bfe0be9ef7420f7669a69e27c8c8f4d8a568 Mon Sep 17 00:00:00 2001
+From: David Francis <David.Francis@amd.com>
+Date: Fri, 29 Mar 2019 13:23:15 -0400
+Subject: [PATCH] drm/amd/display: If one stream full updates, full update all planes
+Git-commit: c238bfe0be9ef7420f7669a69e27c8c8f4d8a568
+Patch-mainline: v5.1-rc6
+References: bsc#1111666
+
+[Why]
+On some compositors, with two monitors attached, VT terminal
+switch can cause a graphical issue by the following means:
+
+There are two streams, one for each monitor. Each stream has one
+plane
+
+current state:
+ M1:S1->P1
+ M2:S2->P2
+
+The user calls for a terminal switch and a commit is made to
+change both planes to linear swizzle mode. In atomic check,
+a new dc_state is constructed with new planes on each stream
+
+new state:
+ M1:S1->P3
+ M2:S2->P4
+
+In commit tail, each stream is committed, one at a time. The first
+stream (S1) updates properly, triggerring a full update and replacing
+the state
+
+current state:
+ M1:S1->P3
+ M2:S2->P4
+
+The update for S2 comes in, but dc detects that there is no difference
+between the stream and plane in the new and current states, and so
+triggers a fast update. The fast update does not program swizzle,
+so the second monitor is corrupted
+
+[How]
+Add a flag to dc_plane_state that forces full updates
+
+When a stream undergoes a full update, set this flag on all changed
+planes, then clear it on the current stream
+
+Subsequent streams will get full updates as a result
+
+Signed-off-by: David Francis <David.Francis@amd.com>
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Reviewed-by: Roman Li <Roman.Li@amd.com>
+Acked-by: Bhawanpreet Lakha <Bhawanpreet Lakha@amd.com>
+Acked-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/amd/display/dc/core/dc.c | 19 +++++++++++++++++++
+ drivers/gpu/drm/amd/display/dc/dc.h | 3 +++
+ 2 files changed, 22 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
+index c68fbd55db3c..a6cda201c964 100644
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
+@@ -1377,6 +1377,11 @@ static enum surface_update_type det_surface_update(const struct dc *dc,
+ return UPDATE_TYPE_FULL;
+ }
+
++ if (u->surface->force_full_update) {
++ update_flags->bits.full_update = 1;
++ return UPDATE_TYPE_FULL;
++ }
++
+ type = get_plane_info_update_type(u);
+ elevate_update_type(&overall_type, type);
+
+@@ -1802,6 +1807,14 @@ void dc_commit_updates_for_stream(struct dc *dc,
+ }
+
+ dc_resource_state_copy_construct(state, context);
++
++ for (i = 0; i < dc->res_pool->pipe_count; i++) {
++ struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i];
++ struct pipe_ctx *old_pipe = &dc->current_state->res_ctx.pipe_ctx[i];
++
++ if (new_pipe->plane_state && new_pipe->plane_state != old_pipe->plane_state)
++ new_pipe->plane_state->force_full_update = true;
++ }
+ }
+
+
+@@ -1838,6 +1851,12 @@ void dc_commit_updates_for_stream(struct dc *dc,
+ dc->current_state = context;
+ dc_release_state(old);
+
++ for (i = 0; i < dc->res_pool->pipe_count; i++) {
++ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
++
++ if (pipe_ctx->plane_state && pipe_ctx->stream == stream)
++ pipe_ctx->plane_state->force_full_update = false;
++ }
+ }
+ /*let's use current_state to update watermark etc*/
+ if (update_type >= UPDATE_TYPE_FULL)
+diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
+index 1a7fd6aa77eb..0515095574e7 100644
+--- a/drivers/gpu/drm/amd/display/dc/dc.h
++++ b/drivers/gpu/drm/amd/display/dc/dc.h
+@@ -503,6 +503,9 @@ struct dc_plane_state {
+ struct dc_plane_status status;
+ struct dc_context *ctx;
+
++ /* HACK: Workaround for forcing full reprogramming under some conditions */
++ bool force_full_update;
++
+ /* private to dc_surface.c */
+ enum dc_irq_source irq_source;
+ struct kref refcount;
+--
+2.16.4
+
diff --git a/patches.drm/drm-amd-display-extending-AUX-SW-Timeout.patch b/patches.drm/drm-amd-display-extending-AUX-SW-Timeout.patch
new file mode 100644
index 0000000000..ce8e148668
--- /dev/null
+++ b/patches.drm/drm-amd-display-extending-AUX-SW-Timeout.patch
@@ -0,0 +1,71 @@
+From f4bbebf8e7eb4d294b040ab2d2ba71e70e69b930 Mon Sep 17 00:00:00 2001
+From: Martin Leung <martin.leung@amd.com>
+Date: Tue, 26 Mar 2019 13:14:11 -0400
+Subject: [PATCH] drm/amd/display: extending AUX SW Timeout
+Git-commit: f4bbebf8e7eb4d294b040ab2d2ba71e70e69b930
+Patch-mainline: v5.1-rc6
+References: bsc#1111666
+
+[Why]
+AUX takes longer to reply when using active DP-DVI dongle on some asics
+resulting in up to 2000+ us edid read (timeout).
+
+[How]
+1. Adjust AUX poll to match spec
+2. Extend the SW timeout. This does not affect normal
+operation since we exit the loop as soon as AUX acks.
+
+Signed-off-by: Martin Leung <martin.leung@amd.com>
+Reviewed-by: Jun Lei <Jun.Lei@amd.com>
+Acked-by: Joshua Aberback <Joshua.Aberback@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/amd/display/dc/dce/dce_aux.c | 9 ++++++---
+ drivers/gpu/drm/amd/display/dc/dce/dce_aux.h | 6 +++---
+ 2 files changed, 9 insertions(+), 6 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.c
+@@ -189,6 +189,12 @@ static void submit_channel_request(
+ 1,
+ 0);
+ }
++
++ REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1);
++
++ REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0,
++ 10, aux110->timeout_period/10);
++
+ /* set the delay and the number of bytes to write */
+
+ /* The length include
+@@ -241,9 +247,6 @@ static void submit_channel_request(
+ }
+ }
+
+- REG_UPDATE(AUX_INTERRUPT_CONTROL, AUX_SW_DONE_ACK, 1);
+- REG_WAIT(AUX_SW_STATUS, AUX_SW_DONE, 0,
+- 10, aux110->timeout_period/10);
+ REG_UPDATE(AUX_SW_CONTROL, AUX_SW_GO, 1);
+ }
+
+--- a/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
++++ b/drivers/gpu/drm/amd/display/dc/dce/dce_aux.h
+@@ -69,11 +69,11 @@ enum { /* This is the timeout as defined
+ * at most within ~240usec. That means,
+ * increasing this timeout will not affect normal operation,
+ * and we'll timeout after
+- * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 1600usec.
++ * SW_AUX_TIMEOUT_PERIOD_MULTIPLIER * AUX_TIMEOUT_PERIOD = 2400usec.
+ * This timeout is especially important for
+- * resume from S3 and CTS.
++ * converters, resume from S3, and CTS.
+ */
+- SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 4
++ SW_AUX_TIMEOUT_PERIOD_MULTIPLIER = 6
+ };
+ struct aux_engine_dce110 {
+ struct aux_engine base;
diff --git a/patches.drm/drm-bridge-adv7511-Fix-low-refresh-rate-selection.patch b/patches.drm/drm-bridge-adv7511-Fix-low-refresh-rate-selection.patch
new file mode 100644
index 0000000000..e105b76f1c
--- /dev/null
+++ b/patches.drm/drm-bridge-adv7511-Fix-low-refresh-rate-selection.patch
@@ -0,0 +1,51 @@
+From 67793bd3b3948dc8c8384b6430e036a30a0ecb43 Mon Sep 17 00:00:00 2001
+From: Matt Redfearn <matt.redfearn@thinci.com>
+Date: Wed, 24 Apr 2019 13:22:27 +0000
+Subject: [PATCH] drm/bridge: adv7511: Fix low refresh rate selection
+Git-commit: 67793bd3b3948dc8c8384b6430e036a30a0ecb43
+Patch-mainline: v5.2-rc1
+References: bsc#1051510
+
+The driver currently sets register 0xfb (Low Refresh Rate) based on the
+value of mode->vrefresh. Firstly, this field is specified to be in Hz,
+but the magic numbers used by the code are Hz * 1000. This essentially
+leads to the low refresh rate always being set to 0x01, since the
+vrefresh value will always be less than 24000. Fix the magic numbers to
+be in Hz.
+Secondly, according to the comment in drm_modes.h, the field is not
+supposed to be used in a functional way anyway. Instead, use the helper
+function drm_mode_vrefresh().
+
+Fixes: 9c8af882bf12 ("drm: Add adv7511 encoder driver")
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: Matt Redfearn <matt.redfearn@thinci.com>
+Signed-off-by: Sean Paul <seanpaul@chromium.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20190424132210.26338-1-matt.redfearn@thinci.com
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+index ec2ca71e1323..c532e9c9e491 100644
+--- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
++++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c
+@@ -748,11 +748,11 @@ static void adv7511_mode_set(struct adv7511 *adv7511,
+ vsync_polarity = 1;
+ }
+
+- if (mode->vrefresh <= 24000)
++ if (drm_mode_vrefresh(mode) <= 24)
+ low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ;
+- else if (mode->vrefresh <= 25000)
++ else if (drm_mode_vrefresh(mode) <= 25)
+ low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ;
+- else if (mode->vrefresh <= 30000)
++ else if (drm_mode_vrefresh(mode) <= 30)
+ low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ;
+ else
+ low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE;
+--
+2.16.4
+
diff --git a/patches.drm/0004-drm-i915-Disable-LP3-watermarks-on-all-SNB-machines.patch b/patches.drm/drm-i915-Disable-LP3-watermarks-on-all-SNB-machines.patch
index db39e2d0dc..4a04e2be96 100644
--- a/patches.drm/0004-drm-i915-Disable-LP3-watermarks-on-all-SNB-machines.patch
+++ b/patches.drm/drm-i915-Disable-LP3-watermarks-on-all-SNB-machines.patch
@@ -1,13 +1,14 @@
-From 21556350ade3cb5d7afecc8b3544e56431d21695 Mon Sep 17 00:00:00 2001
+From 03981c6ebec4fc7056b9b45f847393aeac90d060 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
Date: Wed, 14 Nov 2018 19:34:40 +0200
-Subject: drm/i915: Disable LP3 watermarks on all SNB machines
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-Git-commit: 21556350ade3cb5d7afecc8b3544e56431d21695
-Patch-mainline: v4.20-rc4
-References: bsc#1113956
+Subject: [PATCH] drm/i915: Disable LP3 watermarks on all SNB machines
+Mime-version: 1.0
+Content-type: text/plain; charset=UTF-8
+Content-transfer-encoding: 8bit
+Git-commit: 03981c6ebec4fc7056b9b45f847393aeac90d060
+No-fix: 21556350ade3cb5d7afecc8b3544e56431d21695
+Patch-mainline: v5.0-rc1
+References: bsc#1051510 bsc#1113956
I have a Thinkpad X220 Tablet in my hands that is losing vblank
interrupts whenever LP3 watermarks are used.
@@ -38,7 +39,7 @@ to check for that. The behaviour now matches that of the
g4x/vlv/skl wm code in the presence of a zeroed latency
value.
-v2: s/USHRT_MAX/U32_MAX/ for consistency with the types (Chris)
+V2: s/USHRT_MAX/U32_MAX/ for consistency with the types (Chris)
Cc: stable@vger.kernel.org
Cc: Chris Wilson <chris@chris-wilson.co.uk>
@@ -47,15 +48,14 @@ Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=101269
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103713
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181114173440.6730-1-ville.syrjala@linux.intel.com
-(cherry picked from commit 03981c6ebec4fc7056b9b45f847393aeac90d060)
-Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
-Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
---
- drivers/gpu/drm/i915/intel_pm.c | 41 ++++++++++++++++++++++++++++++++-
+ drivers/gpu/drm/i915/intel_pm.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
-index 245f0022bcfd..3fe358db1276 100644
+index 27498ded4949..897a791662c5 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2493,6 +2493,9 @@ static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
@@ -136,5 +136,5 @@ index 245f0022bcfd..3fe358db1276 100644
static void skl_setup_wm_latency(struct drm_i915_private *dev_priv)
--
-2.20.1
+2.16.4
diff --git a/patches.drm/0001-drm-i915-Downgrade-Gen9-Plane-WM-latency-error.patch b/patches.drm/drm-i915-Downgrade-Gen9-Plane-WM-latency-error.patch
index ecdaa571ac..3ffca73c60 100644
--- a/patches.drm/0001-drm-i915-Downgrade-Gen9-Plane-WM-latency-error.patch
+++ b/patches.drm/drm-i915-Downgrade-Gen9-Plane-WM-latency-error.patch
@@ -1,10 +1,10 @@
From 86c1c87d0e6241cbe35bd52badfc84b154e1b959 Mon Sep 17 00:00:00 2001
From: Chris Wilson <chris@chris-wilson.co.uk>
Date: Thu, 26 Jul 2018 17:15:27 +0100
-Subject: drm/i915: Downgrade Gen9 Plane WM latency error
+Subject: [PATCH] drm/i915: Downgrade Gen9 Plane WM latency error
Git-commit: 86c1c87d0e6241cbe35bd52badfc84b154e1b959
Patch-mainline: v4.20-rc1
-References: bsc#1113956
+References: bsc#1051510 bsc#1113956
According to intel_read_wm_latency() it is perfectly legal for one WM
and all subsequent levels to be 0 (and the deeper powersaving states
@@ -15,7 +15,8 @@ Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Acked-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180726161527.10516-1-chris@chris-wilson.co.uk
-Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
---
drivers/gpu/drm/i915/intel_pm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
@@ -36,5 +37,5 @@ index f175923939ae..8a4152244571 100644
}
--
-2.20.1
+2.16.4
diff --git a/patches.drm/drm-i915-Force-2-96-MHz-cdclk-on-glk-cnl-when-audio-.patch b/patches.drm/drm-i915-Force-2-96-MHz-cdclk-on-glk-cnl-when-audio-.patch
new file mode 100644
index 0000000000..d5ca7b05b6
--- /dev/null
+++ b/patches.drm/drm-i915-Force-2-96-MHz-cdclk-on-glk-cnl-when-audio-.patch
@@ -0,0 +1,271 @@
+From 905801fe72377b4dc53c6e13eea1a91c6a4aa0c4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
+Date: Wed, 20 Mar 2019 15:54:36 +0200
+Subject: [PATCH] drm/i915: Force 2*96 MHz cdclk on glk/cnl when audio power is enabled
+Mime-version: 1.0
+Content-type: text/plain; charset=UTF-8
+Content-transfer-encoding: 8bit
+Git-commit: 905801fe72377b4dc53c6e13eea1a91c6a4aa0c4
+Patch-mainline: v5.2-rc1
+References: bsc#1111666
+
+[ Backport note: slightly modified the context to apply cleanly without the
+ prerequisite changes (d31c85fc8642) about display power cookie.
+ The actual regression report is found in bko#203623 -- tiwai ]
+
+CDCLK has to be at least twice the BLCK regardless of audio. Audio
+driver has to probe using this hook and increase the clock even in
+absence of any display.
+
+V2: Use atomic refcount for get_power, put_power so that we can call each once(Abhay).
+V3: Reset power well 2 to avoid any transaction on iDisp link during cdclk change(Abhay).
+V4: Remove Power well 2 reset workaround(Ville).
+V5: Remove unwanted Power well 2 register defined in v4(Abhay).
+V6:
+- Use a dedicated flag instead of state->modeset for min CDCLK changes
+- Make get/put audio power domain symmetric
+- Rebased on top of intel_wakeref tracking changes.
+
+Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Signed-off-by: Abhay Kumar <abhay.kumar@intel.com>
+Tested-by: Abhay Kumar <abhay.kumar@intel.com>
+Signed-off-by: Imre Deak <imre.deak@intel.com>
+Reviewed-by: Clint Taylor <Clinton.A.Taylor@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20190320135439.12201-1-imre.deak@intel.com
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/i915/i915_drv.h | 3 +
+ drivers/gpu/drm/i915/intel_audio.c | 57 +++++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/i915/intel_cdclk.c | 30 ++++++------------
+ drivers/gpu/drm/i915/intel_display.c | 9 ++++-
+ drivers/gpu/drm/i915/intel_drv.h | 3 +
+ 5 files changed, 81 insertions(+), 21 deletions(-)
+
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -1732,6 +1732,8 @@ struct drm_i915_private {
+ struct intel_cdclk_state actual;
+ /* The current hardware cdclk state */
+ struct intel_cdclk_state hw;
++
++ int force_min_cdclk;
+ } cdclk;
+
+ /**
+@@ -1852,6 +1854,7 @@ struct drm_i915_private {
+ *
+ */
+ struct mutex av_mutex;
++ int audio_power_refcount;
+
+ struct {
+ struct mutex mutex;
+--- a/drivers/gpu/drm/i915/intel_audio.c
++++ b/drivers/gpu/drm/i915/intel_audio.c
+@@ -742,13 +742,70 @@ void intel_init_audio_hooks(struct drm_i
+ }
+ }
+
++static void glk_force_audio_cdclk(struct drm_i915_private *dev_priv,
++ bool enable)
++{
++ struct drm_modeset_acquire_ctx ctx;
++ struct drm_atomic_state *state;
++ int ret;
++
++ drm_modeset_acquire_init(&ctx, 0);
++ state = drm_atomic_state_alloc(&dev_priv->drm);
++ if (WARN_ON(!state))
++ return;
++
++ state->acquire_ctx = &ctx;
++
++retry:
++ to_intel_atomic_state(state)->cdclk.force_min_cdclk_changed = true;
++ to_intel_atomic_state(state)->cdclk.force_min_cdclk =
++ enable ? 2 * 96000 : 0;
++
++ /*
++ * Protects dev_priv->cdclk.force_min_cdclk
++ * Need to lock this here in case we have no active pipes
++ * and thus wouldn't lock it during the commit otherwise.
++ */
++ ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex,
++ &ctx);
++ if (!ret)
++ ret = drm_atomic_commit(state);
++
++ if (ret == -EDEADLK) {
++ drm_atomic_state_clear(state);
++ drm_modeset_backoff(&ctx);
++ goto retry;
++ }
++
++ WARN_ON(ret);
++
++ drm_atomic_state_put(state);
++
++ drm_modeset_drop_locks(&ctx);
++ drm_modeset_acquire_fini(&ctx);
++}
++
+ static void i915_audio_component_get_power(struct device *kdev)
+ {
++ struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
++
+ intel_display_power_get(kdev_to_i915(kdev), POWER_DOMAIN_AUDIO);
++
++ /* Force CDCLK to 2*BCLK as long as we need audio to be powered. */
++ if (dev_priv->audio_power_refcount++ == 0)
++ if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
++ glk_force_audio_cdclk(dev_priv, true);
+ }
+
+ static void i915_audio_component_put_power(struct device *kdev)
+ {
++ struct drm_i915_private *dev_priv = kdev_to_i915(kdev);
++
++ /* Stop forcing CDCLK to 2*BCLK if no need for audio to be powered. */
++ if (--dev_priv->audio_power_refcount == 0)
++ if (IS_CANNONLAKE(dev_priv) || IS_GEMINILAKE(dev_priv))
++ glk_force_audio_cdclk(dev_priv, false);
++
+ intel_display_power_put(kdev_to_i915(kdev), POWER_DOMAIN_AUDIO);
+ }
+
+--- a/drivers/gpu/drm/i915/intel_cdclk.c
++++ b/drivers/gpu/drm/i915/intel_cdclk.c
+@@ -2185,19 +2185,8 @@ int intel_crtc_compute_min_cdclk(const s
+ /*
+ * According to BSpec, "The CD clock frequency must be at least twice
+ * the frequency of the Azalia BCLK." and BCLK is 96 MHz by default.
+- *
+- * FIXME: Check the actual, not default, BCLK being used.
+- *
+- * FIXME: This does not depend on ->has_audio because the higher CDCLK
+- * is required for audio probe, also when there are no audio capable
+- * displays connected at probe time. This leads to unnecessarily high
+- * CDCLK when audio is not required.
+- *
+- * FIXME: This limit is only applied when there are displays connected
+- * at probe time. If we probe without displays, we'll still end up using
+- * the platform minimum CDCLK, failing audio probe.
+ */
+- if (INTEL_GEN(dev_priv) >= 9)
++ if (crtc_state->has_audio && INTEL_GEN(dev_priv) >= 9)
+ min_cdclk = max(2 * 96000, min_cdclk);
+
+ /*
+@@ -2237,7 +2226,7 @@ static int intel_compute_min_cdclk(struc
+ intel_state->min_cdclk[i] = min_cdclk;
+ }
+
+- min_cdclk = 0;
++ min_cdclk = intel_state->cdclk.force_min_cdclk;
+ for_each_pipe(dev_priv, pipe)
+ min_cdclk = max(intel_state->min_cdclk[pipe], min_cdclk);
+
+@@ -2298,7 +2287,8 @@ static int vlv_modeset_calc_cdclk(struct
+ vlv_calc_voltage_level(dev_priv, cdclk);
+
+ if (!intel_state->active_crtcs) {
+- cdclk = vlv_calc_cdclk(dev_priv, 0);
++ cdclk = vlv_calc_cdclk(dev_priv,
++ intel_state->cdclk.force_min_cdclk);
+
+ intel_state->cdclk.actual.cdclk = cdclk;
+ intel_state->cdclk.actual.voltage_level =
+@@ -2331,7 +2321,7 @@ static int bdw_modeset_calc_cdclk(struct
+ bdw_calc_voltage_level(cdclk);
+
+ if (!intel_state->active_crtcs) {
+- cdclk = bdw_calc_cdclk(0);
++ cdclk = bdw_calc_cdclk(intel_state->cdclk.force_min_cdclk);
+
+ intel_state->cdclk.actual.cdclk = cdclk;
+ intel_state->cdclk.actual.voltage_level =
+@@ -2403,7 +2393,7 @@ static int skl_modeset_calc_cdclk(struct
+ skl_calc_voltage_level(cdclk);
+
+ if (!intel_state->active_crtcs) {
+- cdclk = skl_calc_cdclk(0, vco);
++ cdclk = skl_calc_cdclk(intel_state->cdclk.force_min_cdclk, vco);
+
+ intel_state->cdclk.actual.vco = vco;
+ intel_state->cdclk.actual.cdclk = cdclk;
+@@ -2442,10 +2432,10 @@ static int bxt_modeset_calc_cdclk(struct
+
+ if (!intel_state->active_crtcs) {
+ if (IS_GEMINILAKE(dev_priv)) {
+- cdclk = glk_calc_cdclk(0);
++ cdclk = glk_calc_cdclk(intel_state->cdclk.force_min_cdclk);
+ vco = glk_de_pll_vco(dev_priv, cdclk);
+ } else {
+- cdclk = bxt_calc_cdclk(0);
++ cdclk = bxt_calc_cdclk(intel_state->cdclk.force_min_cdclk);
+ vco = bxt_de_pll_vco(dev_priv, cdclk);
+ }
+
+@@ -2481,7 +2471,7 @@ static int cnl_modeset_calc_cdclk(struct
+ cnl_compute_min_voltage_level(intel_state));
+
+ if (!intel_state->active_crtcs) {
+- cdclk = cnl_calc_cdclk(0);
++ cdclk = cnl_calc_cdclk(intel_state->cdclk.force_min_cdclk);
+ vco = cnl_cdclk_pll_vco(dev_priv, cdclk);
+
+ intel_state->cdclk.actual.vco = vco;
+@@ -2517,7 +2507,7 @@ static int icl_modeset_calc_cdclk(struct
+ cnl_compute_min_voltage_level(intel_state));
+
+ if (!intel_state->active_crtcs) {
+- cdclk = icl_calc_cdclk(0, ref);
++ cdclk = icl_calc_cdclk(intel_state->cdclk.force_min_cdclk, ref);
+ vco = icl_calc_cdclk_pll_vco(dev_priv, cdclk);
+
+ intel_state->cdclk.actual.vco = vco;
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -12305,6 +12305,11 @@ static int intel_modeset_checks(struct d
+ return -EINVAL;
+ }
+
++ /* keep the current setting */
++ if (!intel_state->cdclk.force_min_cdclk_changed)
++ intel_state->cdclk.force_min_cdclk =
++ dev_priv->cdclk.force_min_cdclk;
++
+ intel_state->modeset = true;
+ intel_state->active_crtcs = dev_priv->active_crtcs;
+ intel_state->cdclk.logical = dev_priv->cdclk.logical;
+@@ -12400,7 +12405,7 @@ static int intel_atomic_check(struct drm
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *old_crtc_state, *crtc_state;
+ int ret, i;
+- bool any_ms = false;
++ bool any_ms = intel_state->cdclk.force_min_cdclk_changed;
+
+ /* Catch I915_MODE_FLAG_INHERITED */
+ for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
+@@ -12959,6 +12964,8 @@ static int intel_atomic_commit(struct dr
+ dev_priv->active_crtcs = intel_state->active_crtcs;
+ dev_priv->cdclk.logical = intel_state->cdclk.logical;
+ dev_priv->cdclk.actual = intel_state->cdclk.actual;
++ dev_priv->cdclk.force_min_cdclk =
++ intel_state->cdclk.force_min_cdclk;
+ }
+
+ drm_atomic_state_get(state);
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -467,6 +467,9 @@ struct intel_atomic_state {
+ * state only when all crtc's are DPMS off.
+ */
+ struct intel_cdclk_state actual;
++
++ int force_min_cdclk;
++ bool force_min_cdclk_changed;
+ } cdclk;
+
+ bool dpll_set, modeset;
diff --git a/patches.drm/drm-i915-fbc-disable-framebuffer-compression-on-Gemi.patch b/patches.drm/drm-i915-fbc-disable-framebuffer-compression-on-Gemi.patch
new file mode 100644
index 0000000000..e222d5d735
--- /dev/null
+++ b/patches.drm/drm-i915-fbc-disable-framebuffer-compression-on-Gemi.patch
@@ -0,0 +1,55 @@
+From 396dd8143bdd94bd1c358a228a631c8c895a1126 Mon Sep 17 00:00:00 2001
+From: Daniel Drake <drake@endlessm.com>
+Date: Tue, 23 Apr 2019 17:28:10 +0800
+Subject: [PATCH] drm/i915/fbc: disable framebuffer compression on GeminiLake
+Git-commit: 396dd8143bdd94bd1c358a228a631c8c895a1126
+Patch-mainline: v5.2-rc1
+No-fix: 1d25724b41fad7eeb2c3058a5c8190d6ece73e08
+References: bsc#1051510
+
+On many (all?) the Gemini Lake systems we work with, there is frequent
+momentary graphical corruption at the top of the screen, and it seems
+that disabling framebuffer compression can avoid this.
+
+The ticket was reported 6 months ago and has already affected a
+multitude of users, without any real progress being made. So, lets
+disable framebuffer compression on GeminiLake until a solution is found.
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108085
+Fixes: fd7d6c5c8f3e ("drm/i915: enable FBC on gen9+ too")
+Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
+Cc: Jani Nikula <jani.nikula@linux.intel.com>
+Cc: <stable@vger.kernel.org> # v4.11+
+Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
+Signed-off-by: Daniel Drake <drake@endlessm.com>
+Signed-off-by: Jian-Hong Pan <jian-hong@endlessm.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20190423092810.28359-1-jian-hong@endlessm.com
+(cherry picked from commit 1d25724b41fad7eeb2c3058a5c8190d6ece73e08)
+
+Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/i915/intel_fbc.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
+index c805a0966395..5679f2fffb7c 100644
+--- a/drivers/gpu/drm/i915/intel_fbc.c
++++ b/drivers/gpu/drm/i915/intel_fbc.c
+@@ -1280,6 +1280,10 @@ static int intel_sanitize_fbc_option(struct drm_i915_private *dev_priv)
+ if (!HAS_FBC(dev_priv))
+ return 0;
+
++ /* https://bugs.freedesktop.org/show_bug.cgi?id=108085 */
++ if (IS_GEMINILAKE(dev_priv))
++ return 0;
++
+ if (IS_BROADWELL(dev_priv) || INTEL_GEN(dev_priv) >= 9)
+ return 1;
+
+--
+2.16.4
+
diff --git a/patches.drm/drm-imx-don-t-skip-DP-channel-disable-for-background.patch b/patches.drm/drm-imx-don-t-skip-DP-channel-disable-for-background.patch
new file mode 100644
index 0000000000..e27805258f
--- /dev/null
+++ b/patches.drm/drm-imx-don-t-skip-DP-channel-disable-for-background.patch
@@ -0,0 +1,34 @@
+From 7bcde275eb1d0ac8793c77c7e666a886eb16633d Mon Sep 17 00:00:00 2001
+From: Lucas Stach <l.stach@pengutronix.de>
+Date: Fri, 12 Apr 2019 17:59:41 +0200
+Subject: [PATCH] drm/imx: don't skip DP channel disable for background plane
+Git-commit: 7bcde275eb1d0ac8793c77c7e666a886eb16633d
+Patch-mainline: v5.1-rc7
+References: bsc#1051510
+
+In order to make sure that the plane color space gets reset correctly.
+
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/imx/ipuv3-crtc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
+index ec3602ebbc1c..54011df8c2e8 100644
+--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
++++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
+@@ -71,7 +71,7 @@ static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc,
+ if (disable_partial)
+ ipu_plane_disable(ipu_crtc->plane[1], true);
+ if (disable_full)
+- ipu_plane_disable(ipu_crtc->plane[0], false);
++ ipu_plane_disable(ipu_crtc->plane[0], true);
+ }
+
+ static void ipu_crtc_atomic_disable(struct drm_crtc *crtc,
+--
+2.16.4
+
diff --git a/patches.drm/drm-pl111-Initialize-clock-spinlock-early.patch b/patches.drm/drm-pl111-Initialize-clock-spinlock-early.patch
new file mode 100644
index 0000000000..19e11bb2e1
--- /dev/null
+++ b/patches.drm/drm-pl111-Initialize-clock-spinlock-early.patch
@@ -0,0 +1,67 @@
+From 3e01ae2612bdd7975c74ec7123d7f8f5e6eed795 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Mon, 13 May 2019 07:46:21 -0700
+Subject: [PATCH] drm/pl111: Initialize clock spinlock early
+Git-commit: 3e01ae2612bdd7975c74ec7123d7f8f5e6eed795
+Patch-mainline: v5.2-rc1
+References: bsc#1111666
+
+The following warning is seen on systems with broken clock divider.
+
+Info: trying to register non-static key.
+the code is fine but needs lockdep annotation.
+turning off the locking correctness validator.
+Cpu: 0 PID: 1 Comm: swapper Not tainted 5.1.0-09698-g1fb3b52 #1
+Hardware name: ARM Integrator/CP (Device Tree)
+[<c0011be8>] (unwind_backtrace) from [<c000ebb8>] (show_stack+0x10/0x18)
+[<c000ebb8>] (show_stack) from [<c07d3fd0>] (dump_stack+0x18/0x24)
+[<c07d3fd0>] (dump_stack) from [<c0060d48>] (register_lock_class+0x674/0x6f8)
+[<c0060d48>] (register_lock_class) from [<c005de2c>]
+ (__lock_acquire+0x68/0x2128)
+[<c005de2c>] (__lock_acquire) from [<c0060408>] (lock_acquire+0x110/0x21c)
+[<c0060408>] (lock_acquire) from [<c07f755c>] (_raw_spin_lock+0x34/0x48)
+[<c07f755c>] (_raw_spin_lock) from [<c0536c8c>]
+ (pl111_display_enable+0xf8/0x5fc)
+[<c0536c8c>] (pl111_display_enable) from [<c0502f54>]
+ (drm_atomic_helper_commit_modeset_enables+0x1ec/0x244)
+
+Since commit eedd6033b4c8 ("drm/pl111: Support variants with broken clock
+divider"), the spinlock is not initialized if the clock divider is broken.
+Initialize it earlier to fix the problem.
+
+Fixes: eedd6033b4c8 ("drm/pl111: Support variants with broken clock divider")
+Cc: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/1557758781-23586-1-git-send-email-linux@roeck-us.net
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/drm/pl111/pl111_display.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c
+index 0c5d391f0a8f..4501597f30ab 100644
+--- a/drivers/gpu/drm/pl111/pl111_display.c
++++ b/drivers/gpu/drm/pl111/pl111_display.c
+@@ -531,14 +531,15 @@ pl111_init_clock_divider(struct drm_device *drm)
+ dev_err(drm->dev, "CLCD: unable to get clcdclk.\n");
+ return PTR_ERR(parent);
+ }
++
++ spin_lock_init(&priv->tim2_lock);
++
+ /* If the clock divider is broken, use the parent directly */
+ if (priv->variant->broken_clockdivider) {
+ priv->clk = parent;
+ return 0;
+ }
+ parent_name = __clk_get_name(parent);
+-
+- spin_lock_init(&priv->tim2_lock);
+ div->init = &init;
+
+ ret = devm_clk_hw_register(drm->dev, div);
+--
+2.16.4
+
diff --git a/patches.drm/drm-rockchip-fix-for-mailbox-read-validation.patch b/patches.drm/drm-rockchip-fix-for-mailbox-read-validation.patch
index 8a696877e5..3453fe6978 100644
--- a/patches.drm/drm-rockchip-fix-for-mailbox-read-validation.patch
+++ b/patches.drm/drm-rockchip-fix-for-mailbox-read-validation.patch
@@ -4,7 +4,7 @@ Date: Mon, 19 Nov 2018 15:14:14 +0000
Subject: [PATCH] drm/rockchip: fix for mailbox read validation.
Git-commit: e4056bbb6719fe713bfc4030ac78e8e97ddf7574
Patch-mainline: v5.1-rc1
-References: bsc#1111666
+References: bsc#1051510 bsc#1111666
This is basically the same fix as in
commit fa68d4f8476b ("drm/rockchip: fix for mailbox read size")
diff --git a/patches.drm/gpu-ipu-v3-dp-fix-CSC-handling.patch b/patches.drm/gpu-ipu-v3-dp-fix-CSC-handling.patch
new file mode 100644
index 0000000000..088bcd1145
--- /dev/null
+++ b/patches.drm/gpu-ipu-v3-dp-fix-CSC-handling.patch
@@ -0,0 +1,71 @@
+From d4fad0a426c6e26f48c9a7cdd21a7fe9c198d645 Mon Sep 17 00:00:00 2001
+From: Lucas Stach <l.stach@pengutronix.de>
+Date: Fri, 12 Apr 2019 17:59:40 +0200
+Subject: [PATCH] gpu: ipu-v3: dp: fix CSC handling
+Git-commit: d4fad0a426c6e26f48c9a7cdd21a7fe9c198d645
+Patch-mainline: v5.1-rc7
+References: bsc#1051510
+
+Initialize the flow input colorspaces to unknown and reset to that value
+when the channel gets disabled. This avoids the state getting mixed up
+with a previous mode.
+
+Also keep the CSC settings for the background flow intact when disabling
+the foreground flow.
+
+Root-caused-by: Jonathan Marek <jonathan@marek.ca>
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
+Acked-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ drivers/gpu/ipu-v3/ipu-dp.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/ipu-v3/ipu-dp.c b/drivers/gpu/ipu-v3/ipu-dp.c
+index 9b2b3fa479c4..5e44ff1f2085 100644
+--- a/drivers/gpu/ipu-v3/ipu-dp.c
++++ b/drivers/gpu/ipu-v3/ipu-dp.c
+@@ -195,7 +195,8 @@ int ipu_dp_setup_channel(struct ipu_dp *dp,
+ ipu_dp_csc_init(flow, flow->foreground.in_cs, flow->out_cs,
+ DP_COM_CONF_CSC_DEF_BOTH);
+ } else {
+- if (flow->foreground.in_cs == flow->out_cs)
++ if (flow->foreground.in_cs == IPUV3_COLORSPACE_UNKNOWN ||
++ flow->foreground.in_cs == flow->out_cs)
+ /*
+ * foreground identical to output, apply color
+ * conversion on background
+@@ -261,6 +262,8 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync)
+ struct ipu_dp_priv *priv = flow->priv;
+ u32 reg, csc;
+
++ dp->in_cs = IPUV3_COLORSPACE_UNKNOWN;
++
+ if (!dp->foreground)
+ return;
+
+@@ -268,8 +271,9 @@ void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync)
+
+ reg = readl(flow->base + DP_COM_CONF);
+ csc = reg & DP_COM_CONF_CSC_DEF_MASK;
+- if (csc == DP_COM_CONF_CSC_DEF_FG)
+- reg &= ~DP_COM_CONF_CSC_DEF_MASK;
++ reg &= ~DP_COM_CONF_CSC_DEF_MASK;
++ if (csc == DP_COM_CONF_CSC_DEF_BOTH || csc == DP_COM_CONF_CSC_DEF_BG)
++ reg |= DP_COM_CONF_CSC_DEF_BG;
+
+ reg &= ~DP_COM_CONF_FG_EN;
+ writel(reg, flow->base + DP_COM_CONF);
+@@ -347,6 +351,8 @@ int ipu_dp_init(struct ipu_soc *ipu, struct device *dev, unsigned long base)
+ mutex_init(&priv->mutex);
+
+ for (i = 0; i < IPUV3_NUM_FLOWS; i++) {
++ priv->flow[i].background.in_cs = IPUV3_COLORSPACE_UNKNOWN;
++ priv->flow[i].foreground.in_cs = IPUV3_COLORSPACE_UNKNOWN;
+ priv->flow[i].foreground.foreground = true;
+ priv->flow[i].base = priv->base + ipu_dp_flow_base[i];
+ priv->flow[i].priv = priv;
+--
+2.16.4
+
diff --git a/patches.fixes/0001-PCI-pciehp-Tolerate-Presence-Detect-hardwired-to-zer.patch b/patches.fixes/0001-PCI-pciehp-Tolerate-Presence-Detect-hardwired-to-zer.patch
new file mode 100644
index 0000000000..f61a309b5d
--- /dev/null
+++ b/patches.fixes/0001-PCI-pciehp-Tolerate-Presence-Detect-hardwired-to-zer.patch
@@ -0,0 +1,200 @@
+From 80696f991424d05a784c0cf9c314ac09ac280406 Mon Sep 17 00:00:00 2001
+From: Lukas Wunner <lukas@wunner.de>
+Date: Sat, 8 Sep 2018 09:59:01 +0200
+Subject: [PATCH] PCI: pciehp: Tolerate Presence Detect hardwired to zero
+Git-commit: 80696f991424d05a784c0cf9c314ac09ac280406
+Patch-mainline: v4.20
+References: bsc#1133016
+
+The WiGig Bus Extension (WBE) specification allows tunneling PCIe over
+IEEE 802.11. A product implementing this spec is the wil6210 from
+Wilocity (now part of Qualcomm Atheros). It integrates a PCIe switch
+with a wireless network adapter:
+
+ 00.0-+ [1ae9:0101] Upstream Port
+ +-00.0-+ [1ae9:0200] Downstream Port
+ | +-00.0 [168c:0034] Atheros AR9462 Wireless Network Adapter
+ +-02.0 [1ae9:0201] Downstream Port
+ +-03.0 [1ae9:0201] Downstream Port
+
+Wirelessly attached devices presumably appear below the hotplug ports
+with device ID [1ae9:0201]. Oddly, the Downstream Port [1ae9:0200]
+leading to the wireless network adapter is likewise Hotplug Capable,
+but has its Presence Detect State bit hardwired to zero. Even if the
+Link Active bit is set, Presence Detect is zero, so this cannot be
+caused by in-band presence detection but only by broken hardware.
+
+pciehp assumes an empty slot if Presence Detect State is zero,
+regardless of Link Active being one. Consequently, up until v4.18 it
+removes the wireless network adapter in pciehp_resume(). From v4.19 it
+already does so in pciehp_probe().
+
+Be lenient towards broken hardware and assume the slot is occupied if
+Link Active is set: Introduce pciehp_card_present_or_link_active()
+and use it in lieu of pciehp_get_adapter_status() everywhere, except
+in pciehp_handle_presence_or_link_change() whose log messages depend
+on which of Presence Detect State or Link Active is set.
+
+Remove the Presence Detect State check from __pciehp_enable_slot()
+because it is only called if either of Presence Detect State or Link
+Active is set.
+
+Caution: There is a possibility that broken hardware exists which has
+working Presence Detect but hardwires Link Active to one. On such
+hardware the slot will now incorrectly be considered always occupied.
+If such hardware is discovered, this commit can be rolled back and a
+quirk can be added which sets is_hotplug_bridge = 0 for [1ae9:0200].
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=200839
+Reported-and-tested-by: David Yang <mmyangfl@gmail.com>
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: Rajat Jain <rajatja@google.com>
+Cc: Ashok Raj <ashok.raj@intel.com>
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+---
+ drivers/pci/hotplug/pciehp.h | 3 ++-
+ drivers/pci/hotplug/pciehp_core.c | 6 +++---
+ drivers/pci/hotplug/pciehp_ctrl.c | 10 ++--------
+ drivers/pci/hotplug/pciehp_hpc.c | 25 +++++++++++++++++++------
+ 4 files changed, 26 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
+index 8131c08b21e5..b9204ef3ecd7 100644
+--- a/drivers/pci/hotplug/pciehp.h
++++ b/drivers/pci/hotplug/pciehp.h
+@@ -190,11 +190,12 @@ void pciehp_get_power_status(struct slot *slot, u8 *status);
+
+ void pciehp_set_attention_status(struct slot *slot, u8 status);
+ void pciehp_get_latch_status(struct slot *slot, u8 *status);
+-void pciehp_get_adapter_status(struct slot *slot, u8 *status);
+ int pciehp_query_power_fault(struct slot *slot);
+ void pciehp_green_led_on(struct slot *slot);
+ void pciehp_green_led_off(struct slot *slot);
+ void pciehp_green_led_blink(struct slot *slot);
++bool pciehp_card_present(struct controller *ctrl);
++bool pciehp_card_present_or_link_active(struct controller *ctrl);
+ int pciehp_check_link_status(struct controller *ctrl);
+ bool pciehp_check_link_active(struct controller *ctrl);
+ void pciehp_release_ctrl(struct controller *ctrl);
+diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
+index ccaf01e6eced..d24875102b1f 100644
+--- a/drivers/pci/hotplug/pciehp_core.c
++++ b/drivers/pci/hotplug/pciehp_core.c
+@@ -158,7 +158,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ struct pci_dev *pdev = slot->ctrl->pcie->port;
+
+ pci_config_pm_runtime_get(pdev);
+- pciehp_get_adapter_status(slot, value);
++ *value = pciehp_card_present_or_link_active(slot->ctrl);
+ pci_config_pm_runtime_put(pdev);
+ return 0;
+ }
+@@ -176,12 +176,12 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value)
+ static void pciehp_check_presence(struct controller *ctrl)
+ {
+ struct slot *slot = ctrl->slot;
+- u8 occupied;
++ bool occupied;
+
+ down_read(&ctrl->reset_lock);
+ mutex_lock(&slot->lock);
+
+- pciehp_get_adapter_status(slot, &occupied);
++ occupied = pciehp_card_present_or_link_active(ctrl);
+ if ((occupied && (slot->state == OFF_STATE ||
+ slot->state == BLINKINGON_STATE)) ||
+ (!occupied && (slot->state == ON_STATE ||
+diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c
+index c4d0f902f1d2..1fda6ea96fdc 100644
+--- a/drivers/pci/hotplug/pciehp_ctrl.c
++++ b/drivers/pci/hotplug/pciehp_ctrl.c
+@@ -223,8 +223,7 @@ void pciehp_handle_disable_request(struct slot *slot)
+ void pciehp_handle_presence_or_link_change(struct slot *slot, u32 events)
+ {
+ struct controller *ctrl = slot->ctrl;
+- bool link_active;
+- u8 present;
++ bool present, link_active;
+
+ /*
+ * If the slot is on and presence or link has changed, turn it off.
+@@ -253,7 +252,7 @@ void pciehp_handle_presence_or_link_change(struct slot *slot, u32 events)
+
+ /* Turn the slot on if it's occupied or link is up */
+ mutex_lock(&slot->lock);
+- pciehp_get_adapter_status(slot, &present);
++ present = pciehp_card_present(ctrl);
+ link_active = pciehp_check_link_active(ctrl);
+ if (!present && !link_active) {
+ mutex_unlock(&slot->lock);
+@@ -286,11 +285,6 @@ static int __pciehp_enable_slot(struct slot *p_slot)
+ u8 getstatus = 0;
+ struct controller *ctrl = p_slot->ctrl;
+
+- pciehp_get_adapter_status(p_slot, &getstatus);
+- if (!getstatus) {
+- ctrl_info(ctrl, "Slot(%s): No adapter\n", slot_name(p_slot));
+- return -ENODEV;
+- }
+ if (MRL_SENS(p_slot->ctrl)) {
+ pciehp_get_latch_status(p_slot, &getstatus);
+ if (getstatus) {
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
+index 93003ff81166..d6cd4fbc72da 100644
+--- a/drivers/pci/hotplug/pciehp_hpc.c
++++ b/drivers/pci/hotplug/pciehp_hpc.c
+@@ -389,13 +389,27 @@ void pciehp_get_latch_status(struct slot *slot, u8 *status)
+ *status = !!(slot_status & PCI_EXP_SLTSTA_MRLSS);
+ }
+
+-void pciehp_get_adapter_status(struct slot *slot, u8 *status)
++bool pciehp_card_present(struct controller *ctrl)
+ {
+- struct pci_dev *pdev = ctrl_dev(slot->ctrl);
++ struct pci_dev *pdev = ctrl_dev(ctrl);
+ u16 slot_status;
+
+ pcie_capability_read_word(pdev, PCI_EXP_SLTSTA, &slot_status);
+- *status = !!(slot_status & PCI_EXP_SLTSTA_PDS);
++ return slot_status & PCI_EXP_SLTSTA_PDS;
++}
++
++/**
++ * pciehp_card_present_or_link_active() - whether given slot is occupied
++ * @ctrl: PCIe hotplug controller
++ *
++ * Unlike pciehp_card_present(), which determines presence solely from the
++ * Presence Detect State bit, this helper also returns true if the Link Active
++ * bit is set. This is a concession to broken hotplug ports which hardwire
++ * Presence Detect State to zero, such as Wilocity's [1ae9:0200].
++ */
++bool pciehp_card_present_or_link_active(struct controller *ctrl)
++{
++ return pciehp_card_present(ctrl) || pciehp_check_link_active(ctrl);
+ }
+
+ int pciehp_query_power_fault(struct slot *slot)
+@@ -858,7 +872,7 @@ struct controller *pcie_init(struct pcie_device *dev)
+ {
+ struct controller *ctrl;
+ u32 slot_cap, link_cap;
+- u8 occupied, poweron;
++ u8 poweron;
+ struct pci_dev *pdev = dev->port;
+
+ ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL);
+@@ -918,9 +932,8 @@ struct controller *pcie_init(struct pcie_device *dev)
+ * requested yet, so avoid triggering a notification with this command.
+ */
+ if (POWER_CTRL(ctrl)) {
+- pciehp_get_adapter_status(ctrl->slot, &occupied);
+ pciehp_get_power_status(ctrl->slot, &poweron);
+- if (!occupied && poweron) {
++ if (!pciehp_card_present_or_link_active(ctrl) && poweron) {
+ pcie_disable_notification(ctrl);
+ pciehp_power_off_slot(ctrl->slot);
+ }
+--
+2.16.4
+
diff --git a/patches.fixes/0001-netfilter-nf_log-fix-uninit-read-in-nf_log_proc_dost.patch b/patches.fixes/0001-netfilter-nf_log-fix-uninit-read-in-nf_log_proc_dost.patch
new file mode 100644
index 0000000000..047cf3ba05
--- /dev/null
+++ b/patches.fixes/0001-netfilter-nf_log-fix-uninit-read-in-nf_log_proc_dost.patch
@@ -0,0 +1,37 @@
+From: Jann Horn <jannh@google.com>
+Subject: netfilter: nf_log: fix uninit read in
+ nf_log_proc_dostring
+Patch-mainline: v4.18-rc4
+Git-commit: dffd22aed2aa1e804bccf19b30a421e89ee2ae61
+References: git-fixes
+
+When proc_dostring() is called with a non-zero offset in strict mode, it
+doesn't just write to the ->data buffer, it also reads. Make sure it
+doesn't read uninitialized data.
+
+Fixes: c6ac37d8d884 ("netfilter: nf_log: fix error on write NONE to [...]")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/netfilter/nf_log.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
+index 8bb152a7cca4..91dad1afab05 100644
+--- a/net/netfilter/nf_log.c
++++ b/net/netfilter/nf_log.c
+@@ -440,6 +440,10 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,
+ if (write) {
+ struct ctl_table tmp = *table;
+
++ /* proc_dostring() can append to existing strings, so we need to
++ * initialize it as an empty string.
++ */
++ buf[0] = '\0';
+ tmp.data = buf;
+ r = proc_dostring(&tmp, write, buffer, lenp, ppos);
+ if (r)
+--
+2.12.3
+
diff --git a/patches.fixes/0001-netlink-fix-uninit-value-in-netlink_sendmsg.patch b/patches.fixes/0001-netlink-fix-uninit-value-in-netlink_sendmsg.patch
new file mode 100644
index 0000000000..b46b050f49
--- /dev/null
+++ b/patches.fixes/0001-netlink-fix-uninit-value-in-netlink_sendmsg.patch
@@ -0,0 +1,36 @@
+From: Eric Dumazet <edumazet@google.com>
+Subject: netlink: fix uninit-value in netlink_sendmsg
+Patch-mainline: v4.17-rc1
+Git-commit: 6091f09c2f79730d895149bcfe3d66140288cd0e
+References: git-fixes
+
+syzbot reported :
+
+BUG: KMSAN: uninit-value in ffs arch/x86/include/asm/bitops.h:432 [inline]
+BUG: KMSAN: uninit-value in netlink_sendmsg+0xb26/0x1310 net/netlink/af_netlink.c:1851
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/netlink/af_netlink.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 3e012d578ccd..70cf781ececb 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1812,6 +1812,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
+
+ if (msg->msg_namelen) {
+ err = -EINVAL;
++ if (msg->msg_namelen < sizeof(struct sockaddr_nl))
++ goto out;
+ if (addr->nl_family != AF_NETLINK)
+ goto out;
+ dst_portid = addr->nl_pid;
+--
+2.12.3
+
diff --git a/patches.fixes/0001-packet-fix-reserve-calculation.patch b/patches.fixes/0001-packet-fix-reserve-calculation.patch
new file mode 100644
index 0000000000..4031fe8608
--- /dev/null
+++ b/patches.fixes/0001-packet-fix-reserve-calculation.patch
@@ -0,0 +1,49 @@
+From: Willem de Bruijn <willemb@google.com>
+Subject: packet: fix reserve calculation
+Patch-mainline: v4.17-rc7
+Git-commit: 9aad13b087ab0a588cd68259de618f100053360e
+References: git-fixes
+
+
+Commit b84bbaf7a6c8 ("packet: in packet_snd start writing at link
+layer allocation") ensures that packet_snd always starts writing
+the link layer header in reserved headroom allocated for this
+purpose.
+
+This is needed because packets may be shorter than hard_header_len,
+in which case the space up to hard_header_len may be zeroed. But
+that necessary padding is not accounted for in skb->len.
+
+The fix, however, is buggy. It calls skb_push, which grows skb->len
+when moving skb->data back. But in this case packet length should not
+change.
+
+Instead, call skb_reserve, which moves both skb->data and skb->tail
+back, without changing length.
+
+Fixes: b84bbaf7a6c8 ("packet: in packet_snd start writing at link layer allocation")
+Reported-by: Tariq Toukan <tariqt@mellanox.com>
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/packet/af_packet.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 901618eb2725..9689622eaef7 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -2933,7 +2933,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
+ if (unlikely(offset < 0))
+ goto out_free;
+ } else if (reserve) {
+- skb_push(skb, reserve);
++ skb_reserve(skb, -reserve);
+ }
+
+ /* Returns -EFAULT on error */
+--
+2.12.3
+
diff --git a/patches.fixes/0001-tools-lib-traceevent-Fix-missing-equality-check-for-.patch b/patches.fixes/0001-tools-lib-traceevent-Fix-missing-equality-check-for-.patch
new file mode 100644
index 0000000000..9cbd9afd6c
--- /dev/null
+++ b/patches.fixes/0001-tools-lib-traceevent-Fix-missing-equality-check-for-.patch
@@ -0,0 +1,60 @@
+From f32c2877bcb068a718bb70094cd59ccc29d4d082 Mon Sep 17 00:00:00 2001
+From: Rikard Falkeborn <rikard.falkeborn@gmail.com>
+Date: Tue, 9 Apr 2019 11:15:29 +0200
+Subject: [PATCH] tools lib traceevent: Fix missing equality check for strcmp
+Git-commit: f32c2877bcb068a718bb70094cd59ccc29d4d082
+Patch-mainline: v5.1
+References: bsc#1129770
+
+There was a missing comparison with 0 when checking if type is "s64" or
+"u64". Therefore, the body of the if-statement was entered if "type" was
+"u64" or not "s64", which made the first strcmp() redundant since if
+type is "u64", it's not "s64".
+
+If type is "s64", the body of the if-statement is not entered but since
+the remainder of the function consists of if-statements which will not
+be entered if type is "s64", we will just return "val", which is
+correct, albeit at the cost of a few more calls to strcmp(), i.e., it
+will behave just as if the if-statement was entered.
+
+If type is neither "s64" or "u64", the body of the if-statement will be
+entered incorrectly and "val" returned. This means that any type that is
+checked after "s64" and "u64" is handled the same way as "s64" and
+"u64", i.e., the limiting of "val" to fit in for example "s8" is never
+reached.
+
+This was introduced in the kernel tree when the sources were copied from
+trace-cmd in commit f7d82350e597 ("tools/events: Add files to create
+libtraceevent.a"), and in the trace-cmd repo in 1cdbae6035cei
+("Implement typecasting in parser") when the function was introduced,
+i.e., it has always behaved the wrong way.
+
+Detected by cppcheck.
+
+Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com>
+Reviewed-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Cc: Tzvetomir Stoyanov <tstoyanov@vmware.com>
+Fixes: f7d82350e597 ("tools/events: Add files to create libtraceevent.a")
+Link: http://lkml.kernel.org/r/20190409091529.2686-1-rikard.falkeborn@gmail.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Reviewed-by: Fabian Baumanis <fabian.baumanis@suse.com>
+---
+ tools/lib/traceevent/event-parse.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
+index 87494c7c619d..981c6ce2da2c 100644
+--- a/tools/lib/traceevent/event-parse.c
++++ b/tools/lib/traceevent/event-parse.c
+@@ -2233,7 +2233,7 @@ eval_type_str(unsigned long long val, const char *type, int pointer)
+ return val & 0xffffffff;
+
+ if (strcmp(type, "u64") == 0 ||
+- strcmp(type, "s64"))
++ strcmp(type, "s64") == 0)
+ return val;
+
+ if (strcmp(type, "s8") == 0)
+--
+2.16.4
+
diff --git a/patches.fixes/0001-x86-speculation-mds-Fix-documentation-typo.patch b/patches.fixes/0001-x86-speculation-mds-Fix-documentation-typo.patch
new file mode 100644
index 0000000000..ad682831da
--- /dev/null
+++ b/patches.fixes/0001-x86-speculation-mds-Fix-documentation-typo.patch
@@ -0,0 +1,34 @@
+From 95310e348a321b45fb746c176961d4da72344282 Mon Sep 17 00:00:00 2001
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+Date: Tue, 7 May 2019 15:05:22 -0500
+Subject: [PATCH] x86/speculation/mds: Fix documentation typo
+Git-commit: 95310e348a321b45fb746c176961d4da72344282
+Patch-mainline: v5.2-rc1
+References: bsc#1135642
+
+Fix a minor typo in the MDS documentation: "eanbled" -> "enabled".
+
+Reported-by: Jeff Bastian <jbastian@redhat.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Fabian Baumanis <fabian.baumanis@suse.com>
+---
+ Documentation/x86/mds.rst | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Documentation/x86/mds.rst b/Documentation/x86/mds.rst
+index 979945be257a..534e9baa4e1d 100644
+--- a/Documentation/x86/mds.rst
++++ b/Documentation/x86/mds.rst
+@@ -116,7 +116,7 @@ Kernel internal mitigation modes
+ off Mitigation is disabled. Either the CPU is not affected or
+ mds=off is supplied on the kernel command line
+
+- full Mitigation is eanbled. CPU is affected and MD_CLEAR is
++ full Mitigation is enabled. CPU is affected and MD_CLEAR is
+ advertised in CPUID.
+
+ vmwerv Mitigation is enabled. CPU is affected and MD_CLEAR is not
+--
+2.16.4
+
diff --git a/patches.fixes/0002-net-fix-rtnh_ok.patch b/patches.fixes/0002-net-fix-rtnh_ok.patch
new file mode 100644
index 0000000000..ff95b40996
--- /dev/null
+++ b/patches.fixes/0002-net-fix-rtnh_ok.patch
@@ -0,0 +1,40 @@
+From: Eric Dumazet <edumazet@google.com>
+Subject: fix rtnh_ok()
+Patch-mainline: v4.17-rc1
+Git-commit: b1993a2de12c9e75c35729e2ffbc3a92d50c0d31
+References: git-fixes
+
+syzbot reported :
+
+BUG: KMSAN: uninit-value in rtnh_ok include/net/nexthop.h:11 [inline]
+BUG: KMSAN: uninit-value in fib_count_nexthops net/ipv4/fib_semantics.c:469 [inline]
+BUG: KMSAN: uninit-value in fib_create_info+0x554/0x8d20 net/ipv4/fib_semantics.c:1091
+
+@remaining is an integer, coming from user space.
+If it is negative we want rtnh_ok() to return false.
+
+Fixes: 4e902c57417c ("[IPv4]: FIB configuration using struct fib_config")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ include/net/nexthop.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/nexthop.h b/include/net/nexthop.h
+index 3334dbfa5aa4..7fc78663ec9d 100644
+--- a/include/net/nexthop.h
++++ b/include/net/nexthop.h
+@@ -6,7 +6,7 @@
+
+ static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining)
+ {
+- return remaining >= sizeof(*rtnh) &&
++ return remaining >= (int)sizeof(*rtnh) &&
+ rtnh->rtnh_len >= sizeof(*rtnh) &&
+ rtnh->rtnh_len <= remaining;
+ }
+--
+2.12.3
+
diff --git a/patches.fixes/0002-netfilter-nf_log-don-t-hold-nf_log_mutex-during-user.patch b/patches.fixes/0002-netfilter-nf_log-don-t-hold-nf_log_mutex-during-user.patch
new file mode 100644
index 0000000000..7a3835aa28
--- /dev/null
+++ b/patches.fixes/0002-netfilter-nf_log-don-t-hold-nf_log_mutex-during-user.patch
@@ -0,0 +1,52 @@
+From: Jann Horn <jannh@google.com>
+Subject: netfilter: nf_log: don't hold nf_log_mutex during user
+ access
+Patch-mainline: v4.18-rc4
+Git-commit: ce00bf07cc95a57cd20b208e02b3c2604e532ae8
+References: git-fixes
+
+
+The old code would indefinitely block other users of nf_log_mutex if
+a userspace access in proc_dostring() blocked e.g. due to a userfaultfd
+region. Fix it by moving proc_dostring() out of the locked region.
+
+This is a followup to commit 266d07cb1c9a ("netfilter: nf_log: fix
+sleeping function called from invalid context"), which changed this code
+from using rcu_read_lock() to taking nf_log_mutex.
+
+Fixes: 266d07cb1c9a ("netfilter: nf_log: fix sleeping function calle[...]")
+Signed-off-by: Jann Horn <jannh@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/netfilter/nf_log.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
+index 91dad1afab05..cdc744aa5889 100644
+--- a/net/netfilter/nf_log.c
++++ b/net/netfilter/nf_log.c
+@@ -462,14 +462,17 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,
+ rcu_assign_pointer(net->nf.nf_loggers[tindex], logger);
+ mutex_unlock(&nf_log_mutex);
+ } else {
++ struct ctl_table tmp = *table;
++
++ tmp.data = buf;
+ mutex_lock(&nf_log_mutex);
+ logger = nft_log_dereference(net->nf.nf_loggers[tindex]);
+ if (!logger)
+- table->data = "NONE";
++ strlcpy(buf, "NONE", sizeof(buf));
+ else
+- table->data = logger->name;
+- r = proc_dostring(table, write, buffer, lenp, ppos);
++ strlcpy(buf, logger->name, sizeof(buf));
+ mutex_unlock(&nf_log_mutex);
++ r = proc_dostring(&tmp, write, buffer, lenp, ppos);
+ }
+
+ return r;
+--
+2.12.3
+
diff --git a/patches.fixes/0002-packet-reset-network-header-if-packet-shorter-than-l.patch b/patches.fixes/0002-packet-reset-network-header-if-packet-shorter-than-l.patch
new file mode 100644
index 0000000000..a826f3d726
--- /dev/null
+++ b/patches.fixes/0002-packet-reset-network-header-if-packet-shorter-than-l.patch
@@ -0,0 +1,37 @@
+From: Willem de Bruijn <willemb@google.com>
+Subject: packet: reset network header if packet shorter than ll
+ reserved space
+Patch-mainline: v4.18-rc6
+Git-commit: 993675a3100b16a4c80dfd70cbcde8ea7127b31d
+References: git-fixes
+
+If variable length link layer headers result in a packet shorter
+than dev->hard_header_len, reset the network header offset. Else
+skb->mac_len may exceed skb->len after skb_mac_reset_len.
+
+packet_sendmsg_spkt already has similar logic.
+
+Fixes: b84bbaf7a6c8 ("packet: in packet_snd start writing at link layer allocation")
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/packet/af_packet.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 9689622eaef7..cf7652bb2218 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -2934,6 +2934,8 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
+ goto out_free;
+ } else if (reserve) {
+ skb_reserve(skb, -reserve);
++ if (len < reserve)
++ skb_reset_network_header(skb);
+ }
+
+ /* Returns -EFAULT on error */
+--
+2.12.3
+
diff --git a/patches.fixes/0003-l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_io.patch b/patches.fixes/0003-l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_io.patch
new file mode 100644
index 0000000000..fbe8993bb3
--- /dev/null
+++ b/patches.fixes/0003-l2tp-fix-missing-refcount-drop-in-pppol2tp_tunnel_io.patch
@@ -0,0 +1,48 @@
+From: Guillaume Nault <g.nault@alphalink.fr>
+Subject: l2tp: fix missing refcount drop in
+ pppol2tp_tunnel_ioctl()
+Patch-mainline: v4.18-rc8
+Git-commit: f664e37dcc525768280cb94321424a09beb1c992
+References: git-fixes
+
+If 'session' is not NULL and is not a PPP pseudo-wire, then we fail to
+drop the reference taken by l2tp_session_get().
+
+Fixes: ecd012e45ab5 ("l2tp: filter out non-PPP sessions in pppol2tp_tunnel_ioctl()")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/l2tp/l2tp_ppp.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
+index 3cd4cce8338c..93d4c72e4ee5 100644
+--- a/net/l2tp/l2tp_ppp.c
++++ b/net/l2tp/l2tp_ppp.c
+@@ -1214,13 +1214,18 @@ static int pppol2tp_tunnel_ioctl(struct l2tp_tunnel *tunnel,
+ l2tp_session_get(sock_net(sk), tunnel,
+ stats.session_id);
+
+- if (session && session->pwtype == L2TP_PWTYPE_PPP) {
+- err = pppol2tp_session_ioctl(session, cmd,
+- arg);
++ if (!session) {
++ err = -EBADR;
++ break;
++ }
++ if (session->pwtype != L2TP_PWTYPE_PPP) {
+ l2tp_session_dec_refcount(session);
+- } else {
+ err = -EBADR;
++ break;
+ }
++
++ err = pppol2tp_session_ioctl(session, cmd, arg);
++ l2tp_session_dec_refcount(session);
+ break;
+ }
+ #ifdef CONFIG_XFRM
+--
+2.12.3
+
diff --git a/patches.fixes/0003-net-initialize-skb-peeked-when-cloning.patch b/patches.fixes/0003-net-initialize-skb-peeked-when-cloning.patch
new file mode 100644
index 0000000000..9f11b92b6c
--- /dev/null
+++ b/patches.fixes/0003-net-initialize-skb-peeked-when-cloning.patch
@@ -0,0 +1,35 @@
+From: Eric Dumazet <edumazet@google.com>
+Subject: net: initialize skb->peeked when cloning
+Patch-mainline: v4.17-rc1
+Git-commit: b13dda9f9aa7caceeee61c080c2e544d5f5d85e5
+References: git-fixes
+
+syzbot reported __skb_try_recv_from_queue() was using skb->peeked
+while it was potentially unitialized.
+
+We need to clear it in __skb_clone()
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/core/skbuff.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 4fd1eec0b79f..c160048283bc 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -896,6 +896,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
+ n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
+ n->cloned = 1;
+ n->nohdr = 0;
++ n->peeked = 0;
+ n->destructor = NULL;
+ C(tail);
+ C(end);
+--
+2.12.3
+
diff --git a/patches.fixes/0003-xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch b/patches.fixes/0003-xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch
new file mode 100644
index 0000000000..b84a27b9a0
--- /dev/null
+++ b/patches.fixes/0003-xfrm_user-prevent-leaking-2-bytes-of-kernel-memory.patch
@@ -0,0 +1,116 @@
+From: Eric Dumazet <edumazet@google.com>
+Subject: xfrm_user: prevent leaking 2 bytes of kernel memory
+Patch-mainline: v4.18-rc8
+Git-commit: 45c180bc29babbedd6b8c01b975780ef44d9d09c
+References: git-fixes
+
+struct xfrm_userpolicy_type has two holes, so we should not
+use C99 style initializer.
+
+KMSAN report:
+
+BUG: KMSAN: kernel-infoleak in copyout lib/iov_iter.c:140 [inline]
+BUG: KMSAN: kernel-infoleak in _copy_to_iter+0x1b14/0x2800 lib/iov_iter.c:571
+CPU: 1 PID: 4520 Comm: syz-executor841 Not tainted 4.17.0+ #5
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x185/0x1d0 lib/dump_stack.c:113
+ kmsan_report+0x188/0x2a0 mm/kmsan/kmsan.c:1117
+ kmsan_internal_check_memory+0x138/0x1f0 mm/kmsan/kmsan.c:1211
+ kmsan_copy_to_user+0x7a/0x160 mm/kmsan/kmsan.c:1253
+ copyout lib/iov_iter.c:140 [inline]
+ _copy_to_iter+0x1b14/0x2800 lib/iov_iter.c:571
+ copy_to_iter include/linux/uio.h:106 [inline]
+ skb_copy_datagram_iter+0x422/0xfa0 net/core/datagram.c:431
+ skb_copy_datagram_msg include/linux/skbuff.h:3268 [inline]
+ netlink_recvmsg+0x6f1/0x1900 net/netlink/af_netlink.c:1959
+ sock_recvmsg_nosec net/socket.c:802 [inline]
+ sock_recvmsg+0x1d6/0x230 net/socket.c:809
+ ___sys_recvmsg+0x3fe/0x810 net/socket.c:2279
+ __sys_recvmmsg+0x58e/0xe30 net/socket.c:2391
+ do_sys_recvmmsg+0x2a6/0x3e0 net/socket.c:2472
+ __do_sys_recvmmsg net/socket.c:2485 [inline]
+ __se_sys_recvmmsg net/socket.c:2481 [inline]
+ __x64_sys_recvmmsg+0x15d/0x1c0 net/socket.c:2481
+ do_syscall_64+0x15b/0x230 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+RIP: 0033:0x446ce9
+RSP: 002b:00007fc307918db8 EFLAGS: 00000293 ORIG_RAX: 000000000000012b
+RAX: ffffffffffffffda RBX: 00000000006dbc24 RCX: 0000000000446ce9
+RDX: 000000000000000a RSI: 0000000020005040 RDI: 0000000000000003
+RBP: 00000000006dbc20 R08: 0000000020004e40 R09: 0000000000000000
+R10: 0000000040000000 R11: 0000000000000293 R12: 0000000000000000
+R13: 00007ffc8d2df32f R14: 00007fc3079199c0 R15: 0000000000000001
+
+Uninit was stored to memory at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:279 [inline]
+ kmsan_save_stack mm/kmsan/kmsan.c:294 [inline]
+ kmsan_internal_chain_origin+0x12b/0x210 mm/kmsan/kmsan.c:685
+ kmsan_memcpy_origins+0x11d/0x170 mm/kmsan/kmsan.c:527
+ __msan_memcpy+0x109/0x160 mm/kmsan/kmsan_instr.c:413
+ __nla_put lib/nlattr.c:569 [inline]
+ nla_put+0x276/0x340 lib/nlattr.c:627
+ copy_to_user_policy_type net/xfrm/xfrm_user.c:1678 [inline]
+ dump_one_policy+0xbe1/0x1090 net/xfrm/xfrm_user.c:1708
+ xfrm_policy_walk+0x45a/0xd00 net/xfrm/xfrm_policy.c:1013
+ xfrm_dump_policy+0x1c0/0x2a0 net/xfrm/xfrm_user.c:1749
+ netlink_dump+0x9b5/0x1550 net/netlink/af_netlink.c:2226
+ __netlink_dump_start+0x1131/0x1270 net/netlink/af_netlink.c:2323
+ netlink_dump_start include/linux/netlink.h:214 [inline]
+ xfrm_user_rcv_msg+0x8a3/0x9b0 net/xfrm/xfrm_user.c:2577
+ netlink_rcv_skb+0x37e/0x600 net/netlink/af_netlink.c:2448
+ xfrm_netlink_rcv+0xb2/0xf0 net/xfrm/xfrm_user.c:2598
+ netlink_unicast_kernel net/netlink/af_netlink.c:1310 [inline]
+ netlink_unicast+0x1680/0x1750 net/netlink/af_netlink.c:1336
+ netlink_sendmsg+0x104f/0x1350 net/netlink/af_netlink.c:1901
+ sock_sendmsg_nosec net/socket.c:629 [inline]
+ sock_sendmsg net/socket.c:639 [inline]
+ ___sys_sendmsg+0xec8/0x1320 net/socket.c:2117
+ __sys_sendmsg net/socket.c:2155 [inline]
+ __do_sys_sendmsg net/socket.c:2164 [inline]
+ __se_sys_sendmsg net/socket.c:2162 [inline]
+ __x64_sys_sendmsg+0x331/0x460 net/socket.c:2162
+ do_syscall_64+0x15b/0x230 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+Local variable description: ----upt.i@dump_one_policy
+Variable was created at:
+ dump_one_policy+0x78/0x1090 net/xfrm/xfrm_user.c:1689
+ xfrm_policy_walk+0x45a/0xd00 net/xfrm/xfrm_policy.c:1013
+
+Byte 130 of 137 is uninitialized
+Memory access starts at ffff88019550407f
+
+Fixes: c0144beaeca42 ("[XFRM] netlink: Use nla_put()/NLA_PUT() variantes")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/xfrm/xfrm_user.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
+index e2287bc70691..5e8f4f3fbe6b 100644
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -1642,9 +1642,11 @@ static inline size_t userpolicy_type_attrsize(void)
+ #ifdef CONFIG_XFRM_SUB_POLICY
+ static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
+ {
+- struct xfrm_userpolicy_type upt = {
+- .type = type,
+- };
++ struct xfrm_userpolicy_type upt;
++
++ /* Sadly there are two holes in struct xfrm_userpolicy_type */
++ memset(&upt, 0, sizeof(upt));
++ upt.type = type;
+
+ return nla_put(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
+ }
+--
+2.12.3
+
diff --git a/patches.fixes/0004-net-fix-uninit-value-in-__hw_addr_add_ex.patch b/patches.fixes/0004-net-fix-uninit-value-in-__hw_addr_add_ex.patch
new file mode 100644
index 0000000000..61ccd449bc
--- /dev/null
+++ b/patches.fixes/0004-net-fix-uninit-value-in-__hw_addr_add_ex.patch
@@ -0,0 +1,57 @@
+From: Eric Dumazet <edumazet@google.com>
+Subject: net: fix uninit-value in __hw_addr_add_ex()
+Patch-mainline: v4.17-rc1
+Git-commit: 77d36398d99f2565c0a8d43a86fd520a82e64bb8
+References: git-fixes
+
+syzbot complained :
+
+BUG: KMSAN: uninit-value in memcmp+0x119/0x180 lib/string.c:861
+CPU: 0 PID: 3 Comm: kworker/0:0 Not tainted 4.16.0+ #82
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Workqueue: ipv6_addrconf addrconf_dad_work
+Call Trace:
+ __dump_stack lib/dump_stack.c:17 [inline]
+ dump_stack+0x185/0x1d0 lib/dump_stack.c:53
+ kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067
+ __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676
+ memcmp+0x119/0x180 lib/string.c:861
+ __hw_addr_add_ex net/core/dev_addr_lists.c:60 [inline]
+ __dev_mc_add+0x1c2/0x8e0 net/core/dev_addr_lists.c:670
+ dev_mc_add+0x6d/0x80 net/core/dev_addr_lists.c:687
+ igmp6_group_added+0x2db/0xa00 net/ipv6/mcast.c:662
+ ipv6_dev_mc_inc+0xe9e/0x1130 net/ipv6/mcast.c:914
+ addrconf_join_solict net/ipv6/addrconf.c:2078 [inline]
+ addrconf_dad_begin net/ipv6/addrconf.c:3828 [inline]
+ addrconf_dad_work+0x427/0x2150 net/ipv6/addrconf.c:3954
+ process_one_work+0x12c6/0x1f60 kernel/workqueue.c:2113
+ worker_thread+0x113c/0x24f0 kernel/workqueue.c:2247
+ kthread+0x539/0x720 kernel/kthread.c:239
+
+Fixes: f001fde5eadd ("net: introduce a list of device addresses dev_addr_list (v6)")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/core/dev_addr_lists.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c
+index c0548d268e1a..e3e6a3e2ca22 100644
+--- a/net/core/dev_addr_lists.c
++++ b/net/core/dev_addr_lists.c
+@@ -57,8 +57,8 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
+ return -EINVAL;
+
+ list_for_each_entry(ha, &list->list, list) {
+- if (!memcmp(ha->addr, addr, addr_len) &&
+- ha->type == addr_type) {
++ if (ha->type == addr_type &&
++ !memcmp(ha->addr, addr, addr_len)) {
+ if (global) {
+ /* check if addr is already used as global */
+ if (ha->global_use)
+--
+2.12.3
+
diff --git a/patches.fixes/0004-rxrpc-Fix-transport-sockopts-to-get-IPv4-errors-on-a.patch b/patches.fixes/0004-rxrpc-Fix-transport-sockopts-to-get-IPv4-errors-on-a.patch
new file mode 100644
index 0000000000..b3b9fdbd1c
--- /dev/null
+++ b/patches.fixes/0004-rxrpc-Fix-transport-sockopts-to-get-IPv4-errors-on-a.patch
@@ -0,0 +1,82 @@
+From: David Howells <dhowells@redhat.com>
+Subject: rxrpc: Fix transport sockopts to get IPv4 errors on an
+ IPv6 socket
+Patch-mainline: v4.19-rc7
+Git-commit: 37a675e768d7606fe8a53e0c459c9b53e121ac20
+References: git-fixes
+
+It seems that enabling IPV6_RECVERR on an IPv6 socket doesn't also turn on
+IP_RECVERR, so neither local errors nor ICMP-transported remote errors from
+IPv4 peer addresses are returned to the AF_RXRPC protocol.
+
+Make the sockopt setting code in rxrpc_open_socket() fall through from the
+AF_INET6 case to the AF_INET case to turn on all the AF_INET options too in
+the AF_INET6 case.
+
+Fixes: f2aeed3a591f ("rxrpc: Fix error reception on AF_INET6 sockets")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/rxrpc/local_object.c | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
+index adc49d8285bf..852a036c775e 100644
+--- a/net/rxrpc/local_object.c
++++ b/net/rxrpc/local_object.c
+@@ -134,10 +134,10 @@ static int rxrpc_open_socket(struct rxrpc_local *local)
+ }
+
+ switch (local->srx.transport.family) {
+- case AF_INET:
+- /* we want to receive ICMP errors */
++ case AF_INET6:
++ /* we want to receive ICMPv6 errors */
+ opt = 1;
+- ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
++ ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
+ (char *) &opt, sizeof(opt));
+ if (ret < 0) {
+ _debug("setsockopt failed");
+@@ -145,19 +145,22 @@ static int rxrpc_open_socket(struct rxrpc_local *local)
+ }
+
+ /* we want to set the don't fragment bit */
+- opt = IP_PMTUDISC_DO;
+- ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
++ opt = IPV6_PMTUDISC_DO;
++ ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
+ (char *) &opt, sizeof(opt));
+ if (ret < 0) {
+ _debug("setsockopt failed");
+ goto error;
+ }
+- break;
+
+- case AF_INET6:
++ /* Fall through and set IPv4 options too otherwise we don't get
++ * errors from IPv4 packets sent through the IPv6 socket.
++ */
++
++ case AF_INET:
+ /* we want to receive ICMP errors */
+ opt = 1;
+- ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
++ ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
+ (char *) &opt, sizeof(opt));
+ if (ret < 0) {
+ _debug("setsockopt failed");
+@@ -165,8 +168,8 @@ static int rxrpc_open_socket(struct rxrpc_local *local)
+ }
+
+ /* we want to set the don't fragment bit */
+- opt = IPV6_PMTUDISC_DO;
+- ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
++ opt = IP_PMTUDISC_DO;
++ ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
+ (char *) &opt, sizeof(opt));
+ if (ret < 0) {
+ _debug("setsockopt failed");
+--
+2.12.3
+
diff --git a/patches.fixes/0004-xfrm-fix-missing-dst_release-after-policy-blocking-l.patch b/patches.fixes/0004-xfrm-fix-missing-dst_release-after-policy-blocking-l.patch
new file mode 100644
index 0000000000..1b96095957
--- /dev/null
+++ b/patches.fixes/0004-xfrm-fix-missing-dst_release-after-policy-blocking-l.patch
@@ -0,0 +1,70 @@
+From: Tommi Rantala <tommi.t.rantala@nokia.com>
+Subject: xfrm: fix missing dst_release() after policy blocking
+ lbcast and multicast
+Patch-mainline: v4.18-rc8
+Git-commit: 8cc88773855f988d6a3bbf102bbd9dd9c828eb81
+References: git-fixes
+
+
+Fix missing dst_release() when local broadcast or multicast traffic is
+xfrm policy blocked.
+
+For IPv4 this results to dst leak: ip_route_output_flow() allocates
+dst_entry via __ip_route_output_key() and passes it to
+xfrm_lookup_route(). xfrm_lookup returns ERR_PTR(-EPERM) that is
+propagated. The dst that was allocated is never released.
+
+IPv4 local broadcast testcase:
+ ping -b 192.168.1.255 &
+ sleep 1
+ ip xfrm policy add src 0.0.0.0/0 dst 192.168.1.255/32 dir out action block
+
+IPv4 multicast testcase:
+ ping 224.0.0.1 &
+ sleep 1
+ ip xfrm policy add src 0.0.0.0/0 dst 224.0.0.1/32 dir out action block
+
+For IPv6 the missing dst_release() causes trouble e.g. when used in netns:
+ ip netns add TEST
+ ip netns exec TEST ip link set lo up
+ ip link add dummy0 type dummy
+ ip link set dev dummy0 netns TEST
+ ip netns exec TEST ip addr add fd00::1111 dev dummy0
+ ip netns exec TEST ip link set dummy0 up
+ ip netns exec TEST ping -6 -c 5 ff02::1%dummy0 &
+ sleep 1
+ ip netns exec TEST ip xfrm policy add src ::/0 dst ff02::1 dir out action block
+ wait
+ ip netns del TEST
+
+After netns deletion we see:
+[ 258.239097] unregister_netdevice: waiting for lo to become free. Usage count = 2
+[ 268.279061] unregister_netdevice: waiting for lo to become free. Usage count = 2
+[ 278.367018] unregister_netdevice: waiting for lo to become free. Usage count = 2
+[ 288.375259] unregister_netdevice: waiting for lo to become free. Usage count = 2
+
+Fixes: ac37e2515c1a ("xfrm: release dst_orig in case of error in xfrm_lookup()")
+Signed-off-by: Tommi Rantala <tommi.t.rantala@nokia.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/xfrm/xfrm_policy.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index 736bddd6bf0d..e86a65292879 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -2350,6 +2350,9 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
+ if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE)
+ return make_blackhole(net, dst_orig->ops->family, dst_orig);
+
++ if (IS_ERR(dst))
++ dst_release(dst_orig);
++
+ return dst;
+ }
+ EXPORT_SYMBOL(xfrm_lookup_route);
+--
+2.12.3
+
diff --git a/patches.fixes/0005-inetpeer-fix-uninit-value-in-inet_getpeer.patch b/patches.fixes/0005-inetpeer-fix-uninit-value-in-inet_getpeer.patch
new file mode 100644
index 0000000000..1a25b0ee0f
--- /dev/null
+++ b/patches.fixes/0005-inetpeer-fix-uninit-value-in-inet_getpeer.patch
@@ -0,0 +1,119 @@
+From: Eric Dumazet <edumazet@google.com>
+Subject: inetpeer: fix uninit-value in inet_getpeer
+Patch-mainline: v4.17-rc1
+Git-commit: b6a37e5e25414df4b8e9140a5c6f5ee0ec6f3b90
+References: git-fixes
+
+syzbot/KMSAN reported that p->dtime was read while it was
+not yet initialized in :
+
+ delta = (__u32)jiffies - p->dtime;
+ if (delta < ttl || !refcount_dec_if_one(&p->refcnt))
+ gc_stack[i] = NULL;
+
+This is a false positive, because the inetpeer wont be erased
+from rb-tree if the refcount_dec_if_one(&p->refcnt) does not
+succeed. And this wont happen before first inet_putpeer() call
+for this inetpeer has been done, and ->dtime field is written
+exactly before the refcount_dec_and_test(&p->refcnt).
+
+The KMSAN report was :
+
+BUG: KMSAN: uninit-value in inet_peer_gc net/ipv4/inetpeer.c:163 [inline]
+BUG: KMSAN: uninit-value in inet_getpeer+0x1567/0x1e70 net/ipv4/inetpeer.c:228
+CPU: 0 PID: 9494 Comm: syz-executor5 Not tainted 4.16.0+ #82
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:17 [inline]
+ dump_stack+0x185/0x1d0 lib/dump_stack.c:53
+ kmsan_report+0x142/0x240 mm/kmsan/kmsan.c:1067
+ __msan_warning_32+0x6c/0xb0 mm/kmsan/kmsan_instr.c:676
+ inet_peer_gc net/ipv4/inetpeer.c:163 [inline]
+ inet_getpeer+0x1567/0x1e70 net/ipv4/inetpeer.c:228
+ inet_getpeer_v4 include/net/inetpeer.h:110 [inline]
+ icmpv4_xrlim_allow net/ipv4/icmp.c:330 [inline]
+ icmp_send+0x2b44/0x3050 net/ipv4/icmp.c:725
+ ip_options_compile+0x237c/0x29f0 net/ipv4/ip_options.c:472
+ ip_rcv_options net/ipv4/ip_input.c:284 [inline]
+ ip_rcv_finish+0xda8/0x16d0 net/ipv4/ip_input.c:365
+ NF_HOOK include/linux/netfilter.h:288 [inline]
+ ip_rcv+0x119d/0x16f0 net/ipv4/ip_input.c:493
+ __netif_receive_skb_core+0x47cf/0x4a80 net/core/dev.c:4562
+ __netif_receive_skb net/core/dev.c:4627 [inline]
+ netif_receive_skb_internal+0x49d/0x630 net/core/dev.c:4701
+ netif_receive_skb+0x230/0x240 net/core/dev.c:4725
+ tun_rx_batched drivers/net/tun.c:1555 [inline]
+ tun_get_user+0x6d88/0x7580 drivers/net/tun.c:1962
+ tun_chr_write_iter+0x1d4/0x330 drivers/net/tun.c:1990
+ do_iter_readv_writev+0x7bb/0x970 include/linux/fs.h:1776
+ do_iter_write+0x30d/0xd40 fs/read_write.c:932
+ vfs_writev fs/read_write.c:977 [inline]
+ do_writev+0x3c9/0x830 fs/read_write.c:1012
+ SYSC_writev+0x9b/0xb0 fs/read_write.c:1085
+ SyS_writev+0x56/0x80 fs/read_write.c:1082
+ do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x3d/0xa2
+RIP: 0033:0x455111
+RSP: 002b:00007fae0365cba0 EFLAGS: 00000293 ORIG_RAX: 0000000000000014
+RAX: ffffffffffffffda RBX: 000000000000002e RCX: 0000000000455111
+RDX: 0000000000000001 RSI: 00007fae0365cbf0 RDI: 00000000000000fc
+RBP: 0000000020000040 R08: 00000000000000fc R09: 0000000000000000
+R10: 000000000000002e R11: 0000000000000293 R12: 00000000ffffffff
+R13: 0000000000000658 R14: 00000000006fc8e0 R15: 0000000000000000
+
+Uninit was created at:
+ kmsan_save_stack_with_flags mm/kmsan/kmsan.c:278 [inline]
+ kmsan_internal_poison_shadow+0xb8/0x1b0 mm/kmsan/kmsan.c:188
+ kmsan_kmalloc+0x94/0x100 mm/kmsan/kmsan.c:314
+ kmem_cache_alloc+0xaab/0xb90 mm/slub.c:2756
+ inet_getpeer+0xed8/0x1e70 net/ipv4/inetpeer.c:210
+ inet_getpeer_v4 include/net/inetpeer.h:110 [inline]
+ ip4_frag_init+0x4d1/0x740 net/ipv4/ip_fragment.c:153
+ inet_frag_alloc net/ipv4/inet_fragment.c:369 [inline]
+ inet_frag_create net/ipv4/inet_fragment.c:385 [inline]
+ inet_frag_find+0x7da/0x1610 net/ipv4/inet_fragment.c:418
+ ip_find net/ipv4/ip_fragment.c:275 [inline]
+ ip_defrag+0x448/0x67a0 net/ipv4/ip_fragment.c:676
+ ip_check_defrag+0x775/0xda0 net/ipv4/ip_fragment.c:724
+ packet_rcv_fanout+0x2a8/0x8d0 net/packet/af_packet.c:1447
+ deliver_skb net/core/dev.c:1897 [inline]
+ deliver_ptype_list_skb net/core/dev.c:1912 [inline]
+ __netif_receive_skb_core+0x314a/0x4a80 net/core/dev.c:4545
+ __netif_receive_skb net/core/dev.c:4627 [inline]
+ netif_receive_skb_internal+0x49d/0x630 net/core/dev.c:4701
+ netif_receive_skb+0x230/0x240 net/core/dev.c:4725
+ tun_rx_batched drivers/net/tun.c:1555 [inline]
+ tun_get_user+0x6d88/0x7580 drivers/net/tun.c:1962
+ tun_chr_write_iter+0x1d4/0x330 drivers/net/tun.c:1990
+ do_iter_readv_writev+0x7bb/0x970 include/linux/fs.h:1776
+ do_iter_write+0x30d/0xd40 fs/read_write.c:932
+ vfs_writev fs/read_write.c:977 [inline]
+ do_writev+0x3c9/0x830 fs/read_write.c:1012
+ SYSC_writev+0x9b/0xb0 fs/read_write.c:1085
+ SyS_writev+0x56/0x80 fs/read_write.c:1082
+ do_syscall_64+0x309/0x430 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x3d/0xa2
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv4/inetpeer.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
+index b20c8ac64081..64007ce87273 100644
+--- a/net/ipv4/inetpeer.c
++++ b/net/ipv4/inetpeer.c
+@@ -210,6 +210,7 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base,
+ p = kmem_cache_alloc(peer_cachep, GFP_ATOMIC);
+ if (p) {
+ p->daddr = *daddr;
++ p->dtime = (__u32)jiffies;
+ refcount_set(&p->refcnt, 2);
+ atomic_set(&p->rid, 0);
+ p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW;
+--
+2.12.3
+
diff --git a/patches.fixes/0005-net-socket-fix-potential-spectre-v1-gadget-in-socket.patch b/patches.fixes/0005-net-socket-fix-potential-spectre-v1-gadget-in-socket.patch
new file mode 100644
index 0000000000..1e08c72521
--- /dev/null
+++ b/patches.fixes/0005-net-socket-fix-potential-spectre-v1-gadget-in-socket.patch
@@ -0,0 +1,47 @@
+From: Jeremy Cline <jcline@redhat.com>
+Subject: net: socket: fix potential spectre v1 gadget in
+ socketcall
+Patch-mainline: v4.18-rc8
+Git-commit: c8e8cd579bb4265651df8223730105341e61a2d1
+References: git-fixes
+
+'call' is a user-controlled value, so sanitize the array index after the
+bounds check to avoid speculating past the bounds of the 'nargs' array.
+
+Found with the help of Smatch:
+
+net/socket.c:2508 __do_sys_socketcall() warn: potential spectre issue
+'nargs' [r] (local cap)
+
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeremy Cline <jcline@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/socket.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/net/socket.c b/net/socket.c
+index 24bb6684bdda..6a0427b79727 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -89,6 +89,7 @@
+ #include <linux/magic.h>
+ #include <linux/slab.h>
+ #include <linux/xattr.h>
++#include <linux/nospec.h>
+
+ #include <linux/uaccess.h>
+ #include <asm/unistd.h>
+@@ -2433,6 +2434,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
+
+ if (call < 1 || call > SYS_SENDMMSG)
+ return -EINVAL;
++ call = array_index_nospec(call, SYS_SENDMMSG + 1);
+
+ len = nargs[call];
+ if (len > sizeof(a))
+--
+2.12.3
+
diff --git a/patches.fixes/0006-ipvs-fix-rtnl_lock-lockups-caused-by-start_sync_thre.patch b/patches.fixes/0006-ipvs-fix-rtnl_lock-lockups-caused-by-start_sync_thre.patch
new file mode 100644
index 0000000000..a3796b4c6b
--- /dev/null
+++ b/patches.fixes/0006-ipvs-fix-rtnl_lock-lockups-caused-by-start_sync_thre.patch
@@ -0,0 +1,641 @@
+From: Julian Anastasov <ja@ssi.bg>
+Subject: ipvs: fix rtnl_lock lockups caused by start_sync_thread
+Patch-mainline: v4.17-rc3
+Git-commit: 5c64576a77894a50be80be0024bed27171b55989
+References: git-fixes
+
+syzkaller reports for wrong rtnl_lock usage in sync code [1] and [2]
+
+We have 2 problems in start_sync_thread if error path is
+taken, eg. on memory allocation error or failure to configure
+sockets for mcast group or addr/port binding:
+
+1. recursive locking: holding rtnl_lock while calling sock_release
+which in turn calls again rtnl_lock in ip_mc_drop_socket to leave
+the mcast group, as noticed by Florian Westphal. Additionally,
+sock_release can not be called while holding sync_mutex (ABBA
+deadlock).
+
+2. task hung: holding rtnl_lock while calling kthread_stop to
+stop the running kthreads. As the kthreads do the same to leave
+the mcast group (sock_release -> ip_mc_drop_socket -> rtnl_lock)
+they hang.
+
+Fix the problems by calling rtnl_unlock early in the error path,
+now sock_release is called after unlocking both mutexes.
+
+Problem 3 (task hung reported by syzkaller [2]) is variant of
+problem 2: use _trylock to prevent one user to call rtnl_lock and
+then while waiting for sync_mutex to block kthreads that execute
+sock_release when they are stopped by stop_sync_thread.
+
+[1]
+IPVS: stopping backup sync thread 4500 ...
+WARNING: possible recursive locking detected
+4.16.0-rc7+ #3 Not tainted
+--------------------------------------------
+syzkaller688027/4497 is trying to acquire lock:
+ (rtnl_mutex){+.+.}, at: [<00000000bb14d7fb>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+
+but task is already holding lock:
+IPVS: stopping backup sync thread 4495 ...
+ (rtnl_mutex){+.+.}, at: [<00000000bb14d7fb>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+
+other info that might help us debug this:
+ Possible unsafe locking scenario:
+
+ CPU0
+ ----
+ lock(rtnl_mutex);
+ lock(rtnl_mutex);
+
+ *** DEADLOCK ***
+
+ May be due to missing lock nesting notation
+
+2 locks held by syzkaller688027/4497:
+ #0: (rtnl_mutex){+.+.}, at: [<00000000bb14d7fb>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+ #1: (ipvs->sync_mutex){+.+.}, at: [<00000000703f78e3>]
+do_ip_vs_set_ctl+0x10f8/0x1cc0 net/netfilter/ipvs/ip_vs_ctl.c:2388
+
+stack backtrace:
+CPU: 1 PID: 4497 Comm: syzkaller688027 Not tainted 4.16.0-rc7+ #3
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
+Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:17 [inline]
+ dump_stack+0x194/0x24d lib/dump_stack.c:53
+ print_deadlock_bug kernel/locking/lockdep.c:1761 [inline]
+ check_deadlock kernel/locking/lockdep.c:1805 [inline]
+ validate_chain kernel/locking/lockdep.c:2401 [inline]
+ __lock_acquire+0xe8f/0x3e00 kernel/locking/lockdep.c:3431
+ lock_acquire+0x1d5/0x580 kernel/locking/lockdep.c:3920
+ __mutex_lock_common kernel/locking/mutex.c:756 [inline]
+ __mutex_lock+0x16f/0x1a80 kernel/locking/mutex.c:893
+ mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:908
+ rtnl_lock+0x17/0x20 net/core/rtnetlink.c:74
+ ip_mc_drop_socket+0x88/0x230 net/ipv4/igmp.c:2643
+ inet_release+0x4e/0x1c0 net/ipv4/af_inet.c:413
+ sock_release+0x8d/0x1e0 net/socket.c:595
+ start_sync_thread+0x2213/0x2b70 net/netfilter/ipvs/ip_vs_sync.c:1924
+ do_ip_vs_set_ctl+0x1139/0x1cc0 net/netfilter/ipvs/ip_vs_ctl.c:2389
+ nf_sockopt net/netfilter/nf_sockopt.c:106 [inline]
+ nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:115
+ ip_setsockopt+0x97/0xa0 net/ipv4/ip_sockglue.c:1261
+ udp_setsockopt+0x45/0x80 net/ipv4/udp.c:2406
+ sock_common_setsockopt+0x95/0xd0 net/core/sock.c:2975
+ SYSC_setsockopt net/socket.c:1849 [inline]
+ SyS_setsockopt+0x189/0x360 net/socket.c:1828
+ do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x42/0xb7
+RIP: 0033:0x446a69
+RSP: 002b:00007fa1c3a64da8 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
+RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 0000000000446a69
+RDX: 000000000000048b RSI: 0000000000000000 RDI: 0000000000000003
+RBP: 00000000006e29fc R08: 0000000000000018 R09: 0000000000000000
+R10: 00000000200000c0 R11: 0000000000000246 R12: 00000000006e29f8
+R13: 00676e697279656b R14: 00007fa1c3a659c0 R15: 00000000006e2b60
+
+[2]
+IPVS: sync thread started: state = BACKUP, mcast_ifn = syz_tun, syncid = 4,
+id = 0
+IPVS: stopping backup sync thread 25415 ...
+INFO: task syz-executor7:25421 blocked for more than 120 seconds.
+ Not tainted 4.16.0-rc6+ #284
+"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+syz-executor7 D23688 25421 4408 0x00000004
+Call Trace:
+ context_switch kernel/sched/core.c:2862 [inline]
+ __schedule+0x8fb/0x1ec0 kernel/sched/core.c:3440
+ schedule+0xf5/0x430 kernel/sched/core.c:3499
+ schedule_timeout+0x1a3/0x230 kernel/time/timer.c:1777
+ do_wait_for_common kernel/sched/completion.c:86 [inline]
+ __wait_for_common kernel/sched/completion.c:107 [inline]
+ wait_for_common kernel/sched/completion.c:118 [inline]
+ wait_for_completion+0x415/0x770 kernel/sched/completion.c:139
+ kthread_stop+0x14a/0x7a0 kernel/kthread.c:530
+ stop_sync_thread+0x3d9/0x740 net/netfilter/ipvs/ip_vs_sync.c:1996
+ do_ip_vs_set_ctl+0x2b1/0x1cc0 net/netfilter/ipvs/ip_vs_ctl.c:2394
+ nf_sockopt net/netfilter/nf_sockopt.c:106 [inline]
+ nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:115
+ ip_setsockopt+0x97/0xa0 net/ipv4/ip_sockglue.c:1253
+ sctp_setsockopt+0x2ca/0x63e0 net/sctp/socket.c:4154
+ sock_common_setsockopt+0x95/0xd0 net/core/sock.c:3039
+ SYSC_setsockopt net/socket.c:1850 [inline]
+ SyS_setsockopt+0x189/0x360 net/socket.c:1829
+ do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x42/0xb7
+RIP: 0033:0x454889
+RSP: 002b:00007fc927626c68 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
+RAX: ffffffffffffffda RBX: 00007fc9276276d4 RCX: 0000000000454889
+RDX: 000000000000048c RSI: 0000000000000000 RDI: 0000000000000017
+RBP: 000000000072bf58 R08: 0000000000000018 R09: 0000000000000000
+R10: 0000000020000000 R11: 0000000000000246 R12: 00000000ffffffff
+R13: 000000000000051c R14: 00000000006f9b40 R15: 0000000000000001
+
+Showing all locks held in the system:
+2 locks held by khungtaskd/868:
+ #0: (rcu_read_lock){....}, at: [<00000000a1a8f002>]
+check_hung_uninterruptible_tasks kernel/hung_task.c:175 [inline]
+ #0: (rcu_read_lock){....}, at: [<00000000a1a8f002>] watchdog+0x1c5/0xd60
+kernel/hung_task.c:249
+ #1: (tasklist_lock){.+.+}, at: [<0000000037c2f8f9>]
+debug_show_all_locks+0xd3/0x3d0 kernel/locking/lockdep.c:4470
+1 lock held by rsyslogd/4247:
+ #0: (&f->f_pos_lock){+.+.}, at: [<000000000d8d6983>]
+__fdget_pos+0x12b/0x190 fs/file.c:765
+2 locks held by getty/4338:
+ #0: (&tty->ldisc_sem){++++}, at: [<00000000bee98654>]
+ldsem_down_read+0x37/0x40 drivers/tty/tty_ldsem.c:365
+ #1: (&ldata->atomic_read_lock){+.+.}, at: [<00000000c1d180aa>]
+n_tty_read+0x2ef/0x1a40 drivers/tty/n_tty.c:2131
+2 locks held by getty/4339:
+ #0: (&tty->ldisc_sem){++++}, at: [<00000000bee98654>]
+ldsem_down_read+0x37/0x40 drivers/tty/tty_ldsem.c:365
+ #1: (&ldata->atomic_read_lock){+.+.}, at: [<00000000c1d180aa>]
+n_tty_read+0x2ef/0x1a40 drivers/tty/n_tty.c:2131
+2 locks held by getty/4340:
+ #0: (&tty->ldisc_sem){++++}, at: [<00000000bee98654>]
+ldsem_down_read+0x37/0x40 drivers/tty/tty_ldsem.c:365
+ #1: (&ldata->atomic_read_lock){+.+.}, at: [<00000000c1d180aa>]
+n_tty_read+0x2ef/0x1a40 drivers/tty/n_tty.c:2131
+2 locks held by getty/4341:
+ #0: (&tty->ldisc_sem){++++}, at: [<00000000bee98654>]
+ldsem_down_read+0x37/0x40 drivers/tty/tty_ldsem.c:365
+ #1: (&ldata->atomic_read_lock){+.+.}, at: [<00000000c1d180aa>]
+n_tty_read+0x2ef/0x1a40 drivers/tty/n_tty.c:2131
+2 locks held by getty/4342:
+ #0: (&tty->ldisc_sem){++++}, at: [<00000000bee98654>]
+ldsem_down_read+0x37/0x40 drivers/tty/tty_ldsem.c:365
+ #1: (&ldata->atomic_read_lock){+.+.}, at: [<00000000c1d180aa>]
+n_tty_read+0x2ef/0x1a40 drivers/tty/n_tty.c:2131
+2 locks held by getty/4343:
+ #0: (&tty->ldisc_sem){++++}, at: [<00000000bee98654>]
+ldsem_down_read+0x37/0x40 drivers/tty/tty_ldsem.c:365
+ #1: (&ldata->atomic_read_lock){+.+.}, at: [<00000000c1d180aa>]
+n_tty_read+0x2ef/0x1a40 drivers/tty/n_tty.c:2131
+2 locks held by getty/4344:
+ #0: (&tty->ldisc_sem){++++}, at: [<00000000bee98654>]
+ldsem_down_read+0x37/0x40 drivers/tty/tty_ldsem.c:365
+ #1: (&ldata->atomic_read_lock){+.+.}, at: [<00000000c1d180aa>]
+n_tty_read+0x2ef/0x1a40 drivers/tty/n_tty.c:2131
+3 locks held by kworker/0:5/6494:
+ #0: ((wq_completion)"%s"("ipv6_addrconf")){+.+.}, at:
+[<00000000a062b18e>] work_static include/linux/workqueue.h:198 [inline]
+ #0: ((wq_completion)"%s"("ipv6_addrconf")){+.+.}, at:
+[<00000000a062b18e>] set_work_data kernel/workqueue.c:619 [inline]
+ #0: ((wq_completion)"%s"("ipv6_addrconf")){+.+.}, at:
+[<00000000a062b18e>] set_work_pool_and_clear_pending kernel/workqueue.c:646
+[inline]
+ #0: ((wq_completion)"%s"("ipv6_addrconf")){+.+.}, at:
+[<00000000a062b18e>] process_one_work+0xb12/0x1bb0 kernel/workqueue.c:2084
+ #1: ((addr_chk_work).work){+.+.}, at: [<00000000278427d5>]
+process_one_work+0xb89/0x1bb0 kernel/workqueue.c:2088
+ #2: (rtnl_mutex){+.+.}, at: [<00000000066e35ac>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+1 lock held by syz-executor7/25421:
+ #0: (ipvs->sync_mutex){+.+.}, at: [<00000000d414a689>]
+do_ip_vs_set_ctl+0x277/0x1cc0 net/netfilter/ipvs/ip_vs_ctl.c:2393
+2 locks held by syz-executor7/25427:
+ #0: (rtnl_mutex){+.+.}, at: [<00000000066e35ac>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+ #1: (ipvs->sync_mutex){+.+.}, at: [<00000000e6d48489>]
+do_ip_vs_set_ctl+0x10f8/0x1cc0 net/netfilter/ipvs/ip_vs_ctl.c:2388
+1 lock held by syz-executor7/25435:
+ #0: (rtnl_mutex){+.+.}, at: [<00000000066e35ac>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+1 lock held by ipvs-b:2:0/25415:
+ #0: (rtnl_mutex){+.+.}, at: [<00000000066e35ac>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+
+Reported-and-tested-by: syzbot+a46d6abf9d56b1365a72@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+5fe074c01b2032ce9618@syzkaller.appspotmail.com
+Fixes: e0b26cc997d5 ("ipvs: call rtnl_lock early")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/netfilter/ipvs/ip_vs_ctl.c | 8 ---
+ net/netfilter/ipvs/ip_vs_sync.c | 155 +++++++++++++++++++++-------------------
+ 2 files changed, 80 insertions(+), 83 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
+index 1fa3c2307b6e..ce51ba12c605 100644
+--- a/net/netfilter/ipvs/ip_vs_ctl.c
++++ b/net/netfilter/ipvs/ip_vs_ctl.c
+@@ -2386,11 +2386,7 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
+ strlcpy(cfg.mcast_ifn, dm->mcast_ifn,
+ sizeof(cfg.mcast_ifn));
+ cfg.syncid = dm->syncid;
+- rtnl_lock();
+- mutex_lock(&ipvs->sync_mutex);
+ ret = start_sync_thread(ipvs, &cfg, dm->state);
+- mutex_unlock(&ipvs->sync_mutex);
+- rtnl_unlock();
+ } else {
+ mutex_lock(&ipvs->sync_mutex);
+ ret = stop_sync_thread(ipvs, dm->state);
+@@ -3483,12 +3479,8 @@ static int ip_vs_genl_new_daemon(struct netns_ipvs *ipvs, struct nlattr **attrs)
+ if (ipvs->mixed_address_family_dests > 0)
+ return -EINVAL;
+
+- rtnl_lock();
+- mutex_lock(&ipvs->sync_mutex);
+ ret = start_sync_thread(ipvs, &c,
+ nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]));
+- mutex_unlock(&ipvs->sync_mutex);
+- rtnl_unlock();
+ return ret;
+ }
+
+diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
+index 0e5b64a75da0..9f1aa78e837d 100644
+--- a/net/netfilter/ipvs/ip_vs_sync.c
++++ b/net/netfilter/ipvs/ip_vs_sync.c
+@@ -48,6 +48,7 @@
+ #include <linux/kthread.h>
+ #include <linux/wait.h>
+ #include <linux/kernel.h>
++#include <linux/sched/signal.h>
+
+ #include <asm/unaligned.h> /* Used for ntoh_seq and hton_seq */
+
+@@ -1359,15 +1360,9 @@ static void set_mcast_pmtudisc(struct sock *sk, int val)
+ /*
+ * Specifiy default interface for outgoing multicasts
+ */
+-static int set_mcast_if(struct sock *sk, char *ifname)
++static int set_mcast_if(struct sock *sk, struct net_device *dev)
+ {
+- struct net_device *dev;
+ struct inet_sock *inet = inet_sk(sk);
+- struct net *net = sock_net(sk);
+-
+- dev = __dev_get_by_name(net, ifname);
+- if (!dev)
+- return -ENODEV;
+
+ if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+ return -EINVAL;
+@@ -1395,19 +1390,14 @@ static int set_mcast_if(struct sock *sk, char *ifname)
+ * in the in_addr structure passed in as a parameter.
+ */
+ static int
+-join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
++join_mcast_group(struct sock *sk, struct in_addr *addr, struct net_device *dev)
+ {
+- struct net *net = sock_net(sk);
+ struct ip_mreqn mreq;
+- struct net_device *dev;
+ int ret;
+
+ memset(&mreq, 0, sizeof(mreq));
+ memcpy(&mreq.imr_multiaddr, addr, sizeof(struct in_addr));
+
+- dev = __dev_get_by_name(net, ifname);
+- if (!dev)
+- return -ENODEV;
+ if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+ return -EINVAL;
+
+@@ -1422,15 +1412,10 @@ join_mcast_group(struct sock *sk, struct in_addr *addr, char *ifname)
+
+ #ifdef CONFIG_IP_VS_IPV6
+ static int join_mcast_group6(struct sock *sk, struct in6_addr *addr,
+- char *ifname)
++ struct net_device *dev)
+ {
+- struct net *net = sock_net(sk);
+- struct net_device *dev;
+ int ret;
+
+- dev = __dev_get_by_name(net, ifname);
+- if (!dev)
+- return -ENODEV;
+ if (sk->sk_bound_dev_if && dev->ifindex != sk->sk_bound_dev_if)
+ return -EINVAL;
+
+@@ -1442,24 +1427,18 @@ static int join_mcast_group6(struct sock *sk, struct in6_addr *addr,
+ }
+ #endif
+
+-static int bind_mcastif_addr(struct socket *sock, char *ifname)
++static int bind_mcastif_addr(struct socket *sock, struct net_device *dev)
+ {
+- struct net *net = sock_net(sock->sk);
+- struct net_device *dev;
+ __be32 addr;
+ struct sockaddr_in sin;
+
+- dev = __dev_get_by_name(net, ifname);
+- if (!dev)
+- return -ENODEV;
+-
+ addr = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
+ if (!addr)
+ pr_err("You probably need to specify IP address on "
+ "multicast interface.\n");
+
+ IP_VS_DBG(7, "binding socket with (%s) %pI4\n",
+- ifname, &addr);
++ dev->name, &addr);
+
+ /* Now bind the socket with the address of multicast interface */
+ sin.sin_family = AF_INET;
+@@ -1492,7 +1471,8 @@ static void get_mcast_sockaddr(union ipvs_sockaddr *sa, int *salen,
+ /*
+ * Set up sending multicast socket over UDP
+ */
+-static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
++static int make_send_sock(struct netns_ipvs *ipvs, int id,
++ struct net_device *dev, struct socket **sock_ret)
+ {
+ /* multicast addr */
+ union ipvs_sockaddr mcast_addr;
+@@ -1504,9 +1484,10 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
+ IPPROTO_UDP, &sock);
+ if (result < 0) {
+ pr_err("Error during creation of socket; terminating\n");
+- return ERR_PTR(result);
++ goto error;
+ }
+- result = set_mcast_if(sock->sk, ipvs->mcfg.mcast_ifn);
++ *sock_ret = sock;
++ result = set_mcast_if(sock->sk, dev);
+ if (result < 0) {
+ pr_err("Error setting outbound mcast interface\n");
+ goto error;
+@@ -1521,7 +1502,7 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
+ set_sock_size(sock->sk, 1, result);
+
+ if (AF_INET == ipvs->mcfg.mcast_af)
+- result = bind_mcastif_addr(sock, ipvs->mcfg.mcast_ifn);
++ result = bind_mcastif_addr(sock, dev);
+ else
+ result = 0;
+ if (result < 0) {
+@@ -1537,19 +1518,18 @@ static struct socket *make_send_sock(struct netns_ipvs *ipvs, int id)
+ goto error;
+ }
+
+- return sock;
++ return 0;
+
+ error:
+- sock_release(sock);
+- return ERR_PTR(result);
++ return result;
+ }
+
+
+ /*
+ * Set up receiving multicast socket over UDP
+ */
+-static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
+- int ifindex)
++static int make_receive_sock(struct netns_ipvs *ipvs, int id,
++ struct net_device *dev, struct socket **sock_ret)
+ {
+ /* multicast addr */
+ union ipvs_sockaddr mcast_addr;
+@@ -1561,8 +1541,9 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
+ IPPROTO_UDP, &sock);
+ if (result < 0) {
+ pr_err("Error during creation of socket; terminating\n");
+- return ERR_PTR(result);
++ goto error;
+ }
++ *sock_ret = sock;
+ /* it is equivalent to the REUSEADDR option in user-space */
+ sock->sk->sk_reuse = SK_CAN_REUSE;
+ result = sysctl_sync_sock_size(ipvs);
+@@ -1570,7 +1551,7 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
+ set_sock_size(sock->sk, 0, result);
+
+ get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->bcfg, id);
+- sock->sk->sk_bound_dev_if = ifindex;
++ sock->sk->sk_bound_dev_if = dev->ifindex;
+ result = sock->ops->bind(sock, (struct sockaddr *)&mcast_addr, salen);
+ if (result < 0) {
+ pr_err("Error binding to the multicast addr\n");
+@@ -1581,21 +1562,20 @@ static struct socket *make_receive_sock(struct netns_ipvs *ipvs, int id,
+ #ifdef CONFIG_IP_VS_IPV6
+ if (ipvs->bcfg.mcast_af == AF_INET6)
+ result = join_mcast_group6(sock->sk, &mcast_addr.in6.sin6_addr,
+- ipvs->bcfg.mcast_ifn);
++ dev);
+ else
+ #endif
+ result = join_mcast_group(sock->sk, &mcast_addr.in.sin_addr,
+- ipvs->bcfg.mcast_ifn);
++ dev);
+ if (result < 0) {
+ pr_err("Error joining to the multicast group\n");
+ goto error;
+ }
+
+- return sock;
++ return 0;
+
+ error:
+- sock_release(sock);
+- return ERR_PTR(result);
++ return result;
+ }
+
+
+@@ -1780,13 +1760,12 @@ static int sync_thread_backup(void *data)
+ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+ int state)
+ {
+- struct ip_vs_sync_thread_data *tinfo;
++ struct ip_vs_sync_thread_data *tinfo = NULL;
+ struct task_struct **array = NULL, *task;
+- struct socket *sock;
+ struct net_device *dev;
+ char *name;
+ int (*threadfn)(void *data);
+- int id, count, hlen;
++ int id = 0, count, hlen;
+ int result = -ENOMEM;
+ u16 mtu, min_mtu;
+
+@@ -1794,6 +1773,18 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+ IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %zd bytes\n",
+ sizeof(struct ip_vs_sync_conn_v0));
+
++ /* Do not hold one mutex and then to block on another */
++ for (;;) {
++ rtnl_lock();
++ if (mutex_trylock(&ipvs->sync_mutex))
++ break;
++ rtnl_unlock();
++ mutex_lock(&ipvs->sync_mutex);
++ if (rtnl_trylock())
++ break;
++ mutex_unlock(&ipvs->sync_mutex);
++ }
++
+ if (!ipvs->sync_state) {
+ count = clamp(sysctl_sync_ports(ipvs), 1, IPVS_SYNC_PORTS_MAX);
+ ipvs->threads_mask = count - 1;
+@@ -1812,7 +1803,8 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+ dev = __dev_get_by_name(ipvs->net, c->mcast_ifn);
+ if (!dev) {
+ pr_err("Unknown mcast interface: %s\n", c->mcast_ifn);
+- return -ENODEV;
++ result = -ENODEV;
++ goto out_early;
+ }
+ hlen = (AF_INET6 == c->mcast_af) ?
+ sizeof(struct ipv6hdr) + sizeof(struct udphdr) :
+@@ -1829,26 +1821,30 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+ c->sync_maxlen = mtu - hlen;
+
+ if (state == IP_VS_STATE_MASTER) {
++ result = -EEXIST;
+ if (ipvs->ms)
+- return -EEXIST;
++ goto out_early;
+
+ ipvs->mcfg = *c;
+ name = "ipvs-m:%d:%d";
+ threadfn = sync_thread_master;
+ } else if (state == IP_VS_STATE_BACKUP) {
++ result = -EEXIST;
+ if (ipvs->backup_threads)
+- return -EEXIST;
++ goto out_early;
+
+ ipvs->bcfg = *c;
+ name = "ipvs-b:%d:%d";
+ threadfn = sync_thread_backup;
+ } else {
+- return -EINVAL;
++ result = -EINVAL;
++ goto out_early;
+ }
+
+ if (state == IP_VS_STATE_MASTER) {
+ struct ipvs_master_sync_state *ms;
+
++ result = -ENOMEM;
+ ipvs->ms = kcalloc(count, sizeof(ipvs->ms[0]), GFP_KERNEL);
+ if (!ipvs->ms)
+ goto out;
+@@ -1864,39 +1860,38 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+ } else {
+ array = kcalloc(count, sizeof(struct task_struct *),
+ GFP_KERNEL);
++ result = -ENOMEM;
+ if (!array)
+ goto out;
+ }
+
+- tinfo = NULL;
+ for (id = 0; id < count; id++) {
+- if (state == IP_VS_STATE_MASTER)
+- sock = make_send_sock(ipvs, id);
+- else
+- sock = make_receive_sock(ipvs, id, dev->ifindex);
+- if (IS_ERR(sock)) {
+- result = PTR_ERR(sock);
+- goto outtinfo;
+- }
++ result = -ENOMEM;
+ tinfo = kmalloc(sizeof(*tinfo), GFP_KERNEL);
+ if (!tinfo)
+- goto outsocket;
++ goto out;
+ tinfo->ipvs = ipvs;
+- tinfo->sock = sock;
++ tinfo->sock = NULL;
+ if (state == IP_VS_STATE_BACKUP) {
+ tinfo->buf = kmalloc(ipvs->bcfg.sync_maxlen,
+ GFP_KERNEL);
+ if (!tinfo->buf)
+- goto outtinfo;
++ goto out;
+ } else {
+ tinfo->buf = NULL;
+ }
+ tinfo->id = id;
++ if (state == IP_VS_STATE_MASTER)
++ result = make_send_sock(ipvs, id, dev, &tinfo->sock);
++ else
++ result = make_receive_sock(ipvs, id, dev, &tinfo->sock);
++ if (result < 0)
++ goto out;
+
+ task = kthread_run(threadfn, tinfo, name, ipvs->gen, id);
+ if (IS_ERR(task)) {
+ result = PTR_ERR(task);
+- goto outtinfo;
++ goto out;
+ }
+ tinfo = NULL;
+ if (state == IP_VS_STATE_MASTER)
+@@ -1913,20 +1908,20 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+ ipvs->sync_state |= state;
+ spin_unlock_bh(&ipvs->sync_buff_lock);
+
++ mutex_unlock(&ipvs->sync_mutex);
++ rtnl_unlock();
++
+ /* increase the module use count */
+ ip_vs_use_count_inc();
+
+ return 0;
+
+-outsocket:
+- sock_release(sock);
+-
+-outtinfo:
+- if (tinfo) {
+- sock_release(tinfo->sock);
+- kfree(tinfo->buf);
+- kfree(tinfo);
+- }
++out:
++ /* We do not need RTNL lock anymore, release it here so that
++ * sock_release below and in the kthreads can use rtnl_lock
++ * to leave the mcast group.
++ */
++ rtnl_unlock();
+ count = id;
+ while (count-- > 0) {
+ if (state == IP_VS_STATE_MASTER)
+@@ -1934,13 +1929,23 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c,
+ else
+ kthread_stop(array[count]);
+ }
+- kfree(array);
+-
+-out:
+ if (!(ipvs->sync_state & IP_VS_STATE_MASTER)) {
+ kfree(ipvs->ms);
+ ipvs->ms = NULL;
+ }
++ mutex_unlock(&ipvs->sync_mutex);
++ if (tinfo) {
++ if (tinfo->sock)
++ sock_release(tinfo->sock);
++ kfree(tinfo->buf);
++ kfree(tinfo);
++ }
++ kfree(array);
++ return result;
++
++out_early:
++ mutex_unlock(&ipvs->sync_mutex);
++ rtnl_unlock();
+ return result;
+ }
+
+--
+2.12.3
+
diff --git a/patches.fixes/0006-packet-refine-ring-v3-block-size-test-to-hold-one-fr.patch b/patches.fixes/0006-packet-refine-ring-v3-block-size-test-to-hold-one-fr.patch
new file mode 100644
index 0000000000..7e241b76d4
--- /dev/null
+++ b/patches.fixes/0006-packet-refine-ring-v3-block-size-test-to-hold-one-fr.patch
@@ -0,0 +1,68 @@
+From: Willem de Bruijn <willemb@google.com>
+Subject: packet: refine ring v3 block size test to hold one
+ frame
+Patch-mainline: v4.18
+Git-commit: 4576cd469d980317c4edd9173f8b694aa71ea3a3
+References: git-fixes
+
+TPACKET_V3 stores variable length frames in fixed length blocks.
+Blocks must be able to store a block header, optional private space
+and at least one minimum sized frame.
+
+Frames, even for a zero snaplen packet, store metadata headers and
+optional reserved space.
+
+In the block size bounds check, ensure that the frame of the
+chosen configuration fits. This includes sockaddr_ll and optional
+tp_reserve.
+
+Syzbot was able to construct a ring with insuffient room for the
+sockaddr_ll in the header of a zero-length frame, triggering an
+out-of-bounds write in dev_parse_header.
+
+Convert the comparison to less than, as zero is a valid snap len.
+This matches the test for minimum tp_frame_size immediately below.
+
+Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
+Fixes: eb73190f4fbe ("net/packet: refine check for priv area size")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/packet/af_packet.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index cf7652bb2218..aefda8127760 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -4285,6 +4285,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
+ }
+
+ if (req->tp_block_nr) {
++ unsigned int min_frame_size;
++
+ /* Sanity tests and some calculations */
+ err = -EBUSY;
+ if (unlikely(rb->pg_vec))
+@@ -4307,12 +4309,12 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
+ goto out;
+ if (unlikely(!PAGE_ALIGNED(req->tp_block_size)))
+ goto out;
++ min_frame_size = po->tp_hdrlen + po->tp_reserve;
+ if (po->tp_version >= TPACKET_V3 &&
+- req->tp_block_size <=
+- BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + sizeof(struct tpacket3_hdr))
++ req->tp_block_size <
++ BLK_PLUS_PRIV((u64)req_u->req3.tp_sizeof_priv) + min_frame_size)
+ goto out;
+- if (unlikely(req->tp_frame_size < po->tp_hdrlen +
+- po->tp_reserve))
++ if (unlikely(req->tp_frame_size < min_frame_size))
+ goto out;
+ if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
+ goto out;
+--
+2.12.3
+
diff --git a/patches.fixes/0007-net-ipv6-fix-addrconf_sysctl_addr_gen_mode.patch b/patches.fixes/0007-net-ipv6-fix-addrconf_sysctl_addr_gen_mode.patch
new file mode 100644
index 0000000000..c8eb608238
--- /dev/null
+++ b/patches.fixes/0007-net-ipv6-fix-addrconf_sysctl_addr_gen_mode.patch
@@ -0,0 +1,99 @@
+From: Sabrina Dubroca <sd@queasysnail.net>
+Subject: net/ipv6: fix addrconf_sysctl_addr_gen_mode
+Patch-mainline: v4.19-rc1
+Git-commit: c6dbf7aaa48289d2eeacbef06785c069869ed0c0
+References: git-fixes
+
+
+addrconf_sysctl_addr_gen_mode() has multiple problems. First, it ignores
+the errors returned by proc_dointvec().
+
+addrconf_sysctl_addr_gen_mode() calls proc_dointvec() directly, which
+writes the value to memory, and then checks if it's valid and may return
+EINVAL. If a bad value is given, the value displayed when reading
+net.ipv6.conf.foo.addr_gen_mode next time will be invalid. In case the
+value provided by the user was valid, addrconf_dev_config() won't be
+called since idev->cnf.addr_gen_mode has already been updated.
+
+Fix this in the usual way we deal with values that need to be checked
+after the proc_do*() helper has returned: define a local ctl_table and
+storage, call proc_dointvec() on that temporary area, then check and
+store.
+
+addrconf_sysctl_addr_gen_mode() also writes the new value to the global
+ipv6_devconf_dflt, when we're writing to some netns's default, so that
+new netns will inherit the value that was set by the change occuring in
+any netns. That doesn't make any sense, so let's drop this assignment.
+
+Finally, since addr_gen_mode is a __u32, switch to proc_douintvec().
+
+Fixes: d35a00b8e33d ("net/ipv6: allow sysctl to change link-local address generation mode")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv6/addrconf.c | 27 ++++++++++++++-------------
+ 1 file changed, 14 insertions(+), 13 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 4a21afaacc59..1e72d02dd061 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -5790,32 +5790,31 @@ static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
+ loff_t *ppos)
+ {
+ int ret = 0;
+- int new_val;
++ u32 new_val;
+ struct inet6_dev *idev = (struct inet6_dev *)ctl->extra1;
+ struct net *net = (struct net *)ctl->extra2;
++ struct ctl_table tmp = {
++ .data = &new_val,
++ .maxlen = sizeof(new_val),
++ .mode = ctl->mode,
++ };
+
+ if (!rtnl_trylock())
+ return restart_syscall();
+
+- ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
++ new_val = *((u32 *)ctl->data);
+
+- if (write) {
+- new_val = *((int *)ctl->data);
++ ret = proc_douintvec(&tmp, write, buffer, lenp, ppos);
++ if (ret != 0)
++ goto out;
+
++ if (write) {
+ if (check_addr_gen_mode(new_val) < 0) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+- /* request for default */
+- if (&net->ipv6.devconf_dflt->addr_gen_mode == ctl->data) {
+- ipv6_devconf_dflt.addr_gen_mode = new_val;
+-
+- /* request for individual net device */
+- } else {
+- if (!idev)
+- goto out;
+-
++ if (idev) {
+ if (check_stable_privacy(idev, net, new_val) < 0) {
+ ret = -EINVAL;
+ goto out;
+@@ -5826,6 +5825,8 @@ static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
+ addrconf_dev_config(idev->dev);
+ }
+ }
++
++ *((u32 *)ctl->data) = new_val;
+ }
+
+ out:
+--
+2.12.3
+
diff --git a/patches.fixes/0007-netfilter-nf_tables-can-t-fail-after-linking-rule-in.patch b/patches.fixes/0007-netfilter-nf_tables-can-t-fail-after-linking-rule-in.patch
new file mode 100644
index 0000000000..36254a92b1
--- /dev/null
+++ b/patches.fixes/0007-netfilter-nf_tables-can-t-fail-after-linking-rule-in.patch
@@ -0,0 +1,112 @@
+From: Florian Westphal <fw@strlen.de>
+Subject: netfilter: nf_tables: can't fail after linking rule
+ into active rule list
+Patch-mainline: v4.17-rc3
+Git-commit: 569ccae68b38654f04b6842b034aa33857f605fe
+References: git-fixes
+
+rules in nftables a free'd using kfree, but protected by rcu, i.e. we
+must wait for a grace period to elapse.
+
+Normal removal patch does this, but nf_tables_newrule() doesn't obey
+this rule during error handling.
+
+It calls nft_trans_rule_add() *after* linking rule, and, if that
+fails to allocate memory, it unlinks the rule and then kfree() it --
+this is unsafe.
+
+Switch order -- first add rule to transaction list, THEN link it
+to public list.
+
+Note: nft_trans_rule_add() uses GFP_KERNEL; it will not fail so this
+is not a problem in practice (spotted only during code review).
+
+Fixes: 0628b123c96d12 ("netfilter: nfnetlink: add batch support and use it from nf_tables")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/netfilter/nf_tables_api.c | 59 +++++++++++++++++++++++--------------------
+ 1 file changed, 32 insertions(+), 27 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 595004098410..d627a479e332 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2251,41 +2251,46 @@ static int nf_tables_newrule(struct net *net, struct sock *nlsk,
+ }
+
+ if (nlh->nlmsg_flags & NLM_F_REPLACE) {
+- if (nft_is_active_next(net, old_rule)) {
+- trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
+- old_rule);
+- if (trans == NULL) {
+- err = -ENOMEM;
+- goto err2;
+- }
+- nft_deactivate_next(net, old_rule);
+- chain->use--;
+- list_add_tail_rcu(&rule->list, &old_rule->list);
+- } else {
++ if (!nft_is_active_next(net, old_rule)) {
+ err = -ENOENT;
+ goto err2;
+ }
+- } else if (nlh->nlmsg_flags & NLM_F_APPEND)
+- if (old_rule)
+- list_add_rcu(&rule->list, &old_rule->list);
+- else
+- list_add_tail_rcu(&rule->list, &chain->rules);
+- else {
+- if (old_rule)
+- list_add_tail_rcu(&rule->list, &old_rule->list);
+- else
+- list_add_rcu(&rule->list, &chain->rules);
+- }
++ trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
++ old_rule);
++ if (trans == NULL) {
++ err = -ENOMEM;
++ goto err2;
++ }
++ nft_deactivate_next(net, old_rule);
++ chain->use--;
+
+- if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
+- err = -ENOMEM;
+- goto err3;
++ if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
++ err = -ENOMEM;
++ goto err2;
++ }
++
++ list_add_tail_rcu(&rule->list, &old_rule->list);
++ } else {
++ if (nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule) == NULL) {
++ err = -ENOMEM;
++ goto err2;
++ }
++
++ if (nlh->nlmsg_flags & NLM_F_APPEND) {
++ if (old_rule)
++ list_add_rcu(&rule->list, &old_rule->list);
++ else
++ list_add_tail_rcu(&rule->list, &chain->rules);
++ } else {
++ if (old_rule)
++ list_add_tail_rcu(&rule->list, &old_rule->list);
++ else
++ list_add_rcu(&rule->list, &chain->rules);
++ }
+ }
+ chain->use++;
+ return 0;
+
+-err3:
+- list_del_rcu(&rule->list);
+ err2:
+ nf_tables_rule_destroy(&ctx, rule);
+ err1:
+--
+2.12.3
+
diff --git a/patches.fixes/0008-net-ipv6-don-t-reinitialize-ndev-cnf.addr_gen_mode-o.patch b/patches.fixes/0008-net-ipv6-don-t-reinitialize-ndev-cnf.addr_gen_mode-o.patch
new file mode 100644
index 0000000000..6ccd45d7b5
--- /dev/null
+++ b/patches.fixes/0008-net-ipv6-don-t-reinitialize-ndev-cnf.addr_gen_mode-o.patch
@@ -0,0 +1,36 @@
+From: Sabrina Dubroca <sd@queasysnail.net>
+Subject: net/ipv6: don't reinitialize ndev->cnf.addr_gen_mode on
+ new inet6_dev
+Patch-mainline: v4.19-rc1
+Git-commit: 70c30d76e580fe4aefe6facdf0f1edb1aa9a0e7a
+References: git-fixes
+
+
+The value has already been copied from this netns's devconf_dflt, it
+shouldn't be reset to the global kernel default.
+
+Fixes: d35a00b8e33d ("net/ipv6: allow sysctl to change link-local address generation mode")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv6/addrconf.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 1e72d02dd061..8a8bb3eb9b1e 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -395,8 +395,6 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev)
+
+ if (ndev->cnf.stable_secret.initialized)
+ ndev->cnf.addr_gen_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
+- else
+- ndev->cnf.addr_gen_mode = ipv6_devconf_dflt.addr_gen_mode;
+
+ ndev->cnf.mtu6 = dev->mtu;
+ ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
+--
+2.12.3
+
diff --git a/patches.fixes/0008-rxrpc-Fix-error-reception-on-AF_INET6-sockets.patch b/patches.fixes/0008-rxrpc-Fix-error-reception-on-AF_INET6-sockets.patch
new file mode 100644
index 0000000000..995ee8bf73
--- /dev/null
+++ b/patches.fixes/0008-rxrpc-Fix-error-reception-on-AF_INET6-sockets.patch
@@ -0,0 +1,95 @@
+From: David Howells <dhowells@redhat.com>
+Subject: rxrpc: Fix error reception on AF_INET6 sockets
+Patch-mainline: v4.17-rc5
+Git-commit: f2aeed3a591ff29a82495eeaa92ac4780bad7487
+References: git-fixes
+
+AF_RXRPC tries to turn on IP_RECVERR and IP_MTU_DISCOVER on the UDP socket
+it just opened for communications with the outside world, regardless of the
+type of socket. Unfortunately, this doesn't work with an AF_INET6 socket.
+
+Fix this by turning on IPV6_RECVERR and IPV6_MTU_DISCOVER instead if the
+socket is of the AF_INET6 family.
+
+Without this, kAFS server and address rotation doesn't work correctly
+because the algorithm doesn't detect received network errors.
+
+Fixes: 75b54cb57ca3 ("rxrpc: Add IPv6 support")
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/rxrpc/local_object.c | 57 +++++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 42 insertions(+), 15 deletions(-)
+
+diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
+index ff4864d550b8..adc49d8285bf 100644
+--- a/net/rxrpc/local_object.c
++++ b/net/rxrpc/local_object.c
+@@ -133,22 +133,49 @@ static int rxrpc_open_socket(struct rxrpc_local *local)
+ }
+ }
+
+- /* we want to receive ICMP errors */
+- opt = 1;
+- ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
+- (char *) &opt, sizeof(opt));
+- if (ret < 0) {
+- _debug("setsockopt failed");
+- goto error;
+- }
++ switch (local->srx.transport.family) {
++ case AF_INET:
++ /* we want to receive ICMP errors */
++ opt = 1;
++ ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
++ (char *) &opt, sizeof(opt));
++ if (ret < 0) {
++ _debug("setsockopt failed");
++ goto error;
++ }
+
+- /* we want to set the don't fragment bit */
+- opt = IP_PMTUDISC_DO;
+- ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
+- (char *) &opt, sizeof(opt));
+- if (ret < 0) {
+- _debug("setsockopt failed");
+- goto error;
++ /* we want to set the don't fragment bit */
++ opt = IP_PMTUDISC_DO;
++ ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
++ (char *) &opt, sizeof(opt));
++ if (ret < 0) {
++ _debug("setsockopt failed");
++ goto error;
++ }
++ break;
++
++ case AF_INET6:
++ /* we want to receive ICMP errors */
++ opt = 1;
++ ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
++ (char *) &opt, sizeof(opt));
++ if (ret < 0) {
++ _debug("setsockopt failed");
++ goto error;
++ }
++
++ /* we want to set the don't fragment bit */
++ opt = IPV6_PMTUDISC_DO;
++ ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_MTU_DISCOVER,
++ (char *) &opt, sizeof(opt));
++ if (ret < 0) {
++ _debug("setsockopt failed");
++ goto error;
++ }
++ break;
++
++ default:
++ BUG();
+ }
+
+ /* set the socket up */
+--
+2.12.3
+
diff --git a/patches.fixes/0009-net-ipv6-reserve-room-for-IFLA_INET6_ADDR_GEN_MODE.patch b/patches.fixes/0009-net-ipv6-reserve-room-for-IFLA_INET6_ADDR_GEN_MODE.patch
new file mode 100644
index 0000000000..9fd786f94f
--- /dev/null
+++ b/patches.fixes/0009-net-ipv6-reserve-room-for-IFLA_INET6_ADDR_GEN_MODE.patch
@@ -0,0 +1,38 @@
+From: Sabrina Dubroca <sd@queasysnail.net>
+Subject: net/ipv6: reserve room for IFLA_INET6_ADDR_GEN_MODE
+Patch-mainline: v4.19-rc1
+Git-commit: bdd72f41333d9f61a22e4c4494e95782e9731fdb
+References: git-fixes
+
+
+inet6_ifla6_size() is called to check how much space is needed by
+inet6_fill_link_af() and inet6_fill_ifinfo(), both of which include
+the IFLA_INET6_ADDR_GEN_MODE attribute. Reserve some room for it.
+
+Fixes: bc91b0f07ada ("ipv6: addrconf: implement address generation modes")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Reviewed-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv6/addrconf.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 8a8bb3eb9b1e..bbe616f991e9 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -5107,7 +5107,9 @@ static inline size_t inet6_ifla6_size(void)
+ + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
+ + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
+ + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
+- + nla_total_size(sizeof(struct in6_addr)); /* IFLA_INET6_TOKEN */
++ + nla_total_size(sizeof(struct in6_addr)) /* IFLA_INET6_TOKEN */
++ + nla_total_size(1) /* IFLA_INET6_ADDR_GEN_MODE */
++ + 0;
+ }
+
+ static inline size_t inet6_if_nlmsg_size(void)
+--
+2.12.3
+
diff --git a/patches.fixes/0009-packet-in-packet_snd-start-writing-at-link-layer-all.patch b/patches.fixes/0009-packet-in-packet_snd-start-writing-at-link-layer-all.patch
new file mode 100644
index 0000000000..98f7330676
--- /dev/null
+++ b/patches.fixes/0009-packet-in-packet_snd-start-writing-at-link-layer-all.patch
@@ -0,0 +1,59 @@
+From: Willem de Bruijn <willemb@google.com>
+Subject: packet: in packet_snd start writing at link layer
+ allocation
+Patch-mainline: v4.17-rc7
+Git-commit: b84bbaf7a6c8cca24f8acf25a2c8e46913a947ba
+References: git-fixes
+
+Packet sockets allow construction of packets shorter than
+dev->hard_header_len to accommodate protocols with variable length
+link layer headers. These packets are padded to dev->hard_header_len,
+because some device drivers interpret that as a minimum packet size.
+
+packet_snd reserves dev->hard_header_len bytes on allocation.
+SOCK_DGRAM sockets call skb_push in dev_hard_header() to ensure that
+link layer headers are stored in the reserved range. SOCK_RAW sockets
+do the same in tpacket_snd, but not in packet_snd.
+
+Syzbot was able to send a zero byte packet to a device with massive
+116B link layer header, causing padding to cross over into skb_shinfo.
+Fix this by writing from the start of the llheader reserved range also
+in the case of packet_snd/SOCK_RAW.
+
+Update skb_set_network_header to the new offset. This also corrects
+it for SOCK_DGRAM, where it incorrectly double counted reserve due to
+the skb_push in dev_hard_header.
+
+Fixes: 9ed988cd5915 ("packet: validate variable length ll headers")
+Reported-by: syzbot+71d74a5406d02057d559@syzkaller.appspotmail.com
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/packet/af_packet.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index c6c4d9be2276..901618eb2725 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -2925,13 +2925,15 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
+ if (skb == NULL)
+ goto out_unlock;
+
+- skb_set_network_header(skb, reserve);
++ skb_reset_network_header(skb);
+
+ err = -EINVAL;
+ if (sock->type == SOCK_DGRAM) {
+ offset = dev_hard_header(skb, dev, ntohs(proto), addr, NULL, len);
+ if (unlikely(offset < 0))
+ goto out_free;
++ } else if (reserve) {
++ skb_push(skb, reserve);
+ }
+
+ /* Returns -EFAULT on error */
+--
+2.12.3
+
diff --git a/patches.fixes/0010-ipvs-fix-stats-update-from-local-clients.patch b/patches.fixes/0010-ipvs-fix-stats-update-from-local-clients.patch
new file mode 100644
index 0000000000..f77c884071
--- /dev/null
+++ b/patches.fixes/0010-ipvs-fix-stats-update-from-local-clients.patch
@@ -0,0 +1,124 @@
+From: Julian Anastasov <ja@ssi.bg>
+Subject: ipvs: fix stats update from local clients
+Patch-mainline: v4.17-rc7
+Git-commit: d5e032fc5697b6c0d6b4958bcacb981a08f8174e
+References: git-fixes
+
+
+Local clients are not properly synchronized on 32-bit CPUs when
+updating stats (3.10+). Now it is possible estimation_timer (timer),
+a stats reader, to interrupt the local client in the middle of
+write_seqcount_{begin,end} sequence leading to loop (DEADLOCK).
+The same interrupt can happen from received packet (SoftIRQ)
+which updates the same per-CPU stats.
+
+Fix it by disabling BH while updating stats.
+
+Found with debug:
+
+WARNING: inconsistent lock state
+4.17.0-rc2-00105-g35cb6d7-dirty #2 Not tainted
+--------------------------------
+inconsistent {IN-SOFTIRQ-R} -> {SOFTIRQ-ON-W} usage.
+ftp/2545 [HC0[0]:SC0[0]:HE1:SE1] takes:
+86845479 (&syncp->seq#6){+.+-}, at: ip_vs_schedule+0x1c5/0x59e [ip_vs]
+{IN-SOFTIRQ-R} state was registered at:
+ lock_acquire+0x44/0x5b
+ estimation_timer+0x1b3/0x341 [ip_vs]
+ call_timer_fn+0x54/0xcd
+ run_timer_softirq+0x10c/0x12b
+ __do_softirq+0xc1/0x1a9
+ do_softirq_own_stack+0x1d/0x23
+ irq_exit+0x4a/0x64
+ smp_apic_timer_interrupt+0x63/0x71
+ apic_timer_interrupt+0x3a/0x40
+ default_idle+0xa/0xc
+ arch_cpu_idle+0x9/0xb
+ default_idle_call+0x21/0x23
+ do_idle+0xa0/0x167
+ cpu_startup_entry+0x19/0x1b
+ start_secondary+0x133/0x182
+ startup_32_smp+0x164/0x168
+irq event stamp: 42213
+
+other info that might help us debug this:
+Possible unsafe locking scenario:
+
+ CPU0
+ ----
+ lock(&syncp->seq#6);
+ <Interrupt>
+ lock(&syncp->seq#6);
+
+*** DEADLOCK ***
+
+Fixes: ac69269a45e8 ("ipvs: do not disable bh for long time")
+Signed-off-by: Julian Anastasov <ja@ssi.bg>
+Acked-by: Simon Horman <horms@verge.net.au>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/netfilter/ipvs/ip_vs_core.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
+index ad99c1ceea6f..62ed310e2397 100644
+--- a/net/netfilter/ipvs/ip_vs_core.c
++++ b/net/netfilter/ipvs/ip_vs_core.c
+@@ -119,6 +119,8 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+ struct ip_vs_cpu_stats *s;
+ struct ip_vs_service *svc;
+
++ local_bh_disable();
++
+ s = this_cpu_ptr(dest->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+ s->cnt.inpkts++;
+@@ -139,6 +141,8 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+ s->cnt.inpkts++;
+ s->cnt.inbytes += skb->len;
+ u64_stats_update_end(&s->syncp);
++
++ local_bh_enable();
+ }
+ }
+
+@@ -153,6 +157,8 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+ struct ip_vs_cpu_stats *s;
+ struct ip_vs_service *svc;
+
++ local_bh_disable();
++
+ s = this_cpu_ptr(dest->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+ s->cnt.outpkts++;
+@@ -173,6 +179,8 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
+ s->cnt.outpkts++;
+ s->cnt.outbytes += skb->len;
+ u64_stats_update_end(&s->syncp);
++
++ local_bh_enable();
+ }
+ }
+
+@@ -183,6 +191,8 @@ ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
+ struct netns_ipvs *ipvs = svc->ipvs;
+ struct ip_vs_cpu_stats *s;
+
++ local_bh_disable();
++
+ s = this_cpu_ptr(cp->dest->stats.cpustats);
+ u64_stats_update_begin(&s->syncp);
+ s->cnt.conns++;
+@@ -197,6 +207,8 @@ ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
+ u64_stats_update_begin(&s->syncp);
+ s->cnt.conns++;
+ u64_stats_update_end(&s->syncp);
++
++ local_bh_enable();
+ }
+
+
+--
+2.12.3
+
diff --git a/patches.fixes/0010-net-ipv6-propagate-net.ipv6.conf.all.addr_gen_mode-t.patch b/patches.fixes/0010-net-ipv6-propagate-net.ipv6.conf.all.addr_gen_mode-t.patch
new file mode 100644
index 0000000000..0ace619829
--- /dev/null
+++ b/patches.fixes/0010-net-ipv6-propagate-net.ipv6.conf.all.addr_gen_mode-t.patch
@@ -0,0 +1,45 @@
+From: Sabrina Dubroca <sd@queasysnail.net>
+Subject: net/ipv6: propagate net.ipv6.conf.all.addr_gen_mode to
+ devices
+Patch-mainline: v4.19-rc1
+Git-commit: f24c5987dddd28b23443e7b21b55d47549207755
+References: git-fixes
+
+This aligns the addr_gen_mode sysctl with the expected behavior of the
+"all" variant.
+
+Fixes: d35a00b8e33d ("net/ipv6: allow sysctl to change link-local address generation mode")
+Suggested-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv6/addrconf.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index bbe616f991e9..106da7d7052b 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -5824,6 +5824,18 @@ static int addrconf_sysctl_addr_gen_mode(struct ctl_table *ctl, int write,
+ idev->cnf.addr_gen_mode = new_val;
+ addrconf_dev_config(idev->dev);
+ }
++ } else if (&net->ipv6.devconf_all->addr_gen_mode == ctl->data) {
++ struct net_device *dev;
++
++ net->ipv6.devconf_dflt->addr_gen_mode = new_val;
++ for_each_netdev(net, dev) {
++ idev = __in6_dev_get(dev);
++ if (idev &&
++ idev->cnf.addr_gen_mode != new_val) {
++ idev->cnf.addr_gen_mode = new_val;
++ addrconf_dev_config(idev->dev);
++ }
++ }
+ }
+
+ *((u32 *)ctl->data) = new_val;
+--
+2.12.3
+
diff --git a/patches.fixes/0011-tcp-purge-write-queue-in-tcp_connect_init.patch b/patches.fixes/0011-tcp-purge-write-queue-in-tcp_connect_init.patch
new file mode 100644
index 0000000000..fa8a24755f
--- /dev/null
+++ b/patches.fixes/0011-tcp-purge-write-queue-in-tcp_connect_init.patch
@@ -0,0 +1,90 @@
+From: Eric Dumazet <edumazet@google.com>
+Subject: tcp: purge write queue in tcp_connect_init()
+Patch-mainline: v4.17-rc7
+Git-commit: 7f582b248d0a86bae5788c548d7bb5bca6f7691a
+References: git-fixes
+
+syzkaller found a reliable way to crash the host, hitting a BUG()
+in __tcp_retransmit_skb()
+
+Malicous MSG_FASTOPEN is the root cause. We need to purge write queue
+in tcp_connect_init() at the point we init snd_una/write_seq.
+
+This patch also replaces the BUG() by a less intrusive WARN_ON_ONCE()
+
+kernel BUG at net/ipv4/tcp_output.c:2837!
+invalid opcode: 0000 [#1] SMP KASAN
+Dumping ftrace buffer:
+ (ftrace buffer empty)
+Modules linked in:
+CPU: 0 PID: 5276 Comm: syz-executor0 Not tainted 4.17.0-rc3+ #51
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+RIP: 0010:__tcp_retransmit_skb+0x2992/0x2eb0 net/ipv4/tcp_output.c:2837
+RSP: 0000:ffff8801dae06ff8 EFLAGS: 00010206
+RAX: ffff8801b9fe61c0 RBX: 00000000ffc18a16 RCX: ffffffff864e1a49
+RDX: 0000000000000100 RSI: ffffffff864e2e12 RDI: 0000000000000005
+RBP: ffff8801dae073a0 R08: ffff8801b9fe61c0 R09: ffffed0039c40dd2
+R10: ffffed0039c40dd2 R11: ffff8801ce206e93 R12: 00000000421eeaad
+R13: ffff8801ce206d4e R14: ffff8801ce206cc0 R15: ffff8801cd4f4a80
+FS: 0000000000000000(0000) GS:ffff8801dae00000(0063) knlGS:00000000096bc900
+CS: 0010 DS: 002b ES: 002b CR0: 0000000080050033
+CR2: 0000000020000000 CR3: 00000001c47b6000 CR4: 00000000001406f0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ <IRQ>
+ tcp_retransmit_skb+0x2e/0x250 net/ipv4/tcp_output.c:2923
+ tcp_retransmit_timer+0xc50/0x3060 net/ipv4/tcp_timer.c:488
+ tcp_write_timer_handler+0x339/0x960 net/ipv4/tcp_timer.c:573
+ tcp_write_timer+0x111/0x1d0 net/ipv4/tcp_timer.c:593
+ call_timer_fn+0x230/0x940 kernel/time/timer.c:1326
+ expire_timers kernel/time/timer.c:1363 [inline]
+ __run_timers+0x79e/0xc50 kernel/time/timer.c:1666
+ run_timer_softirq+0x4c/0x70 kernel/time/timer.c:1692
+ __do_softirq+0x2e0/0xaf5 kernel/softirq.c:285
+ invoke_softirq kernel/softirq.c:365 [inline]
+ irq_exit+0x1d1/0x200 kernel/softirq.c:405
+ exiting_irq arch/x86/include/asm/apic.h:525 [inline]
+ smp_apic_timer_interrupt+0x17e/0x710 arch/x86/kernel/apic/apic.c:1052
+ apic_timer_interrupt+0xf/0x20 arch/x86/entry/entry_64.S:863
+
+Fixes: cf60af03ca4e ("net-tcp: Fast Open client - sendmsg(MSG_FASTOPEN)")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Yuchung Cheng <ycheng@google.com>
+Cc: Neal Cardwell <ncardwell@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv4/tcp_output.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 2d139697bcd8..beda69aad37d 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -2842,8 +2842,10 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs)
+ return -EBUSY;
+
+ if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
+- if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
+- BUG();
++ if (unlikely(before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))) {
++ WARN_ON_ONCE(1);
++ return -EINVAL;
++ }
+ if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq))
+ return -ENOMEM;
+ }
+@@ -3332,6 +3334,7 @@ static void tcp_connect_init(struct sock *sk)
+ sock_reset_flag(sk, SOCK_DONE);
+ tp->snd_wnd = 0;
+ tcp_init_wl(tp, 0);
++ tcp_write_queue_purge(sk);
+ tp->snd_una = tp->write_seq;
+ tp->snd_sml = tp->write_seq;
+ tp->snd_up = tp->write_seq;
+--
+2.12.3
+
diff --git a/patches.fixes/0011-xfrm-fix-passing-zero-to-ERR_PTR-warning.patch b/patches.fixes/0011-xfrm-fix-passing-zero-to-ERR_PTR-warning.patch
new file mode 100644
index 0000000000..a0cca58803
--- /dev/null
+++ b/patches.fixes/0011-xfrm-fix-passing-zero-to-ERR_PTR-warning.patch
@@ -0,0 +1,41 @@
+From: YueHaibing <yuehaibing@huawei.com>
+Subject: xfrm: fix 'passing zero to ERR_PTR()' warning
+Patch-mainline: v4.19-rc1
+Git-commit: 934ffce1343f22ed5e2d0bd6da4440f4848074de
+References: git-fixes
+
+
+Fix a static code checker warning:
+
+ net/xfrm/xfrm_policy.c:1836 xfrm_resolve_and_create_bundle() warn: passing zero to 'ERR_PTR'
+
+xfrm_tmpl_resolve return 0 just means no xdst found, return NULL
+instead of passing zero to ERR_PTR.
+
+Fixes: d809ec895505 ("xfrm: do not assume that template resolving always returns xfrms")
+Signed-off-by: YueHaibing <yuehaibing@huawei.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/xfrm/xfrm_policy.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
+index e86a65292879..c82c695fa3fd 100644
+--- a/net/xfrm/xfrm_policy.c
++++ b/net/xfrm/xfrm_policy.c
+@@ -1864,7 +1864,10 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
+ /* Try to instantiate a bundle */
+ err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
+ if (err <= 0) {
+- if (err != 0 && err != -EAGAIN)
++ if (err == 0)
++ return NULL;
++
++ if (err != -EAGAIN)
+ XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
+ return ERR_PTR(err);
+ }
+--
+2.12.3
+
diff --git a/patches.fixes/0012-ip6_tunnel-collect_md-xmit-Use-ip_tunnel_key-s-provi.patch b/patches.fixes/0012-ip6_tunnel-collect_md-xmit-Use-ip_tunnel_key-s-provi.patch
new file mode 100644
index 0000000000..0fb0103115
--- /dev/null
+++ b/patches.fixes/0012-ip6_tunnel-collect_md-xmit-Use-ip_tunnel_key-s-provi.patch
@@ -0,0 +1,62 @@
+From: Shmulik Ladkani <shmulik@metanetworks.com>
+Subject: ip6_tunnel: collect_md xmit: Use ip_tunnel_key's
+ provided src address
+Patch-mainline: v4.19-rc1
+Git-commit: 3789cabaab1a939eb56edd76bbde2c2e49f081da
+References: git-fixes
+
+
+calculation purposes (flowi6 construction) and for assigning the
+packet's final ipv6h->saddr.
+
+This makes it impossible specifying a desired ipv6 local address in the
+encapsulating header (for example, when using tc action tunnel_key).
+
+This is also not aligned with behavior of ipip (ipv4) in collect_md
+mode, where the key->u.ipv4.src gets used.
+
+Fix, by assigning fl6.saddr with given key->u.ipv6.src.
+In case ipv6.src is not specified, ip6_tnl_xmit uses existing saddr
+selection code.
+
+Fixes: 8d79266bc48c ("ip6_tunnel: add collect_md mode to IPv6 tunnels")
+Signed-off-by: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+Reviewed-by: Eyal Birger <eyal.birger@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv6/ip6_tunnel.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index f626d3e5c8dc..92a0ff707023 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1115,7 +1115,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
+ dst = NULL;
+ goto tx_err_link_failure;
+ }
+- if (t->parms.collect_md &&
++ if (t->parms.collect_md && ipv6_addr_any(&fl6->saddr) &&
+ ipv6_dev_get_saddr(net, ip6_dst_idev(dst)->dev,
+ &fl6->daddr, 0, &fl6->saddr))
+ goto tx_err_link_failure;
+@@ -1253,6 +1253,7 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
+ key = &tun_info->key;
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_IPIP;
++ fl6.saddr = key->u.ipv6.src;
+ fl6.daddr = key->u.ipv6.dst;
+ fl6.flowlabel = key->label;
+ dsfield = key->tos;
+@@ -1325,6 +1326,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
+ key = &tun_info->key;
+ memset(&fl6, 0, sizeof(fl6));
+ fl6.flowi6_proto = IPPROTO_IPV6;
++ fl6.saddr = key->u.ipv6.src;
+ fl6.daddr = key->u.ipv6.dst;
+ fl6.flowlabel = key->label;
+ dsfield = key->tos;
+--
+2.12.3
+
diff --git a/patches.fixes/0012-net-test-tailroom-before-appending-to-linear-skb.patch b/patches.fixes/0012-net-test-tailroom-before-appending-to-linear-skb.patch
new file mode 100644
index 0000000000..705d0dab79
--- /dev/null
+++ b/patches.fixes/0012-net-test-tailroom-before-appending-to-linear-skb.patch
@@ -0,0 +1,58 @@
+From: Willem de Bruijn <willemb@google.com>
+Subject: net: test tailroom before appending to linear skb
+Patch-mainline: v4.17-rc7
+Git-commit: 113f99c3358564a0647d444c2ae34e8b1abfd5b9
+References: git-fixes
+
+Device features may change during transmission. In particular with
+corking, a device may toggle scatter-gather in between allocating
+and writing to an skb.
+
+Do not unconditionally assume that !NETIF_F_SG at write time implies
+that the same held at alloc time and thus the skb has sufficient
+tailroom.
+
+This issue predates git history.
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv4/ip_output.c | 3 ++-
+ net/ipv6/ip6_output.c | 3 ++-
+ 2 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 41c5d8bdc768..c81916930652 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -1042,7 +1042,8 @@ static int __ip_append_data(struct sock *sk,
+ if (copy > length)
+ copy = length;
+
+- if (!(rt->dst.dev->features&NETIF_F_SG)) {
++ if (!(rt->dst.dev->features&NETIF_F_SG) &&
++ skb_tailroom(skb) >= copy) {
+ unsigned int off;
+
+ off = skb->len;
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index 42a97e490737..04729272dfb3 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1484,7 +1484,8 @@ static int __ip6_append_data(struct sock *sk,
+ if (copy > length)
+ copy = length;
+
+- if (!(rt->dst.dev->features&NETIF_F_SG)) {
++ if (!(rt->dst.dev->features&NETIF_F_SG) &&
++ skb_tailroom(skb) >= copy) {
+ unsigned int off;
+
+ off = skb->len;
+--
+2.12.3
+
diff --git a/patches.fixes/0013-ipv6-fix-cleanup-ordering-for-ip6_mr-failure.patch b/patches.fixes/0013-ipv6-fix-cleanup-ordering-for-ip6_mr-failure.patch
new file mode 100644
index 0000000000..5afd71b135
--- /dev/null
+++ b/patches.fixes/0013-ipv6-fix-cleanup-ordering-for-ip6_mr-failure.patch
@@ -0,0 +1,65 @@
+From: Sabrina Dubroca <sd@queasysnail.net>
+Subject: ipv6: fix cleanup ordering for ip6_mr failure
+Patch-mainline: v4.19-rc3
+Git-commit: afe49de44c27a89e8e9631c44b5ffadf6ace65e2
+References: git-fixes
+
+
+Commit 15e668070a64 ("ipv6: reorder icmpv6_init() and ip6_mr_init()")
+moved the cleanup label for ipmr_fail, but should have changed the
+contents of the cleanup labels as well. Now we can end up cleaning up
+icmpv6 even though it hasn't been initialized (jump to icmp_fail or
+ipmr_fail).
+
+Simply undo things in the reverse order of their initialization.
+
+Example of panic (triggered by faking a failure of icmpv6_init):
+
+ kasan: GPF could be caused by NULL-ptr deref or user memory access
+ general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI
+ [...]
+ RIP: 0010:__list_del_entry_valid+0x79/0x160
+ [...]
+ Call Trace:
+ ? lock_release+0x8a0/0x8a0
+ unregister_pernet_operations+0xd4/0x560
+ ? ops_free_list+0x480/0x480
+ ? down_write+0x91/0x130
+ ? unregister_pernet_subsys+0x15/0x30
+ ? down_read+0x1b0/0x1b0
+ ? up_read+0x110/0x110
+ ? kmem_cache_create_usercopy+0x1b4/0x240
+ unregister_pernet_subsys+0x1d/0x30
+ icmpv6_cleanup+0x1d/0x30
+ inet6_init+0x1b5/0x23f
+
+Fixes: 15e668070a64 ("ipv6: reorder icmpv6_init() and ip6_mr_init()")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv6/af_inet6.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 94b0cf2c2829..45873b1025d4 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -1085,11 +1085,11 @@ static int __init inet6_init(void)
+ igmp_fail:
+ ndisc_cleanup();
+ ndisc_fail:
+- ip6_mr_cleanup();
++ icmpv6_cleanup();
+ icmp_fail:
+- unregister_pernet_subsys(&inet6_net_ops);
++ ip6_mr_cleanup();
+ ipmr_fail:
+- icmpv6_cleanup();
++ unregister_pernet_subsys(&inet6_net_ops);
+ register_pernet_fail:
+ sock_unregister(PF_INET6);
+ rtnl_unregister_all(PF_INET6);
+--
+2.12.3
+
diff --git a/patches.fixes/0013-net-Fix-a-bug-in-removing-queues-from-XPS-map.patch b/patches.fixes/0013-net-Fix-a-bug-in-removing-queues-from-XPS-map.patch
new file mode 100644
index 0000000000..c833d893d3
--- /dev/null
+++ b/patches.fixes/0013-net-Fix-a-bug-in-removing-queues-from-XPS-map.patch
@@ -0,0 +1,35 @@
+From: Amritha Nambiar <amritha.nambiar@intel.com>
+Subject: net: Fix a bug in removing queues from XPS map
+Patch-mainline: v4.17-rc7
+Git-commit: 6358d49ac23995fdfe157cc8747ab0f274d3954b
+References: git-fixes
+
+While removing queues from the XPS map, the individual CPU ID
+alone was used to index the CPUs map, this should be changed to also
+factor in the traffic class mapping for the CPU-to-queue lookup.
+
+Fixes: 184c449f91fe ("net: Add support for XPS with QoS via traffic classes")
+Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
+Acked-by: Alexander Duyck <alexander.h.duyck@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 15880ba084a9..f259eb1b21b8 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2078,7 +2078,7 @@ static bool remove_xps_queue_cpu(struct net_device *dev,
+ int i, j;
+
+ for (i = count, j = offset; i--; j++) {
+- if (!remove_xps_queue(dev_maps, cpu, j))
++ if (!remove_xps_queue(dev_maps, tci, j))
+ break;
+ }
+
+--
+2.12.3
+
diff --git a/patches.fixes/0014-ipv6-fix-cleanup-ordering-for-pingv6-registration.patch b/patches.fixes/0014-ipv6-fix-cleanup-ordering-for-pingv6-registration.patch
new file mode 100644
index 0000000000..af792c0fe8
--- /dev/null
+++ b/patches.fixes/0014-ipv6-fix-cleanup-ordering-for-pingv6-registration.patch
@@ -0,0 +1,58 @@
+From: Sabrina Dubroca <sd@queasysnail.net>
+Subject: ipv6: fix cleanup ordering for pingv6 registration
+Patch-mainline: v4.19-rc3
+Git-commit: a03dc36bdca6b614651fedfcd8559cf914d2d21d
+References: git-fixes
+
+
+Commit 6d0bfe226116 ("net: ipv6: Add IPv6 support to the ping socket.")
+contains an error in the cleanup path of inet6_init(): when
+proto_register(&pingv6_prot, 1) fails, we try to unregister
+&pingv6_prot. When rawv6_init() fails, we skip unregistering
+&pingv6_prot.
+
+Example of panic (triggered by faking a failure of
+ proto_register(&pingv6_prot, 1)):
+
+ general protection fault: 0000 [#1] PREEMPT SMP KASAN PTI
+ [...]
+ RIP: 0010:__list_del_entry_valid+0x79/0x160
+ [...]
+ Call Trace:
+ proto_unregister+0xbb/0x550
+ ? trace_preempt_on+0x6f0/0x6f0
+ ? sock_no_shutdown+0x10/0x10
+ inet6_init+0x153/0x1b8
+
+Fixes: 6d0bfe226116 ("net: ipv6: Add IPv6 support to the ping socket.")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv6/af_inet6.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 45873b1025d4..7f6e15e03ef5 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -911,14 +911,14 @@ static int __init inet6_init(void)
+
+ err = proto_register(&pingv6_prot, 1);
+ if (err)
+- goto out_unregister_ping_proto;
++ goto out_unregister_raw_proto;
+
+ /* We MUST register RAW sockets before we create the ICMP6,
+ * IGMP6, or NDISC control sockets.
+ */
+ err = rawv6_init();
+ if (err)
+- goto out_unregister_raw_proto;
++ goto out_unregister_ping_proto;
+
+ /* Register the family here so that the init calls below will
+ * be able to create sockets. (?? is this dangerous ??)
+--
+2.12.3
+
diff --git a/patches.fixes/0014-netfilter-nf_tables-fix-NULL-pointer-dereference-on-.patch b/patches.fixes/0014-netfilter-nf_tables-fix-NULL-pointer-dereference-on-.patch
new file mode 100644
index 0000000000..59aff0b412
--- /dev/null
+++ b/patches.fixes/0014-netfilter-nf_tables-fix-NULL-pointer-dereference-on-.patch
@@ -0,0 +1,164 @@
+From: Taehee Yoo <ap420073@gmail.com>
+Subject: netfilter: nf_tables: fix NULL pointer dereference on
+ nft_ct_helper_obj_dump()
+Patch-mainline: v4.17
+Git-commit: b71534583f22d08c3e3563bf5100aeb5f5c9fbe5
+References: git-fixes
+
+
+In the nft_ct_helper_obj_dump(), always priv->helper4 is dereferenced.
+But if family is ipv6, priv->helper6 should be dereferenced.
+
+Steps to reproduces:
+
+ #test.nft
+ table ip6 filter {
+ ct helper ftp {
+ type "ftp" protocol tcp
+ }
+ chain input {
+ type filter hook input priority 4;
+ ct helper set "ftp"
+ }
+ }
+
+ %nft -f test.nft
+ %nft list ruleset
+
+we can see the below messages:
+
+[ 916.286233] kasan: GPF could be caused by NULL-ptr deref or user memory access
+[ 916.294777] general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN PTI
+[ 916.302613] Modules linked in: nft_objref nf_conntrack_sip nf_conntrack_snmp nf_conntrack_broadcast nf_conntrack_ftp nft_ct nf_conntrack nf_tables nfnetlink [last unloaded: nfnetlink]
+[ 916.318758] CPU: 1 PID: 2093 Comm: nft Not tainted 4.17.0-rc4+ #181
+[ 916.326772] Hardware name: To be filled by O.E.M. To be filled by O.E.M./Aptio CRB, BIOS 5.6.5 07/08/2015
+[ 916.338773] RIP: 0010:strlen+0x1a/0x90
+[ 916.342781] RSP: 0018:ffff88010ff0f2f8 EFLAGS: 00010292
+[ 916.346773] RAX: dffffc0000000000 RBX: ffff880119b26ee8 RCX: ffff88010c150038
+[ 916.354777] RDX: 0000000000000002 RSI: ffff880119b26ee8 RDI: 0000000000000010
+[ 916.362773] RBP: 0000000000000010 R08: 0000000000007e88 R09: ffff88010c15003c
+[ 916.370773] R10: ffff88010c150037 R11: ffffed002182a007 R12: ffff88010ff04040
+[ 916.378779] R13: 0000000000000010 R14: ffff880119b26f30 R15: ffff88010ff04110
+[ 916.387265] FS: 00007f57a1997700(0000) GS:ffff88011b800000(0000) knlGS:0000000000000000
+[ 916.394785] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 916.402778] CR2: 00007f57a0ac80f0 CR3: 000000010ff02000 CR4: 00000000001006e0
+[ 916.410772] Call Trace:
+[ 916.414787] nft_ct_helper_obj_dump+0x94/0x200 [nft_ct]
+[ 916.418779] ? nft_ct_set_eval+0x560/0x560 [nft_ct]
+[ 916.426771] ? memset+0x1f/0x40
+[ 916.426771] ? __nla_reserve+0x92/0xb0
+[ 916.434774] ? memcpy+0x34/0x50
+[ 916.434774] nf_tables_fill_obj_info+0x484/0x860 [nf_tables]
+[ 916.442773] ? __nft_release_basechain+0x600/0x600 [nf_tables]
+[ 916.450779] ? lock_acquire+0x193/0x380
+[ 916.454771] ? lock_acquire+0x193/0x380
+[ 916.458789] ? nf_tables_dump_obj+0x148/0xcb0 [nf_tables]
+[ 916.462777] nf_tables_dump_obj+0x5f0/0xcb0 [nf_tables]
+[ 916.470769] ? __alloc_skb+0x30b/0x500
+[ 916.474779] netlink_dump+0x752/0xb50
+[ 916.478775] __netlink_dump_start+0x4d3/0x750
+[ 916.482784] nf_tables_getobj+0x27a/0x930 [nf_tables]
+[ 916.490774] ? nft_obj_notify+0x100/0x100 [nf_tables]
+[ 916.494772] ? nf_tables_getobj+0x930/0x930 [nf_tables]
+[ 916.502579] ? nf_tables_dump_flowtable_done+0x70/0x70 [nf_tables]
+[ 916.506774] ? nft_obj_notify+0x100/0x100 [nf_tables]
+[ 916.514808] nfnetlink_rcv_msg+0x8ab/0xa86 [nfnetlink]
+[ 916.518771] ? nfnetlink_rcv_msg+0x550/0xa86 [nfnetlink]
+[ 916.526782] netlink_rcv_skb+0x23e/0x360
+[ 916.530773] ? nfnetlink_bind+0x200/0x200 [nfnetlink]
+[ 916.534778] ? debug_check_no_locks_freed+0x280/0x280
+[ 916.542770] ? netlink_ack+0x870/0x870
+[ 916.546786] ? ns_capable_common+0xf4/0x130
+[ 916.550765] nfnetlink_rcv+0x172/0x16c0 [nfnetlink]
+[ 916.554771] ? sched_clock_local+0xe2/0x150
+[ 916.558774] ? sched_clock_cpu+0x144/0x180
+[ 916.566575] ? lock_acquire+0x380/0x380
+[ 916.570775] ? sched_clock_local+0xe2/0x150
+[ 916.574765] ? nfnetlink_net_init+0x130/0x130 [nfnetlink]
+[ 916.578763] ? sched_clock_cpu+0x144/0x180
+[ 916.582770] ? lock_acquire+0x193/0x380
+[ 916.590771] ? lock_acquire+0x193/0x380
+[ 916.594766] ? lock_acquire+0x380/0x380
+[ 916.598760] ? netlink_deliver_tap+0x262/0xa60
+[ 916.602766] ? lock_acquire+0x193/0x380
+[ 916.606766] netlink_unicast+0x3ef/0x5a0
+[ 916.610771] ? netlink_attachskb+0x630/0x630
+[ 916.614763] netlink_sendmsg+0x72a/0xb00
+[ 916.618769] ? netlink_unicast+0x5a0/0x5a0
+[ 916.626766] ? _copy_from_user+0x92/0xc0
+[ 916.630773] __sys_sendto+0x202/0x300
+[ 916.634772] ? __ia32_sys_getpeername+0xb0/0xb0
+[ 916.638759] ? lock_acquire+0x380/0x380
+[ 916.642769] ? lock_acquire+0x193/0x380
+[ 916.646761] ? finish_task_switch+0xf4/0x560
+[ 916.650763] ? __schedule+0x582/0x19a0
+[ 916.655301] ? __sched_text_start+0x8/0x8
+[ 916.655301] ? up_read+0x1c/0x110
+[ 916.655301] ? __do_page_fault+0x48b/0xaa0
+[ 916.655301] ? entry_SYSCALL_64_after_hwframe+0x59/0xbe
+[ 916.655301] __x64_sys_sendto+0xdd/0x1b0
+[ 916.655301] do_syscall_64+0x96/0x3d0
+[ 916.655301] entry_SYSCALL_64_after_hwframe+0x49/0xbe
+[ 916.655301] RIP: 0033:0x7f57a0ff5e03
+[ 916.655301] RSP: 002b:00007fff6367e0a8 EFLAGS: 00000246 ORIG_RAX: 000000000000002c
+[ 916.655301] RAX: ffffffffffffffda RBX: 00007fff6367f1e0 RCX: 00007f57a0ff5e03
+[ 916.655301] RDX: 0000000000000020 RSI: 00007fff6367e110 RDI: 0000000000000003
+[ 916.655301] RBP: 00007fff6367e100 R08: 00007f57a0ce9160 R09: 000000000000000c
+[ 916.655301] R10: 0000000000000000 R11: 0000000000000246 R12: 00007fff6367e110
+[ 916.655301] R13: 0000000000000020 R14: 00007f57a153c610 R15: 0000562417258de0
+[ 916.655301] Code: ff ff ff 0f 1f 40 00 66 2e 0f 1f 84 00 00 00 00 00 55 48 89 fa 53 48 c1 ea 03 48 b8 00 00 00 00 00 fc ff df 48 89 fd 48 83 ec 08 <0f> b6 04 02 48 89 fa 83 e2 07 38 d0 7f
+[ 916.655301] RIP: strlen+0x1a/0x90 RSP: ffff88010ff0f2f8
+[ 916.771929] ---[ end trace 1065e048e72479fe ]---
+[ 916.777204] Kernel panic - not syncing: Fatal exception
+[ 916.778158] Kernel Offset: 0x14000000 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
+
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/netfilter/nft_ct.c | 20 ++++++++++++--------
+ 1 file changed, 12 insertions(+), 8 deletions(-)
+
+diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
+index 1678e9e75e8e..2cded8ee6d30 100644
+--- a/net/netfilter/nft_ct.c
++++ b/net/netfilter/nft_ct.c
+@@ -875,22 +875,26 @@ static int nft_ct_helper_obj_dump(struct sk_buff *skb,
+ struct nft_object *obj, bool reset)
+ {
+ const struct nft_ct_helper_obj *priv = nft_obj_data(obj);
+- const struct nf_conntrack_helper *helper = priv->helper4;
++ const struct nf_conntrack_helper *helper;
+ u16 family;
+
++ if (priv->helper4 && priv->helper6) {
++ family = NFPROTO_INET;
++ helper = priv->helper4;
++ } else if (priv->helper6) {
++ family = NFPROTO_IPV6;
++ helper = priv->helper6;
++ } else {
++ family = NFPROTO_IPV4;
++ helper = priv->helper4;
++ }
++
+ if (nla_put_string(skb, NFTA_CT_HELPER_NAME, helper->name))
+ return -1;
+
+ if (nla_put_u8(skb, NFTA_CT_HELPER_L4PROTO, priv->l4proto))
+ return -1;
+
+- if (priv->helper4 && priv->helper6)
+- family = NFPROTO_INET;
+- else if (priv->helper6)
+- family = NFPROTO_IPV6;
+- else
+- family = NFPROTO_IPV4;
+-
+ if (nla_put_be16(skb, NFTA_CT_HELPER_L3PROTO, htons(family)))
+ return -1;
+
+--
+2.12.3
+
diff --git a/patches.fixes/0015-igmp-fix-incorrect-unsolicit-report-count-when-join-.patch b/patches.fixes/0015-igmp-fix-incorrect-unsolicit-report-count-when-join-.patch
new file mode 100644
index 0000000000..64f8a446a1
--- /dev/null
+++ b/patches.fixes/0015-igmp-fix-incorrect-unsolicit-report-count-when-join-.patch
@@ -0,0 +1,39 @@
+From: Hangbin Liu <liuhangbin@gmail.com>
+Subject: igmp: fix incorrect unsolicit report count when join
+ group
+Patch-mainline: v4.19-rc3
+Git-commit: 4fb7253e4f9a8f06a986a3b317e2f79d9b43d552
+References: git-fixes
+
+We should not start timer if im->unsolicit_count equal to 0 after decrease.
+Or we will send one more unsolicit report message. i.e. 3 instead of 2 by
+default.
+
+Fixes: 1da177e4c3f41 ("Linux-2.6.12-rc2")
+Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/ipv4/igmp.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
+index eaec888f3b6c..6afb20af0f93 100644
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -820,10 +820,9 @@ static void igmp_timer_expire(unsigned long data)
+ spin_lock(&im->lock);
+ im->tm_running = 0;
+
+- if (im->unsolicit_count) {
+- im->unsolicit_count--;
++ if (im->unsolicit_count && --im->unsolicit_count)
+ igmp_start_timer(im, unsolicited_report_interval(in_dev));
+- }
++
+ im->reporter = 1;
+ spin_unlock(&im->lock);
+
+--
+2.12.3
+
diff --git a/patches.fixes/0015-netfilter-ebtables-handle-string-from-userspace-with.patch b/patches.fixes/0015-netfilter-ebtables-handle-string-from-userspace-with.patch
new file mode 100644
index 0000000000..f97ecde4f7
--- /dev/null
+++ b/patches.fixes/0015-netfilter-ebtables-handle-string-from-userspace-with.patch
@@ -0,0 +1,102 @@
+From: Paolo Abeni <pabeni@redhat.com>
+Subject: netfilter: ebtables: handle string from userspace with
+ care
+Patch-mainline: v4.17
+Git-commit: 94c752f99954797da583a84c4907ff19e92550a4
+References: git-fixes
+
+strlcpy() can't be safely used on a user-space provided string,
+as it can try to read beyond the buffer's end, if the latter is
+not NULL terminated.
+
+Leveraging the above, syzbot has been able to trigger the following
+splat:
+
+BUG: KASAN: stack-out-of-bounds in strlcpy include/linux/string.h:300
+[inline]
+BUG: KASAN: stack-out-of-bounds in compat_mtw_from_user
+net/bridge/netfilter/ebtables.c:1957 [inline]
+BUG: KASAN: stack-out-of-bounds in ebt_size_mwt
+net/bridge/netfilter/ebtables.c:2059 [inline]
+BUG: KASAN: stack-out-of-bounds in size_entry_mwt
+net/bridge/netfilter/ebtables.c:2155 [inline]
+BUG: KASAN: stack-out-of-bounds in compat_copy_entries+0x96c/0x14a0
+net/bridge/netfilter/ebtables.c:2194
+Write of size 33 at addr ffff8801b0abf888 by task syz-executor0/4504
+
+CPU: 0 PID: 4504 Comm: syz-executor0 Not tainted 4.17.0-rc2+ #40
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
+Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x1b9/0x294 lib/dump_stack.c:113
+ print_address_description+0x6c/0x20b mm/kasan/report.c:256
+ kasan_report_error mm/kasan/report.c:354 [inline]
+ kasan_report.cold.7+0x242/0x2fe mm/kasan/report.c:412
+ check_memory_region_inline mm/kasan/kasan.c:260 [inline]
+ check_memory_region+0x13e/0x1b0 mm/kasan/kasan.c:267
+ memcpy+0x37/0x50 mm/kasan/kasan.c:303
+ strlcpy include/linux/string.h:300 [inline]
+ compat_mtw_from_user net/bridge/netfilter/ebtables.c:1957 [inline]
+ ebt_size_mwt net/bridge/netfilter/ebtables.c:2059 [inline]
+ size_entry_mwt net/bridge/netfilter/ebtables.c:2155 [inline]
+ compat_copy_entries+0x96c/0x14a0 net/bridge/netfilter/ebtables.c:2194
+ compat_do_replace+0x483/0x900 net/bridge/netfilter/ebtables.c:2285
+ compat_do_ebt_set_ctl+0x2ac/0x324 net/bridge/netfilter/ebtables.c:2367
+ compat_nf_sockopt net/netfilter/nf_sockopt.c:144 [inline]
+ compat_nf_setsockopt+0x9b/0x140 net/netfilter/nf_sockopt.c:156
+ compat_ip_setsockopt+0xff/0x140 net/ipv4/ip_sockglue.c:1279
+ inet_csk_compat_setsockopt+0x97/0x120 net/ipv4/inet_connection_sock.c:1041
+ compat_tcp_setsockopt+0x49/0x80 net/ipv4/tcp.c:2901
+ compat_sock_common_setsockopt+0xb4/0x150 net/core/sock.c:3050
+ __compat_sys_setsockopt+0x1ab/0x7c0 net/compat.c:403
+ __do_compat_sys_setsockopt net/compat.c:416 [inline]
+ __se_compat_sys_setsockopt net/compat.c:413 [inline]
+ __ia32_compat_sys_setsockopt+0xbd/0x150 net/compat.c:413
+ do_syscall_32_irqs_on arch/x86/entry/common.c:323 [inline]
+ do_fast_syscall_32+0x345/0xf9b arch/x86/entry/common.c:394
+ entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
+RIP: 0023:0xf7fb3cb9
+RSP: 002b:00000000fff0c26c EFLAGS: 00000282 ORIG_RAX: 000000000000016e
+RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000000000
+RDX: 0000000000000080 RSI: 0000000020000300 RDI: 00000000000005f4
+RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
+
+The buggy address belongs to the page:
+page:ffffea0006c2afc0 count:0 mapcount:0 mapping:0000000000000000 index:0x0
+flags: 0x2fffc0000000000()
+raw: 02fffc0000000000 0000000000000000 0000000000000000 00000000ffffffff
+raw: 0000000000000000 ffffea0006c20101 0000000000000000 0000000000000000
+page dumped because: kasan: bad access detected
+
+Fix the issue replacing the unsafe function with strscpy() and
+taking care of possible errors.
+
+Fixes: 81e675c227ec ("netfilter: ebtables: add CONFIG_COMPAT support")
+Reported-and-tested-by: syzbot+4e42a04e0bc33cb6c087@syzkaller.appspotmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Acked-by: Denis Kirjanov <dkirjanov@suse.com>
+---
+ net/bridge/netfilter/ebtables.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index 9b11e61c4b7e..546c20cf632e 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1950,7 +1950,8 @@ static int compat_mtw_from_user(struct compat_ebt_entry_mwt *mwt,
+ int off, pad = 0;
+ unsigned int size_kern, match_size = mwt->match_size;
+
+- strlcpy(name, mwt->u.name, sizeof(name));
++ if (strscpy(name, mwt->u.name, sizeof(name)) < 0)
++ return -EINVAL;
+
+ if (state->buf_kern_start)
+ dst = state->buf_kern_start + state->buf_kern_offset;
+--
+2.12.3
+
diff --git a/patches.fixes/0016-ipvs-fix-buffer-overflow-with-sync-daemon-and-servic.patch b/patches.fixes/0016-ipvs-fix-buffer-overflow-with-sync-daemon-and-servic.patch
new file mode 100644
index 0000000000..08f73e30d6
--- /dev/null
+++ b/patches.fixes/0016-ipvs-fix-buffer-overflow-with-sync-daemon-and-servic.patch
@@ -0,0 +1,147 @@
+From: Julian Anastasov <ja@ssi.bg>
+Subject: ipvs: fix buffer overflow with sync daemon and service
+Patch-mainline: v4.17
+Git-commit: 52f96757905bbf0edef47f3ee6c7c784e7f8ff8a
+References: git-fixes
+
+syzkaller reports for buffer overflow for interface name
+when starting sync daemons [1]
+
+What we do is that we copy user structure into larger stack
+buffer but later we search NUL past the stack buffer.
+The same happens for sched_name when adding/editing virtual server.
+
+We are restricted by IP_VS_SCHEDNAME_MAXLEN and IP_VS_IFNAME_MAXLEN
+being used as size in include/uapi/linux/ip_vs.h, so they
+include the space for NUL.
+
+As using strlcpy is wrong for unsafe source, replace it with
+strscpy and add checks to return EINVAL if source string is not
+NUL-terminated. The incomplete strlcpy fix comes from 2.6.13.
+
+For the netlink interface reduce the len parameter for
+IPVS_DAEMON_ATTR_MCAST_IFN and IPVS_SVC_ATTR_SCHED_NAME,
+so that we get proper EINVAL.
+
+[1]
+kernel BUG at lib/string.c:1052!
+invalid opcode: 0000 [#1] SMP KASAN
+Dumping ftrace buffer:
+ (ftrace buffer empty)
+Modules linked in:
+CPU: 1 PID: 373 Comm: syz-executor936 Not tainted 4.17.0-rc4+ #45
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
+Google 01/01/2011
+RIP: 0010:fortify_panic+0x13/0x20 lib/string.c:1051
+RSP: 0018:ffff8801c976f800 EFLAGS: 00010282
+RAX: 0000000000000022 RBX: 0000000000000040 RCX: 0000000000000000
+RDX: 0000000000000022 RSI: ffffffff8160f6f1 RDI: ffffed00392edef6
+RBP: ffff8801c976f800 R08: ffff8801cf4c62c0 R09: ffffed003b5e4fb0
+R10: ffffed003b5e4fb0 R11: ffff8801daf27d87 R12: ffff8801c976fa20
+R13: ffff8801c976fae4 R14: ffff8801c976fae0 R15: 000000000000048b
+FS: 00007fd99f75e700(0000) GS:ffff8801daf00000(0000)
+knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00000000200001c0 CR3: 00000001d6843000 CR4: 00000000001406e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ strlen include/linux/string.h:270 [inline]
+ strlcpy include/linux/string.h:293 [inline]
+ do_ip_vs_set_ctl+0x31c/0x1d00 net/netfilter/ipvs/ip_vs_ctl.c:2388
+ nf_sockopt net/netfilter/nf_sockopt.c:106 [inline]
+ nf_setsockopt+0x7d/0xd0 net/netfilter/nf_sockopt.c:115
+ ip_setsockopt+0xd8/0xf0 net/ipv4/ip_sockglue.c:1253
+ udp_setsockopt+0x62/0xa0 net/ipv4/udp.c:2487
+ ipv6_setsockopt+0x149/0x170 net/ipv6/ipv6_sockglue.c:917
+ tcp_setsockopt+0x93/0xe0 net/ipv4/tcp.c:3057
+ sock_common_setsockopt+0x9a/0xe0 net/core/sock.c:3046
+ __sys_setsockopt+0x1bd/0x390 net/socket.c:1903
+ __do_sys_setsockopt net/socket.c:1914 [inline]
+ __se_sys_setsockopt net/socket.c:1911 [inline]
+ __x64_sys_setsockopt+0xbe/0x150 net/socket.c:1911
+ do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+RIP: 0033:0x447369
+RSP: 002b:00007fd99f75dda8 EFLAGS: 00000246 ORIG_RAX: 0000000000000036
+RAX: ffffffffffffffda RBX: 00000000006e39e4 RCX: 0000000000447369
+RDX: 000000000000048b RSI: 0000000000000000 RDI: 0000000000000003
+RBP: 0000000000000000 R08: 0000000000000018 R09: 0000000000000000
+R10: 00000000200001c0 R11: 0000000000000246 R12: 00000000006e39e0
+R13: 75a1ff93f0896195 R14: 6f745f3168746576 R15: 0000000000000001
+Code: 08 5b 41 5c 41 5d 41 5e 41 5f 5d c3 0f 0b 48 89 df