--- /dev/null
+From 5da6bd182471c2371594859e65871bc8e3f78d77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 16 Aug 2020 21:32:17 -0700
+Subject: ALSA: hda/realtek: Add model alc298-samsung-headphone
+
+From: Mike Pozulp <pozulp.kernel@gmail.com>
+
+[ Upstream commit 23dc958689449be85e39351a8c809c3d344b155b ]
+
+The very quiet and distorted headphone output bug that afflicted my
+Samsung Notebook 9 is appearing in many other Samsung laptops. Expose
+the quirk which fixed my laptop as a model so other users can try it.
+
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=207423
+Signed-off-by: Mike Pozulp <pozulp.kernel@gmail.com>
+Link: https://lore.kernel.org/r/20200817043219.458889-1-pozulp.kernel@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index b767d8fce828e..da23c2d4ca51e 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -7969,6 +7969,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
+ {.id = ALC299_FIXUP_PREDATOR_SPK, .name = "predator-spk"},
+ {.id = ALC298_FIXUP_HUAWEI_MBX_STEREO, .name = "huawei-mbx-stereo"},
+ {.id = ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE, .name = "alc256-medion-headset"},
++ {.id = ALC298_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET, .name = "alc298-samsung-headphone"},
+ {}
+ };
+ #define ALC225_STANDARD_PINS \
+--
+2.25.1
+
--- /dev/null
+From 084eba58f9b8f3af2ebf49efb48b3183516a3deb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Aug 2020 01:20:11 +0800
+Subject: ALSA: usb-audio: ignore broken processing/extension unit
+
+From: Tom Yan <tom.ty89@gmail.com>
+
+[ Upstream commit d8d0db7bb358ef65d60726a61bfcd08eccff0bc0 ]
+
+Some devices have broken extension unit where getting current value
+doesn't work. Attempt that once when creating mixer control for it. If
+it fails, just ignore it, so that it won't cripple the device entirely
+(and/or make the error floods).
+
+Signed-off-by: Tom Yan <tom.ty89@gmail.com>
+Link: https://lore.kernel.org/r/5f3abc52.1c69fb81.9cf2.fe91@mx.google.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/usb/mixer.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index eab0fd4fd7c33..e0b7174c10430 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -2367,7 +2367,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
+ int num_ins;
+ struct usb_mixer_elem_info *cval;
+ struct snd_kcontrol *kctl;
+- int i, err, nameid, type, len;
++ int i, err, nameid, type, len, val;
+ const struct procunit_info *info;
+ const struct procunit_value_info *valinfo;
+ const struct usbmix_name_map *map;
+@@ -2470,6 +2470,12 @@ static int build_audio_procunit(struct mixer_build *state, int unitid,
+ break;
+ }
+
++ err = get_cur_ctl_value(cval, cval->control << 8, &val);
++ if (err < 0) {
++ usb_mixer_elem_info_free(cval);
++ return -EINVAL;
++ }
++
+ kctl = snd_ctl_new1(&mixer_procunit_ctl, cval);
+ if (!kctl) {
+ usb_mixer_elem_info_free(cval);
+--
+2.25.1
+
--- /dev/null
+From 6fb9aa4e7c835007152ed40ac8b64c2ae60c1ad2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2020 18:38:24 +0100
+Subject: arm64: Allow booting of late CPUs affected by erratum 1418040
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit bf87bb0881d0f59181fe3bbcf29c609f36483ff8 ]
+
+As we can now switch from a system that isn't affected by 1418040
+to a system that globally is affected, let's allow affected CPUs
+to come in at a later time.
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20200731173824.107480-3-maz@kernel.org
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/cpu_errata.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
+index 79728bfb5351f..2c0b82db825ba 100644
+--- a/arch/arm64/kernel/cpu_errata.c
++++ b/arch/arm64/kernel/cpu_errata.c
+@@ -910,6 +910,8 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
+ .desc = "ARM erratum 1418040",
+ .capability = ARM64_WORKAROUND_1418040,
+ ERRATA_MIDR_RANGE_LIST(erratum_1418040_list),
++ .type = (ARM64_CPUCAP_SCOPE_LOCAL_CPU |
++ ARM64_CPUCAP_PERMITTED_FOR_LATE_CPU),
+ },
+ #endif
+ #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT
+--
+2.25.1
+
--- /dev/null
+From e78241b27fcaa911b44179d6f705aef93bc9f830 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2020 18:38:23 +0100
+Subject: arm64: Move handling of erratum 1418040 into C code
+
+From: Marc Zyngier <maz@kernel.org>
+
+[ Upstream commit d49f7d7376d0c0daf8680984a37bd07581ac7d38 ]
+
+Instead of dealing with erratum 1418040 on each entry and exit,
+let's move the handling to __switch_to() instead, which has
+several advantages:
+
+- It can be applied when it matters (switching between 32 and 64
+ bit tasks).
+- It is written in C (yay!)
+- It can rely on static keys rather than alternatives
+
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Tested-by: Sai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
+Reviewed-by: Stephen Boyd <swboyd@chromium.org>
+Acked-by: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20200731173824.107480-2-maz@kernel.org
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/entry.S | 21 ---------------------
+ arch/arm64/kernel/process.c | 34 ++++++++++++++++++++++++++++++++++
+ 2 files changed, 34 insertions(+), 21 deletions(-)
+
+diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
+index 35de8ba60e3d5..44445d471442d 100644
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -169,19 +169,6 @@ alternative_cb_end
+ stp x28, x29, [sp, #16 * 14]
+
+ .if \el == 0
+- .if \regsize == 32
+- /*
+- * If we're returning from a 32-bit task on a system affected by
+- * 1418040 then re-enable userspace access to the virtual counter.
+- */
+-#ifdef CONFIG_ARM64_ERRATUM_1418040
+-alternative_if ARM64_WORKAROUND_1418040
+- mrs x0, cntkctl_el1
+- orr x0, x0, #2 // ARCH_TIMER_USR_VCT_ACCESS_EN
+- msr cntkctl_el1, x0
+-alternative_else_nop_endif
+-#endif
+- .endif
+ clear_gp_regs
+ mrs x21, sp_el0
+ ldr_this_cpu tsk, __entry_task, x20
+@@ -337,14 +324,6 @@ alternative_else_nop_endif
+ tst x22, #PSR_MODE32_BIT // native task?
+ b.eq 3f
+
+-#ifdef CONFIG_ARM64_ERRATUM_1418040
+-alternative_if ARM64_WORKAROUND_1418040
+- mrs x0, cntkctl_el1
+- bic x0, x0, #2 // ARCH_TIMER_USR_VCT_ACCESS_EN
+- msr cntkctl_el1, x0
+-alternative_else_nop_endif
+-#endif
+-
+ #ifdef CONFIG_ARM64_ERRATUM_845719
+ alternative_if ARM64_WORKAROUND_845719
+ #ifdef CONFIG_PID_IN_CONTEXTIDR
+diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
+index 6089638c7d43f..d8a10cf28f827 100644
+--- a/arch/arm64/kernel/process.c
++++ b/arch/arm64/kernel/process.c
+@@ -515,6 +515,39 @@ static void entry_task_switch(struct task_struct *next)
+ __this_cpu_write(__entry_task, next);
+ }
+
++/*
++ * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT.
++ * Assuming the virtual counter is enabled at the beginning of times:
++ *
++ * - disable access when switching from a 64bit task to a 32bit task
++ * - enable access when switching from a 32bit task to a 64bit task
++ */
++static void erratum_1418040_thread_switch(struct task_struct *prev,
++ struct task_struct *next)
++{
++ bool prev32, next32;
++ u64 val;
++
++ if (!(IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040) &&
++ cpus_have_const_cap(ARM64_WORKAROUND_1418040)))
++ return;
++
++ prev32 = is_compat_thread(task_thread_info(prev));
++ next32 = is_compat_thread(task_thread_info(next));
++
++ if (prev32 == next32)
++ return;
++
++ val = read_sysreg(cntkctl_el1);
++
++ if (!next32)
++ val |= ARCH_TIMER_USR_VCT_ACCESS_EN;
++ else
++ val &= ~ARCH_TIMER_USR_VCT_ACCESS_EN;
++
++ write_sysreg(val, cntkctl_el1);
++}
++
+ /*
+ * Thread switching.
+ */
+@@ -530,6 +563,7 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
+ entry_task_switch(next);
+ uao_thread_switch(next);
+ ssbs_thread_switch(next);
++ erratum_1418040_thread_switch(prev, next);
+
+ /*
+ * Complete any pending TLB or cache maintenance on this CPU in case
+--
+2.25.1
+
--- /dev/null
+From 8971bdd057002dd9f10ac70f07fd6636927bd082 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2020 19:38:34 +0200
+Subject: ASoC: wm8994: Avoid attempts to read unreadable registers
+
+From: Sylwester Nawrocki <s.nawrocki@samsung.com>
+
+[ Upstream commit f082bb59b72039a2326ec1a44496899fb8aa6d0e ]
+
+The driver supports WM1811, WM8994, WM8958 devices but according to
+documentation and the regmap definitions the WM8958_DSP2_* registers
+are only available on WM8958. In current code these registers are
+being accessed as if they were available on all the three chips.
+
+When starting playback on WM1811 CODEC multiple errors like:
+"wm8994-codec wm8994-codec: ASoC: error at soc_component_read_no_lock on wm8994-codec: -5"
+can be seen, which is caused by attempts to read an unavailable
+WM8958_DSP2_PROGRAM register. The issue has been uncovered by recent
+commit "e2329ee ASoC: soc-component: add soc_component_err()".
+
+This patch adds a check in wm8958_aif_ev() callback so the DSP2 handling
+is only done for WM8958.
+
+Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
+Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20200731173834.23832-1-s.nawrocki@samsung.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/codecs/wm8958-dsp2.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c
+index ca42445b649d4..b471892d84778 100644
+--- a/sound/soc/codecs/wm8958-dsp2.c
++++ b/sound/soc/codecs/wm8958-dsp2.c
+@@ -412,8 +412,12 @@ int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+ {
+ struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
++ struct wm8994 *control = dev_get_drvdata(component->dev->parent);
+ int i;
+
++ if (control->type != WM8958)
++ return 0;
++
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ case SND_SOC_DAPM_PRE_PMU:
+--
+2.25.1
+
--- /dev/null
+From 03fc22c71dac02d2ea51c25627819d3c7e6e46ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Aug 2020 06:43:40 +0000
+Subject: bfq: fix blkio cgroup leakage v4
+
+From: Dmitry Monakhov <dmtrmonakhov@yandex-team.ru>
+
+[ Upstream commit 2de791ab4918969d8108f15238a701968375f235 ]
+
+Changes from v1:
+ - update commit description with proper ref-accounting justification
+
+commit db37a34c563b ("block, bfq: get a ref to a group when adding it to a service tree")
+introduce leak forbfq_group and blkcg_gq objects because of get/put
+imbalance.
+In fact whole idea of original commit is wrong because bfq_group entity
+can not dissapear under us because it is referenced by child bfq_queue's
+entities from here:
+ -> bfq_init_entity()
+ ->bfqg_and_blkg_get(bfqg);
+ ->entity->parent = bfqg->my_entity
+
+ -> bfq_put_queue(bfqq)
+ FINAL_PUT
+ ->bfqg_and_blkg_put(bfqq_group(bfqq))
+ ->kmem_cache_free(bfq_pool, bfqq);
+
+So parent entity can not disappear while child entity is in tree,
+and child entities already has proper protection.
+This patch revert commit db37a34c563b ("block, bfq: get a ref to a group when adding it to a service tree")
+
+bfq_group leak trace caused by bad commit:
+-> blkg_alloc
+ -> bfq_pq_alloc
+ -> bfqg_get (+1)
+->bfq_activate_bfqq
+ ->bfq_activate_requeue_entity
+ -> __bfq_activate_entity
+ ->bfq_get_entity
+ ->bfqg_and_blkg_get (+1) <==== : Note1
+->bfq_del_bfqq_busy
+ ->bfq_deactivate_entity+0x53/0xc0 [bfq]
+ ->__bfq_deactivate_entity+0x1b8/0x210 [bfq]
+ -> bfq_forget_entity(is_in_service = true)
+ entity->on_st_or_in_serv = false <=== :Note2
+ if (is_in_service)
+ return; ==> do not touch reference
+-> blkcg_css_offline
+ -> blkcg_destroy_blkgs
+ -> blkg_destroy
+ -> bfq_pd_offline
+ -> __bfq_deactivate_entity
+ if (!entity->on_st_or_in_serv) /* true, because (Note2)
+ return false;
+ -> bfq_pd_free
+ -> bfqg_put() (-1, byt bfqg->ref == 2) because of (Note2)
+So bfq_group and blkcg_gq will leak forever, see test-case below.
+
+##TESTCASE_BEGIN:
+#!/bin/bash
+
+max_iters=${1:-100}
+#prep cgroup mounts
+mount -t tmpfs cgroup_root /sys/fs/cgroup
+mkdir /sys/fs/cgroup/blkio
+mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
+
+# Prepare blkdev
+grep blkio /proc/cgroups
+truncate -s 1M img
+losetup /dev/loop0 img
+echo bfq > /sys/block/loop0/queue/scheduler
+
+grep blkio /proc/cgroups
+for ((i=0;i<max_iters;i++))
+do
+ mkdir -p /sys/fs/cgroup/blkio/a
+ echo 0 > /sys/fs/cgroup/blkio/a/cgroup.procs
+ dd if=/dev/loop0 bs=4k count=1 of=/dev/null iflag=direct 2> /dev/null
+ echo 0 > /sys/fs/cgroup/blkio/cgroup.procs
+ rmdir /sys/fs/cgroup/blkio/a
+ grep blkio /proc/cgroups
+done
+##TESTCASE_END:
+
+Fixes: db37a34c563b ("block, bfq: get a ref to a group when adding it to a service tree")
+Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
+Signed-off-by: Dmitry Monakhov <dmtrmonakhov@yandex-team.ru>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bfq-cgroup.c | 2 +-
+ block/bfq-iosched.h | 1 -
+ block/bfq-wf2q.c | 12 ++----------
+ 3 files changed, 3 insertions(+), 12 deletions(-)
+
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 68882b9b8f11f..b791e2041e49b 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -332,7 +332,7 @@ static void bfqg_put(struct bfq_group *bfqg)
+ kfree(bfqg);
+ }
+
+-void bfqg_and_blkg_get(struct bfq_group *bfqg)
++static void bfqg_and_blkg_get(struct bfq_group *bfqg)
+ {
+ /* see comments in bfq_bic_update_cgroup for why refcounting bfqg */
+ bfqg_get(bfqg);
+diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h
+index cd224aaf9f52a..703895224562c 100644
+--- a/block/bfq-iosched.h
++++ b/block/bfq-iosched.h
+@@ -986,7 +986,6 @@ struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,
+ struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg);
+ struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
+ struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node);
+-void bfqg_and_blkg_get(struct bfq_group *bfqg);
+ void bfqg_and_blkg_put(struct bfq_group *bfqg);
+
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+diff --git a/block/bfq-wf2q.c b/block/bfq-wf2q.c
+index eb0e2a6daabe6..26776bdbdf360 100644
+--- a/block/bfq-wf2q.c
++++ b/block/bfq-wf2q.c
+@@ -533,9 +533,7 @@ static void bfq_get_entity(struct bfq_entity *entity)
+ bfqq->ref++;
+ bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
+ bfqq, bfqq->ref);
+- } else
+- bfqg_and_blkg_get(container_of(entity, struct bfq_group,
+- entity));
++ }
+ }
+
+ /**
+@@ -649,14 +647,8 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
+
+ entity->on_st_or_in_serv = false;
+ st->wsum -= entity->weight;
+- if (is_in_service)
+- return;
+-
+- if (bfqq)
++ if (bfqq && !is_in_service)
+ bfq_put_queue(bfqq);
+- else
+- bfqg_and_blkg_put(container_of(entity, struct bfq_group,
+- entity));
+ }
+
+ /**
+--
+2.25.1
+
--- /dev/null
+From e061367f4b90fecb16ae550c569962145575fe00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Aug 2020 17:07:28 +0800
+Subject: blk-mq: insert request not through ->queue_rq into sw/scheduler queue
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit db03f88fae8a2c8007caafa70287798817df2875 ]
+
+c616cbee97ae ("blk-mq: punt failed direct issue to dispatch list") supposed
+to add request which has been through ->queue_rq() to the hw queue dispatch
+list, however it adds request running out of budget or driver tag to hw queue
+too. This way basically bypasses request merge, and causes too many request
+dispatched to LLD, and system% is unnecessary increased.
+
+Fixes this issue by adding request not through ->queue_rq into sw/scheduler
+queue, and this way is safe because no ->queue_rq is called on this request
+yet.
+
+High %system can be observed on Azure storvsc device, and even soft lock
+is observed. This patch reduces %system during heavy sequential IO,
+meantime decreases soft lockup risk.
+
+Fixes: c616cbee97ae ("blk-mq: punt failed direct issue to dispatch list")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Bart Van Assche <bvanassche@acm.org>
+Cc: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 4e0d173beaa35..e86ccfe377779 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1909,7 +1909,8 @@ insert:
+ if (bypass_insert)
+ return BLK_STS_RESOURCE;
+
+- blk_mq_request_bypass_insert(rq, false, run_queue);
++ blk_mq_sched_insert_request(rq, false, run_queue, false);
++
+ return BLK_STS_OK;
+ }
+
+--
+2.25.1
+
--- /dev/null
+From f62bdb60b12d88f70c591c7306c7f0e926c52b93 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Aug 2020 22:21:16 -0400
+Subject: blkcg: fix memleak for iolatency
+
+From: Yufen Yu <yuyufen@huawei.com>
+
+[ Upstream commit 27029b4b18aa5d3b060f0bf2c26dae254132cfce ]
+
+Normally, blkcg_iolatency_exit() will free related memory in iolatency
+when cleanup queue. But if blk_throtl_init() return error and queue init
+fail, blkcg_iolatency_exit() will not do that for us. Then it cause
+memory leak.
+
+Fixes: d70675121546 ("block: introduce blk-iolatency io controller")
+Signed-off-by: Yufen Yu <yuyufen@huawei.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-cgroup.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index 0ecc897b225c9..6e8f5e60b0982 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -1056,13 +1056,15 @@ int blkcg_init_queue(struct request_queue *q)
+ if (preloaded)
+ radix_tree_preload_end();
+
+- ret = blk_iolatency_init(q);
++ ret = blk_throtl_init(q);
+ if (ret)
+ goto err_destroy_all;
+
+- ret = blk_throtl_init(q);
+- if (ret)
++ ret = blk_iolatency_init(q);
++ if (ret) {
++ blk_throtl_exit(q);
+ goto err_destroy_all;
++ }
+ return 0;
+
+ err_destroy_all:
+--
+2.25.1
+
--- /dev/null
+From 701dcb0f3f87ec60d43da34d9b298ef9a2785fa7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Aug 2020 20:52:06 +0100
+Subject: block: Fix page_is_mergeable() for compound pages
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit d81665198b83e55a28339d1f3e4890ed8a434556 ]
+
+If we pass in an offset which is larger than PAGE_SIZE, then
+page_is_mergeable() thinks it's not mergeable with the previous bio_vec,
+leading to a large number of bio_vecs being used. Use a slightly more
+obvious test that the two pages are compatible with each other.
+
+Fixes: 52d52d1c98a9 ("block: only allow contiguous page structs in a bio_vec")
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/bio.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/block/bio.c b/block/bio.c
+index a7366c02c9b57..b1883adc8f154 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -738,8 +738,8 @@ static inline bool page_is_mergeable(const struct bio_vec *bv,
+ struct page *page, unsigned int len, unsigned int off,
+ bool *same_page)
+ {
+- phys_addr_t vec_end_addr = page_to_phys(bv->bv_page) +
+- bv->bv_offset + bv->bv_len - 1;
++ size_t bv_end = bv->bv_offset + bv->bv_len;
++ phys_addr_t vec_end_addr = page_to_phys(bv->bv_page) + bv_end - 1;
+ phys_addr_t page_addr = page_to_phys(page);
+
+ if (vec_end_addr + 1 != page_addr + off)
+@@ -748,9 +748,9 @@ static inline bool page_is_mergeable(const struct bio_vec *bv,
+ return false;
+
+ *same_page = ((vec_end_addr & PAGE_MASK) == page_addr);
+- if (!*same_page && pfn_to_page(PFN_DOWN(vec_end_addr)) + 1 != page)
+- return false;
+- return true;
++ if (*same_page)
++ return true;
++ return (bv->bv_page + bv_end / PAGE_SIZE) == (page + off / PAGE_SIZE);
+ }
+
+ /*
+--
+2.25.1
+
--- /dev/null
+From cc797dd7742c1cee85ef42d6c89186c10c75f4fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Aug 2020 17:52:39 +0800
+Subject: block: respect queue limit of max discard segment
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 943b40c832beb71115e38a1c4d99b640b5342738 ]
+
+When queue_max_discard_segments(q) is 1, blk_discard_mergable() will
+return false for discard request, then normal request merge is applied.
+However, only queue_max_segments() is checked, so max discard segment
+limit isn't respected.
+
+Check max discard segment limit in the request merge code for fixing
+the issue.
+
+Discard request failure of virtio_blk is fixed.
+
+Fixes: 69840466086d ("block: fix the DISCARD request merge")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-merge.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index f0b0bae075a0c..0b590907676af 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -534,10 +534,17 @@ int __blk_rq_map_sg(struct request_queue *q, struct request *rq,
+ }
+ EXPORT_SYMBOL(__blk_rq_map_sg);
+
++static inline unsigned int blk_rq_get_max_segments(struct request *rq)
++{
++ if (req_op(rq) == REQ_OP_DISCARD)
++ return queue_max_discard_segments(rq->q);
++ return queue_max_segments(rq->q);
++}
++
+ static inline int ll_new_hw_segment(struct request *req, struct bio *bio,
+ unsigned int nr_phys_segs)
+ {
+- if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(req->q))
++ if (req->nr_phys_segments + nr_phys_segs > blk_rq_get_max_segments(req))
+ goto no_merge;
+
+ if (blk_integrity_merge_bio(req->q, req, bio) == false)
+@@ -625,7 +632,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
+ return 0;
+
+ total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
+- if (total_phys_segments > queue_max_segments(q))
++ if (total_phys_segments > blk_rq_get_max_segments(req))
+ return 0;
+
+ if (blk_integrity_merge_rq(q, req, next) == false)
+--
+2.25.1
+
--- /dev/null
+From ada8a136cebd4bc70bf800dddd7b005772446f4d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Aug 2020 17:52:40 +0800
+Subject: block: virtio_blk: fix handling single range discard request
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit af822aa68fbdf0a480a17462ed70232998127453 ]
+
+1f23816b8eb8 ("virtio_blk: add discard and write zeroes support") starts
+to support multi-range discard for virtio-blk. However, the virtio-blk
+disk may report max discard segment as 1, at least that is exactly what
+qemu is doing.
+
+So far, block layer switches to normal request merge if max discard segment
+limit is 1, and multiple bios can be merged to single segment. This way may
+cause memory corruption in virtblk_setup_discard_write_zeroes().
+
+Fix the issue by handling single max discard segment in straightforward
+way.
+
+Fixes: 1f23816b8eb8 ("virtio_blk: add discard and write zeroes support")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Changpeng Liu <changpeng.liu@intel.com>
+Cc: Daniel Verkamp <dverkamp@chromium.org>
+Cc: Michael S. Tsirkin <mst@redhat.com>
+Cc: Stefan Hajnoczi <stefanha@redhat.com>
+Cc: Stefano Garzarella <sgarzare@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/virtio_blk.c | 31 +++++++++++++++++++++++--------
+ 1 file changed, 23 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
+index 980df853ee497..99991b6a6f0ed 100644
+--- a/drivers/block/virtio_blk.c
++++ b/drivers/block/virtio_blk.c
+@@ -126,16 +126,31 @@ static int virtblk_setup_discard_write_zeroes(struct request *req, bool unmap)
+ if (!range)
+ return -ENOMEM;
+
+- __rq_for_each_bio(bio, req) {
+- u64 sector = bio->bi_iter.bi_sector;
+- u32 num_sectors = bio->bi_iter.bi_size >> SECTOR_SHIFT;
+-
+- range[n].flags = cpu_to_le32(flags);
+- range[n].num_sectors = cpu_to_le32(num_sectors);
+- range[n].sector = cpu_to_le64(sector);
+- n++;
++ /*
++ * Single max discard segment means multi-range discard isn't
++ * supported, and block layer only runs contiguity merge like
++ * normal RW request. So we can't reply on bio for retrieving
++ * each range info.
++ */
++ if (queue_max_discard_segments(req->q) == 1) {
++ range[0].flags = cpu_to_le32(flags);
++ range[0].num_sectors = cpu_to_le32(blk_rq_sectors(req));
++ range[0].sector = cpu_to_le64(blk_rq_pos(req));
++ n = 1;
++ } else {
++ __rq_for_each_bio(bio, req) {
++ u64 sector = bio->bi_iter.bi_sector;
++ u32 num_sectors = bio->bi_iter.bi_size >> SECTOR_SHIFT;
++
++ range[n].flags = cpu_to_le32(flags);
++ range[n].num_sectors = cpu_to_le32(num_sectors);
++ range[n].sector = cpu_to_le64(sector);
++ n++;
++ }
+ }
+
++ WARN_ON_ONCE(n != segments);
++
+ req->special_vec.bv_page = virt_to_page(range);
+ req->special_vec.bv_offset = offset_in_page(range);
+ req->special_vec.bv_len = sizeof(*range) * segments;
+--
+2.25.1
+
--- /dev/null
+From 0b71087651754bc5f2d6f2f1edecc4d12f12132c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Aug 2020 15:23:10 -0700
+Subject: bpf: Avoid visit same object multiple times
+
+From: Yonghong Song <yhs@fb.com>
+
+[ Upstream commit e60572b8d4c39572be6857d1ec91fdf979f8775f ]
+
+Currently when traversing all tasks, the next tid
+is always increased by one. This may result in
+visiting the same task multiple times in a
+pid namespace.
+
+This patch fixed the issue by seting the next
+tid as pid_nr_ns(pid, ns) + 1, similar to
+funciton next_tgid().
+
+Signed-off-by: Yonghong Song <yhs@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Cc: Rik van Riel <riel@surriel.com>
+Link: https://lore.kernel.org/bpf/20200818222310.2181500-1-yhs@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/task_iter.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/task_iter.c b/kernel/bpf/task_iter.c
+index a4a0fb4f94cc1..323def936be24 100644
+--- a/kernel/bpf/task_iter.c
++++ b/kernel/bpf/task_iter.c
+@@ -28,8 +28,9 @@ static struct task_struct *task_seq_get_next(struct pid_namespace *ns,
+
+ rcu_read_lock();
+ retry:
+- pid = idr_get_next(&ns->idr, tid);
++ pid = find_ge_pid(*tid, ns);
+ if (pid) {
++ *tid = pid_nr_ns(pid, ns);
+ task = get_pid_task(pid, PIDTYPE_PID);
+ if (!task) {
+ ++*tid;
+--
+2.25.1
+
--- /dev/null
+From 3e75330684248e9490cd578040e1346bc7e21ea6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Aug 2020 15:23:09 -0700
+Subject: bpf: Fix a rcu_sched stall issue with bpf task/task_file iterator
+
+From: Yonghong Song <yhs@fb.com>
+
+[ Upstream commit e679654a704e5bd676ea6446fa7b764cbabf168a ]
+
+In our production system, we observed rcu stalls when
+'bpftool prog` is running.
+ rcu: INFO: rcu_sched self-detected stall on CPU
+ rcu: \x097-....: (20999 ticks this GP) idle=302/1/0x4000000000000000 softirq=1508852/1508852 fqs=4913
+ \x09(t=21031 jiffies g=2534773 q=179750)
+ NMI backtrace for cpu 7
+ CPU: 7 PID: 184195 Comm: bpftool Kdump: loaded Tainted: G W 5.8.0-00004-g68bfc7f8c1b4 #6
+ Hardware name: Quanta Twin Lakes MP/Twin Lakes Passive MP, BIOS F09_3A17 05/03/2019
+ Call Trace:
+ <IRQ>
+ dump_stack+0x57/0x70
+ nmi_cpu_backtrace.cold+0x14/0x53
+ ? lapic_can_unplug_cpu.cold+0x39/0x39
+ nmi_trigger_cpumask_backtrace+0xb7/0xc7
+ rcu_dump_cpu_stacks+0xa2/0xd0
+ rcu_sched_clock_irq.cold+0x1ff/0x3d9
+ ? tick_nohz_handler+0x100/0x100
+ update_process_times+0x5b/0x90
+ tick_sched_timer+0x5e/0xf0
+ __hrtimer_run_queues+0x12a/0x2a0
+ hrtimer_interrupt+0x10e/0x280
+ __sysvec_apic_timer_interrupt+0x51/0xe0
+ asm_call_on_stack+0xf/0x20
+ </IRQ>
+ sysvec_apic_timer_interrupt+0x6f/0x80
+ asm_sysvec_apic_timer_interrupt+0x12/0x20
+ RIP: 0010:task_file_seq_get_next+0x71/0x220
+ Code: 00 00 8b 53 1c 49 8b 7d 00 89 d6 48 8b 47 20 44 8b 18 41 39 d3 76 75 48 8b 4f 20 8b 01 39 d0 76 61 41 89 d1 49 39 c1 48 19 c0 <48> 8b 49 08 21 d0 48 8d 04 c1 4c 8b 08 4d 85 c9 74 46 49 8b 41 38
+ RSP: 0018:ffffc90006223e10 EFLAGS: 00000297
+ RAX: ffffffffffffffff RBX: ffff888f0d172388 RCX: ffff888c8c07c1c0
+ RDX: 00000000000f017b RSI: 00000000000f017b RDI: ffff888c254702c0
+ RBP: ffffc90006223e68 R08: ffff888be2a1c140 R09: 00000000000f017b
+ R10: 0000000000000002 R11: 0000000000100000 R12: ffff888f23c24118
+ R13: ffffc90006223e60 R14: ffffffff828509a0 R15: 00000000ffffffff
+ task_file_seq_next+0x52/0xa0
+ bpf_seq_read+0xb9/0x320
+ vfs_read+0x9d/0x180
+ ksys_read+0x5f/0xe0
+ do_syscall_64+0x38/0x60
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+ RIP: 0033:0x7f8815f4f76e
+ Code: c0 e9 f6 fe ff ff 55 48 8d 3d 76 70 0a 00 48 89 e5 e8 36 06 02 00 66 0f 1f 44 00 00 64 8b 04 25 18 00 00 00 85 c0 75 14 0f 05 <48> 3d 00 f0 ff ff 77 52 c3 66 0f 1f 84 00 00 00 00 00 55 48 89 e5
+ RSP: 002b:00007fff8f9df578 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
+ RAX: ffffffffffffffda RBX: 000000000170b9c0 RCX: 00007f8815f4f76e
+ RDX: 0000000000001000 RSI: 00007fff8f9df5b0 RDI: 0000000000000007
+ RBP: 00007fff8f9e05f0 R08: 0000000000000049 R09: 0000000000000010
+ R10: 00007f881601fa40 R11: 0000000000000246 R12: 00007fff8f9e05a8
+ R13: 00007fff8f9e05a8 R14: 0000000001917f90 R15: 000000000000e22e
+
+Note that `bpftool prog` actually calls a task_file bpf iterator
+program to establish an association between prog/map/link/btf anon
+files and processes.
+
+In the case where the above rcu stall occured, we had a process
+having 1587 tasks and each task having roughly 81305 files.
+This implied 129 million bpf prog invocations. Unfortunwtely none of
+these files are prog/map/link/btf files so bpf iterator/prog needs
+to traverse all these files and not able to return to user space
+since there are no seq_file buffer overflow.
+
+This patch fixed the issue in bpf_seq_read() to limit the number
+of visited objects. If the maximum number of visited objects is
+reached, no more objects will be visited in the current syscall.
+If there is nothing written in the seq_file buffer, -EAGAIN will
+return to the user so user can try again.
+
+The maximum number of visited objects is set at 1 million.
+In our Intel Xeon D-2191 2.3GHZ 18-core server, bpf_seq_read()
+visiting 1 million files takes around 0.18 seconds.
+
+We did not use cond_resched() since for some iterators, e.g.,
+netlink iterator, where rcu read_lock critical section spans between
+consecutive seq_ops->next(), which makes impossible to do cond_resched()
+in the key while loop of function bpf_seq_read().
+
+Signed-off-by: Yonghong Song <yhs@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Cc: Paul E. McKenney <paulmck@kernel.org>
+Link: https://lore.kernel.org/bpf/20200818222309.2181348-1-yhs@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/bpf_iter.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c
+index dd612b80b9fea..3c18090cd73dc 100644
+--- a/kernel/bpf/bpf_iter.c
++++ b/kernel/bpf/bpf_iter.c
+@@ -64,6 +64,9 @@ static void bpf_iter_done_stop(struct seq_file *seq)
+ iter_priv->done_stop = true;
+ }
+
++/* maximum visited objects before bailing out */
++#define MAX_ITER_OBJECTS 1000000
++
+ /* bpf_seq_read, a customized and simpler version for bpf iterator.
+ * no_llseek is assumed for this file.
+ * The following are differences from seq_read():
+@@ -76,7 +79,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size,
+ {
+ struct seq_file *seq = file->private_data;
+ size_t n, offs, copied = 0;
+- int err = 0;
++ int err = 0, num_objs = 0;
+ void *p;
+
+ mutex_lock(&seq->lock);
+@@ -132,6 +135,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size,
+ while (1) {
+ loff_t pos = seq->index;
+
++ num_objs++;
+ offs = seq->count;
+ p = seq->op->next(seq, p, &seq->index);
+ if (pos == seq->index) {
+@@ -150,6 +154,15 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size,
+ if (seq->count >= size)
+ break;
+
++ if (num_objs >= MAX_ITER_OBJECTS) {
++ if (offs == 0) {
++ err = -EAGAIN;
++ seq->op->stop(seq, p);
++ goto done;
++ }
++ break;
++ }
++
+ err = seq->op->show(seq, p);
+ if (err > 0) {
+ bpf_iter_dec_seq_num(seq);
+--
+2.25.1
+
--- /dev/null
+From a9dd3e08dd0228414e4bac95d10d2d1bc140e6d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Aug 2020 14:58:43 +0300
+Subject: bpf: selftests: global_funcs: Check err_str before strstr
+
+From: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
+
+[ Upstream commit c210773d6c6f595f5922d56b7391fe343bc7310e ]
+
+The error path in libbpf.c:load_program() has calls to pr_warn()
+which ends up for global_funcs tests to
+test_global_funcs.c:libbpf_debug_print().
+
+For the tests with no struct test_def::err_str initialized with a
+string, it causes call of strstr() with NULL as the second argument
+and it segfaults.
+
+Fix it by calling strstr() only for non-NULL err_str.
+
+Signed-off-by: Yauheni Kaliuta <yauheni.kaliuta@redhat.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20200820115843.39454-1-yauheni.kaliuta@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/test_global_funcs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
+index 25b068591e9a4..193002b14d7f6 100644
+--- a/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
++++ b/tools/testing/selftests/bpf/prog_tests/test_global_funcs.c
+@@ -19,7 +19,7 @@ static int libbpf_debug_print(enum libbpf_print_level level,
+ log_buf = va_arg(args, char *);
+ if (!log_buf)
+ goto out;
+- if (strstr(log_buf, err_str) == 0)
++ if (err_str && strstr(log_buf, err_str) == 0)
+ found = true;
+ out:
+ printf(format, log_buf);
+--
+2.25.1
+
--- /dev/null
+From 93efed3f3bddc4323648509c89d2f45bb3c16f4a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Aug 2020 12:52:00 +0200
+Subject: can: j1939: transport: j1939_xtp_rx_dat_one(): compare own packets to
+ detect corruptions
+
+From: Oleksij Rempel <o.rempel@pengutronix.de>
+
+[ Upstream commit e052d0540298bfe0f6cbbecdc7e2ea9b859575b2 ]
+
+Since the stack relays on receiving own packets, it was overwriting own
+transmit buffer from received packets.
+
+At least theoretically, the received echo buffer can be corrupt or
+changed and the session partner can request to resend previous data. In
+this case we will re-send bad data.
+
+With this patch we will stop to overwrite own TX buffer and use it for
+sanity checking.
+
+Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
+Link: https://lore.kernel.org/r/20200807105200.26441-6-o.rempel@pengutronix.de
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/can/j1939/transport.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c
+index dbd215cbc53d8..a8dd956b5e8e1 100644
+--- a/net/can/j1939/transport.c
++++ b/net/can/j1939/transport.c
+@@ -1803,7 +1803,20 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
+ }
+
+ tpdat = se_skb->data;
+- memcpy(&tpdat[offset], &dat[1], nbytes);
++ if (!session->transmission) {
++ memcpy(&tpdat[offset], &dat[1], nbytes);
++ } else {
++ int err;
++
++ err = memcmp(&tpdat[offset], &dat[1], nbytes);
++ if (err)
++ netdev_err_once(priv->ndev,
++ "%s: 0x%p: Data of RX-looped back packet (%*ph) doesn't match TX data (%*ph)!\n",
++ __func__, session,
++ nbytes, &dat[1],
++ nbytes, &tpdat[offset]);
++ }
++
+ if (packet == session->pkt.rx)
+ session->pkt.rx++;
+
+--
+2.25.1
+
--- /dev/null
+From 92d1ebfa3f104c1067d387ec05f5d9782f6cba05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Aug 2020 12:26:24 +0200
+Subject: dma-pool: fix coherent pool allocations for IOMMU mappings
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit 9420139f516d7fbc248ce17f35275cb005ed98ea ]
+
+When allocating coherent pool memory for an IOMMU mapping we don't care
+about the DMA mask. Move the guess for the initial GFP mask into the
+dma_direct_alloc_pages and pass dma_coherent_ok as a function pointer
+argument so that it doesn't get applied to the IOMMU case.
+
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Tested-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/dma-iommu.c | 4 +-
+ include/linux/dma-direct.h | 3 -
+ include/linux/dma-mapping.h | 5 +-
+ kernel/dma/direct.c | 13 ++--
+ kernel/dma/pool.c | 114 +++++++++++++++---------------------
+ 5 files changed, 62 insertions(+), 77 deletions(-)
+
+diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
+index 4959f5df21bd0..5141d49a046ba 100644
+--- a/drivers/iommu/dma-iommu.c
++++ b/drivers/iommu/dma-iommu.c
+@@ -1035,8 +1035,8 @@ static void *iommu_dma_alloc(struct device *dev, size_t size,
+
+ if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) &&
+ !gfpflags_allow_blocking(gfp) && !coherent)
+- cpu_addr = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &page,
+- gfp);
++ page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr,
++ gfp, NULL);
+ else
+ cpu_addr = iommu_dma_alloc_pages(dev, size, &page, gfp, attrs);
+ if (!cpu_addr)
+diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
+index ab2e20cba9514..ba22952c24e24 100644
+--- a/include/linux/dma-direct.h
++++ b/include/linux/dma-direct.h
+@@ -67,9 +67,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size,
+ }
+
+ u64 dma_direct_get_required_mask(struct device *dev);
+-gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
+- u64 *phys_mask);
+-bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size);
+ void *dma_direct_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t gfp, unsigned long attrs);
+ void dma_direct_free(struct device *dev, size_t size, void *cpu_addr,
+diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
+index a33ed3954ed46..0dc08701d7b7e 100644
+--- a/include/linux/dma-mapping.h
++++ b/include/linux/dma-mapping.h
+@@ -715,8 +715,9 @@ void *dma_common_pages_remap(struct page **pages, size_t size,
+ pgprot_t prot, const void *caller);
+ void dma_common_free_remap(void *cpu_addr, size_t size);
+
+-void *dma_alloc_from_pool(struct device *dev, size_t size,
+- struct page **ret_page, gfp_t flags);
++struct page *dma_alloc_from_pool(struct device *dev, size_t size,
++ void **cpu_addr, gfp_t flags,
++ bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t));
+ bool dma_free_from_pool(struct device *dev, void *start, size_t size);
+
+ int
+diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
+index 67f060b86a73f..f17aec9d01f0c 100644
+--- a/kernel/dma/direct.c
++++ b/kernel/dma/direct.c
+@@ -45,7 +45,7 @@ u64 dma_direct_get_required_mask(struct device *dev)
+ return (1ULL << (fls64(max_dma) - 1)) * 2 - 1;
+ }
+
+-gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
++static gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
+ u64 *phys_limit)
+ {
+ u64 dma_limit = min_not_zero(dma_mask, dev->bus_dma_limit);
+@@ -70,7 +70,7 @@ gfp_t dma_direct_optimal_gfp_mask(struct device *dev, u64 dma_mask,
+ return 0;
+ }
+
+-bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
++static bool dma_coherent_ok(struct device *dev, phys_addr_t phys, size_t size)
+ {
+ return phys_to_dma_direct(dev, phys) + size - 1 <=
+ min_not_zero(dev->coherent_dma_mask, dev->bus_dma_limit);
+@@ -163,8 +163,13 @@ void *dma_direct_alloc_pages(struct device *dev, size_t size,
+ size = PAGE_ALIGN(size);
+
+ if (dma_should_alloc_from_pool(dev, gfp, attrs)) {
+- ret = dma_alloc_from_pool(dev, size, &page, gfp);
+- if (!ret)
++ u64 phys_mask;
++
++ gfp |= dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
++ &phys_mask);
++ page = dma_alloc_from_pool(dev, size, &ret, gfp,
++ dma_coherent_ok);
++ if (!page)
+ return NULL;
+ goto done;
+ }
+diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
+index 6bc74a2d51273..5d071d4a3cbaa 100644
+--- a/kernel/dma/pool.c
++++ b/kernel/dma/pool.c
+@@ -196,93 +196,75 @@ static int __init dma_atomic_pool_init(void)
+ }
+ postcore_initcall(dma_atomic_pool_init);
+
+-static inline struct gen_pool *dma_guess_pool_from_device(struct device *dev)
++static inline struct gen_pool *dma_guess_pool(struct gen_pool *prev, gfp_t gfp)
+ {
+- u64 phys_mask;
+- gfp_t gfp;
+-
+- gfp = dma_direct_optimal_gfp_mask(dev, dev->coherent_dma_mask,
+- &phys_mask);
+- if (IS_ENABLED(CONFIG_ZONE_DMA) && gfp == GFP_DMA)
++ if (prev == NULL) {
++ if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32))
++ return atomic_pool_dma32;
++ if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA))
++ return atomic_pool_dma;
++ return atomic_pool_kernel;
++ }
++ if (prev == atomic_pool_kernel)
++ return atomic_pool_dma32 ? atomic_pool_dma32 : atomic_pool_dma;
++ if (prev == atomic_pool_dma32)
+ return atomic_pool_dma;
+- if (IS_ENABLED(CONFIG_ZONE_DMA32) && gfp == GFP_DMA32)
+- return atomic_pool_dma32;
+- return atomic_pool_kernel;
++ return NULL;
+ }
+
+-static inline struct gen_pool *dma_get_safer_pool(struct gen_pool *bad_pool)
++static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
++ struct gen_pool *pool, void **cpu_addr,
++ bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
+ {
+- if (bad_pool == atomic_pool_kernel)
+- return atomic_pool_dma32 ? : atomic_pool_dma;
++ unsigned long addr;
++ phys_addr_t phys;
+
+- if (bad_pool == atomic_pool_dma32)
+- return atomic_pool_dma;
++ addr = gen_pool_alloc(pool, size);
++ if (!addr)
++ return NULL;
+
+- return NULL;
+-}
++ phys = gen_pool_virt_to_phys(pool, addr);
++ if (phys_addr_ok && !phys_addr_ok(dev, phys, size)) {
++ gen_pool_free(pool, addr, size);
++ return NULL;
++ }
+
+-static inline struct gen_pool *dma_guess_pool(struct device *dev,
+- struct gen_pool *bad_pool)
+-{
+- if (bad_pool)
+- return dma_get_safer_pool(bad_pool);
++ if (gen_pool_avail(pool) < atomic_pool_size)
++ schedule_work(&atomic_pool_work);
+
+- return dma_guess_pool_from_device(dev);
++ *cpu_addr = (void *)addr;
++ memset(*cpu_addr, 0, size);
++ return pfn_to_page(__phys_to_pfn(phys));
+ }
+
+-void *dma_alloc_from_pool(struct device *dev, size_t size,
+- struct page **ret_page, gfp_t flags)
++struct page *dma_alloc_from_pool(struct device *dev, size_t size,
++ void **cpu_addr, gfp_t gfp,
++ bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
+ {
+ struct gen_pool *pool = NULL;
+- unsigned long val = 0;
+- void *ptr = NULL;
+- phys_addr_t phys;
+-
+- while (1) {
+- pool = dma_guess_pool(dev, pool);
+- if (!pool) {
+- WARN(1, "Failed to get suitable pool for %s\n",
+- dev_name(dev));
+- break;
+- }
+-
+- val = gen_pool_alloc(pool, size);
+- if (!val)
+- continue;
+-
+- phys = gen_pool_virt_to_phys(pool, val);
+- if (dma_coherent_ok(dev, phys, size))
+- break;
+-
+- gen_pool_free(pool, val, size);
+- val = 0;
+- }
+-
+-
+- if (val) {
+- *ret_page = pfn_to_page(__phys_to_pfn(phys));
+- ptr = (void *)val;
+- memset(ptr, 0, size);
++ struct page *page;
+
+- if (gen_pool_avail(pool) < atomic_pool_size)
+- schedule_work(&atomic_pool_work);
++ while ((pool = dma_guess_pool(pool, gfp))) {
++ page = __dma_alloc_from_pool(dev, size, pool, cpu_addr,
++ phys_addr_ok);
++ if (page)
++ return page;
+ }
+
+- return ptr;
++ WARN(1, "Failed to get suitable pool for %s\n", dev_name(dev));
++ return NULL;
+ }
+
+ bool dma_free_from_pool(struct device *dev, void *start, size_t size)
+ {
+ struct gen_pool *pool = NULL;
+
+- while (1) {
+- pool = dma_guess_pool(dev, pool);
+- if (!pool)
+- return false;
+-
+- if (gen_pool_has_addr(pool, (unsigned long)start, size)) {
+- gen_pool_free(pool, (unsigned long)start, size);
+- return true;
+- }
++ while ((pool = dma_guess_pool(pool, 0))) {
++ if (!gen_pool_has_addr(pool, (unsigned long)start, size))
++ continue;
++ gen_pool_free(pool, (unsigned long)start, size);
++ return true;
+ }
++
++ return false;
+ }
+--
+2.25.1
+
--- /dev/null
+From 42c2a6965cb415c3a593d02152827e42bbc6474a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Aug 2020 12:26:23 +0200
+Subject: dma-pool: Only allocate from CMA when in same memory zone
+
+From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+
+[ Upstream commit d7e673ec2c8e0ea39c4c70fc490d67d7fbda869d ]
+
+There is no guarantee to CMA's placement, so allocating a zone specific
+atomic pool from CMA might return memory from a completely different
+memory zone. To get around this double check CMA's placement before
+allocating from it.
+
+Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/dma/pool.c | 31 ++++++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
+index 5d071d4a3cbaa..06582b488e317 100644
+--- a/kernel/dma/pool.c
++++ b/kernel/dma/pool.c
+@@ -3,7 +3,9 @@
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2020 Google LLC
+ */
++#include <linux/cma.h>
+ #include <linux/debugfs.h>
++#include <linux/dma-contiguous.h>
+ #include <linux/dma-direct.h>
+ #include <linux/dma-noncoherent.h>
+ #include <linux/init.h>
+@@ -55,6 +57,29 @@ static void dma_atomic_pool_size_add(gfp_t gfp, size_t size)
+ pool_size_kernel += size;
+ }
+
++static bool cma_in_zone(gfp_t gfp)
++{
++ unsigned long size;
++ phys_addr_t end;
++ struct cma *cma;
++
++ cma = dev_get_cma_area(NULL);
++ if (!cma)
++ return false;
++
++ size = cma_get_size(cma);
++ if (!size)
++ return false;
++
++ /* CMA can't cross zone boundaries, see cma_activate_area() */
++ end = cma_get_base(cma) + size - 1;
++ if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA))
++ return end <= DMA_BIT_MASK(zone_dma_bits);
++ if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32))
++ return end <= DMA_BIT_MASK(32);
++ return true;
++}
++
+ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
+ gfp_t gfp)
+ {
+@@ -68,7 +93,11 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
+
+ do {
+ pool_size = 1 << (PAGE_SHIFT + order);
+- page = alloc_pages(gfp, order);
++ if (cma_in_zone(gfp))
++ page = dma_alloc_from_contiguous(NULL, 1 << order,
++ order, false);
++ if (!page)
++ page = alloc_pages(gfp, order);
+ } while (!page && order-- > 0);
+ if (!page)
+ goto out;
+--
+2.25.1
+
--- /dev/null
+From 57abd1743ba1c69742d4ad9d991dcc2cf68dcf2e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 11:17:04 -0700
+Subject: drivers/net/wan/hdlc_x25: Added needed_headroom and a skb->len check
+
+From: Xie He <xie.he.0141@gmail.com>
+
+[ Upstream commit 77b981c82c1df7c7ad32a046f17f007450b46954 ]
+
+1. Added a skb->len check
+
+This driver expects upper layers to include a pseudo header of 1 byte
+when passing down a skb for transmission. This driver will read this
+1-byte header. This patch added a skb->len check before reading the
+header to make sure the header exists.
+
+2. Added needed_headroom and set hard_header_len to 0
+
+When this driver transmits data,
+ first this driver will remove a pseudo header of 1 byte,
+ then the lapb module will prepend the LAPB header of 2 or 3 bytes.
+So the value of needed_headroom in this driver should be 3 - 1.
+
+Because this driver has no header_ops, according to the logic of
+af_packet.c, the value of hard_header_len should be 0.
+
+Reason of setting needed_headroom and hard_header_len at this place:
+
+This driver is written using the API of the hdlc module, the hdlc
+module enables this driver (the protocol driver) to run on any hardware
+that has a driver (the hardware driver) written using the API of the
+hdlc module.
+
+Two other hdlc protocol drivers - hdlc_ppp and hdlc_raw_eth, also set
+things like hard_header_len at this place. In hdlc_ppp, it sets
+hard_header_len after attach_hdlc_protocol and before setting dev->type.
+In hdlc_raw_eth, it sets hard_header_len by calling ether_setup after
+attach_hdlc_protocol and after memcpy the settings.
+
+3. Reset needed_headroom when detaching protocols (in hdlc.c)
+
+When detaching a protocol from a hardware device, the hdlc module will
+reset various parameters of the device (including hard_header_len) to
+the default values. We add needed_headroom here so that needed_headroom
+will also be reset.
+
+Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Cc: Martin Schiller <ms@dev.tdt.de>
+Cc: Andrew Hendry <andrew.hendry@gmail.com>
+Signed-off-by: Xie He <xie.he.0141@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/wan/hdlc.c | 1 +
+ drivers/net/wan/hdlc_x25.c | 17 ++++++++++++++++-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
+index dfc16770458d8..386ed2aa31fd9 100644
+--- a/drivers/net/wan/hdlc.c
++++ b/drivers/net/wan/hdlc.c
+@@ -230,6 +230,7 @@ static void hdlc_setup_dev(struct net_device *dev)
+ dev->max_mtu = HDLC_MAX_MTU;
+ dev->type = ARPHRD_RAWHDLC;
+ dev->hard_header_len = 16;
++ dev->needed_headroom = 0;
+ dev->addr_len = 0;
+ dev->header_ops = &hdlc_null_ops;
+ }
+diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
+index f70336bb6f524..f52b9fed05931 100644
+--- a/drivers/net/wan/hdlc_x25.c
++++ b/drivers/net/wan/hdlc_x25.c
+@@ -107,8 +107,14 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ int result;
+
++ /* There should be a pseudo header of 1 byte added by upper layers.
++ * Check to make sure it is there before reading it.
++ */
++ if (skb->len < 1) {
++ kfree_skb(skb);
++ return NETDEV_TX_OK;
++ }
+
+- /* X.25 to LAPB */
+ switch (skb->data[0]) {
+ case X25_IFACE_DATA: /* Data to be transmitted */
+ skb_pull(skb, 1);
+@@ -294,6 +300,15 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
+ return result;
+
+ memcpy(&state(hdlc)->settings, &new_settings, size);
++
++ /* There's no header_ops so hard_header_len should be 0. */
++ dev->hard_header_len = 0;
++ /* When transmitting data:
++ * first we'll remove a pseudo header of 1 byte,
++ * then we'll prepend an LAPB header of at most 3 bytes.
++ */
++ dev->needed_headroom = 3 - 1;
++
+ dev->type = ARPHRD_X25;
+ call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
+ netif_dormant_off(dev);
+--
+2.25.1
+
--- /dev/null
+From 8b1c49415d13de3a5e99bce548c9ab388b7802e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jul 2020 17:33:27 -0400
+Subject: drm/amd/display: Fix LFC multiplier changing erratically
+
+From: Anthony Koo <Anthony.Koo@amd.com>
+
+[ Upstream commit e4ed4dbbc8383d42a197da8fe7ca6434b0f14def ]
+
+[Why]
+1. There is a calculation that is using frame_time_in_us instead of
+last_render_time_in_us to calculate whether choosing an LFC multiplier
+would cause the inserted frame duration to be outside of range.
+
+2. We do not handle unsigned integer subtraction correctly and it underflows
+to a really large value, which causes some logic errors.
+
+[How]
+1. Fix logic to calculate 'within range' using last_render_time_in_us
+2. Split out delta_from_mid_point_delta_in_us calculation to ensure
+we don't underflow and wrap around
+
+Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
+Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/modules/freesync/freesync.c | 36 +++++++++++++++----
+ 1 file changed, 29 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+index eb7421e83b865..23a7fa8447e24 100644
+--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
++++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+@@ -324,22 +324,44 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+
+ /* Choose number of frames to insert based on how close it
+ * can get to the mid point of the variable range.
++ * - Delta for CEIL: delta_from_mid_point_in_us_1
++ * - Delta for FLOOR: delta_from_mid_point_in_us_2
+ */
+- if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us &&
+- (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 ||
+- mid_point_frames_floor < 2)) {
++ if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) {
++ /* Check for out of range.
++ * If using CEIL produces a value that is out of range,
++ * then we are forced to use FLOOR.
++ */
++ frames_to_insert = mid_point_frames_floor;
++ } else if (mid_point_frames_floor < 2) {
++ /* Check if FLOOR would result in non-LFC. In this case
++ * choose to use CEIL
++ */
++ frames_to_insert = mid_point_frames_ceil;
++ } else if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
++ /* If choosing CEIL results in a frame duration that is
++ * closer to the mid point of the range.
++ * Choose CEIL
++ */
+ frames_to_insert = mid_point_frames_ceil;
+- delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
+- delta_from_mid_point_in_us_1;
+ } else {
++ /* If choosing FLOOR results in a frame duration that is
++ * closer to the mid point of the range.
++ * Choose FLOOR
++ */
+ frames_to_insert = mid_point_frames_floor;
+- delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 -
+- delta_from_mid_point_in_us_2;
+ }
+
+ /* Prefer current frame multiplier when BTR is enabled unless it drifts
+ * too far from the midpoint
+ */
++ if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
++ delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
++ delta_from_mid_point_in_us_1;
++ } else {
++ delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 -
++ delta_from_mid_point_in_us_2;
++ }
+ if (in_out_vrr->btr.frames_to_insert != 0 &&
+ delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) {
+ if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) <
+--
+2.25.1
+
--- /dev/null
+From 0b84a2970e3ba6a83cbbc41c87d3e6b4671224df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 29 Jul 2020 17:43:10 -0400
+Subject: drm/amd/display: Switch to immediate mode for updating infopackets
+
+From: Anthony Koo <Anthony.Koo@amd.com>
+
+[ Upstream commit abba907c7a20032c2d504fd5afe3af7d440a09d0 ]
+
+[Why]
+Using FRAME_UPDATE will result in infopacket to be potentially updated
+one frame late.
+In commit stream scenarios for previously active stream, some stale
+infopacket data from previous config might be erroneously sent out on
+initial frame after stream is re-enabled.
+
+[How]
+Switch to using IMMEDIATE_UPDATE mode
+
+Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
+Reviewed-by: Ashley Thomas <Ashley.Thomas2@amd.com>
+Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../amd/display/dc/dcn10/dcn10_stream_encoder.c | 16 ++++++++--------
+ .../amd/display/dc/dcn10/dcn10_stream_encoder.h | 14 ++++++++++++++
+ 2 files changed, 22 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
+index 07b2f9399671d..842abb4c475bc 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.c
+@@ -121,35 +121,35 @@ void enc1_update_generic_info_packet(
+ switch (packet_index) {
+ case 0:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC0_FRAME_UPDATE, 1);
++ AFMT_GENERIC0_IMMEDIATE_UPDATE, 1);
+ break;
+ case 1:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC1_FRAME_UPDATE, 1);
++ AFMT_GENERIC1_IMMEDIATE_UPDATE, 1);
+ break;
+ case 2:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC2_FRAME_UPDATE, 1);
++ AFMT_GENERIC2_IMMEDIATE_UPDATE, 1);
+ break;
+ case 3:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC3_FRAME_UPDATE, 1);
++ AFMT_GENERIC3_IMMEDIATE_UPDATE, 1);
+ break;
+ case 4:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC4_FRAME_UPDATE, 1);
++ AFMT_GENERIC4_IMMEDIATE_UPDATE, 1);
+ break;
+ case 5:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC5_FRAME_UPDATE, 1);
++ AFMT_GENERIC5_IMMEDIATE_UPDATE, 1);
+ break;
+ case 6:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC6_FRAME_UPDATE, 1);
++ AFMT_GENERIC6_IMMEDIATE_UPDATE, 1);
+ break;
+ case 7:
+ REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,
+- AFMT_GENERIC7_FRAME_UPDATE, 1);
++ AFMT_GENERIC7_IMMEDIATE_UPDATE, 1);
+ break;
+ default:
+ break;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+index f9b9e221c698b..7507000a99ac4 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_stream_encoder.h
+@@ -273,7 +273,14 @@ struct dcn10_stream_enc_registers {
+ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_FRAME_UPDATE, mask_sh),\
+ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_FRAME_UPDATE, mask_sh),\
+ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_FRAME_UPDATE, mask_sh),\
++ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC0_IMMEDIATE_UPDATE, mask_sh),\
++ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC1_IMMEDIATE_UPDATE, mask_sh),\
++ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC2_IMMEDIATE_UPDATE, mask_sh),\
++ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC3_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC4_IMMEDIATE_UPDATE, mask_sh),\
++ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_IMMEDIATE_UPDATE, mask_sh),\
++ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_IMMEDIATE_UPDATE, mask_sh),\
++ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_IMMEDIATE_UPDATE, mask_sh),\
+ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC5_FRAME_UPDATE, mask_sh),\
+ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC6_FRAME_UPDATE, mask_sh),\
+ SE_SF(DIG0_AFMT_VBI_PACKET_CONTROL1, AFMT_GENERIC7_FRAME_UPDATE, mask_sh),\
+@@ -337,7 +344,14 @@ struct dcn10_stream_enc_registers {
+ type AFMT_GENERIC2_FRAME_UPDATE;\
+ type AFMT_GENERIC3_FRAME_UPDATE;\
+ type AFMT_GENERIC4_FRAME_UPDATE;\
++ type AFMT_GENERIC0_IMMEDIATE_UPDATE;\
++ type AFMT_GENERIC1_IMMEDIATE_UPDATE;\
++ type AFMT_GENERIC2_IMMEDIATE_UPDATE;\
++ type AFMT_GENERIC3_IMMEDIATE_UPDATE;\
+ type AFMT_GENERIC4_IMMEDIATE_UPDATE;\
++ type AFMT_GENERIC5_IMMEDIATE_UPDATE;\
++ type AFMT_GENERIC6_IMMEDIATE_UPDATE;\
++ type AFMT_GENERIC7_IMMEDIATE_UPDATE;\
+ type AFMT_GENERIC5_FRAME_UPDATE;\
+ type AFMT_GENERIC6_FRAME_UPDATE;\
+ type AFMT_GENERIC7_FRAME_UPDATE;\
+--
+2.25.1
+
--- /dev/null
+From 310fd85dfb8e981b10f38ff865240f14fa0927e3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Aug 2020 17:01:47 +0800
+Subject: drm/amd/powerplay: correct UVD/VCE PG state on custom pptable
+ uploading
+
+From: Evan Quan <evan.quan@amd.com>
+
+[ Upstream commit 2c5b8080d810d98e3e59617680218499b17c84a1 ]
+
+The UVD/VCE PG state is managed by UVD and VCE IP. It's error-prone to
+assume the bootup state in SMU based on the dpm status.
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+index b7f3f8b62c2ac..9bd2874a122b4 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+@@ -1640,12 +1640,6 @@ static void vega20_init_powergate_state(struct pp_hwmgr *hwmgr)
+
+ data->uvd_power_gated = true;
+ data->vce_power_gated = true;
+-
+- if (data->smu_features[GNLD_DPM_UVD].enabled)
+- data->uvd_power_gated = false;
+-
+- if (data->smu_features[GNLD_DPM_VCE].enabled)
+- data->vce_power_gated = false;
+ }
+
+ static int vega20_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
+--
+2.25.1
+
--- /dev/null
+From 869a64fb5e173d8143115f6c38234bf55b71ac8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Aug 2020 15:03:40 +0800
+Subject: drm/amd/powerplay: correct Vega20 cached smu feature state
+
+From: Evan Quan <evan.quan@amd.com>
+
+[ Upstream commit 266d81d9eed30f4994d76a2b237c63ece062eefe ]
+
+Correct the cached smu feature state on pp_features sysfs
+setting.
+
+Signed-off-by: Evan Quan <evan.quan@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../drm/amd/powerplay/hwmgr/vega20_hwmgr.c | 38 +++++++++----------
+ 1 file changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+index 9ff470f1b826c..b7f3f8b62c2ac 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
+@@ -979,10 +979,7 @@ static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr)
+ {
+ struct vega20_hwmgr *data =
+ (struct vega20_hwmgr *)(hwmgr->backend);
+- uint64_t features_enabled;
+- int i;
+- bool enabled;
+- int ret = 0;
++ int i, ret = 0;
+
+ PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr,
+ PPSMC_MSG_DisableAllSmuFeatures,
+@@ -990,17 +987,8 @@ static int vega20_disable_all_smu_features(struct pp_hwmgr *hwmgr)
+ "[DisableAllSMUFeatures] Failed to disable all smu features!",
+ return ret);
+
+- ret = vega20_get_enabled_smc_features(hwmgr, &features_enabled);
+- PP_ASSERT_WITH_CODE(!ret,
+- "[DisableAllSMUFeatures] Failed to get enabled smc features!",
+- return ret);
+-
+- for (i = 0; i < GNLD_FEATURES_MAX; i++) {
+- enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ?
+- true : false;
+- data->smu_features[i].enabled = enabled;
+- data->smu_features[i].supported = enabled;
+- }
++ for (i = 0; i < GNLD_FEATURES_MAX; i++)
++ data->smu_features[i].enabled = 0;
+
+ return 0;
+ }
+@@ -3230,10 +3218,11 @@ static int vega20_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf)
+
+ static int vega20_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfeature_masks)
+ {
+- uint64_t features_enabled;
+- uint64_t features_to_enable;
+- uint64_t features_to_disable;
+- int ret = 0;
++ struct vega20_hwmgr *data =
++ (struct vega20_hwmgr *)(hwmgr->backend);
++ uint64_t features_enabled, features_to_enable, features_to_disable;
++ int i, ret = 0;
++ bool enabled;
+
+ if (new_ppfeature_masks >= (1ULL << GNLD_FEATURES_MAX))
+ return -EINVAL;
+@@ -3262,6 +3251,17 @@ static int vega20_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfe
+ return ret;
+ }
+
++ /* Update the cached feature enablement state */
++ ret = vega20_get_enabled_smc_features(hwmgr, &features_enabled);
++ if (ret)
++ return ret;
++
++ for (i = 0; i < GNLD_FEATURES_MAX; i++) {
++ enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ?
++ true : false;
++ data->smu_features[i].enabled = enabled;
++ }
++
+ return 0;
+ }
+
+--
+2.25.1
+
--- /dev/null
+From 2ba111192632987ebcaa308797230abe2644a816 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 14:35:35 +0800
+Subject: drm/amdgpu: fix NULL pointer access issue when unloading driver
+
+From: Guchun Chen <guchun.chen@amd.com>
+
+[ Upstream commit 1a68d96f81b8e7eb2a121fbf9abf9e5974e58832 ]
+
+When unloading driver by "modprobe -r amdgpu", one NULL pointer
+dereference bug occurs in ras debugfs releasing. The cause is the
+duplicated debugfs_remove, as drm debugfs_root dir has been cleaned
+up already by drm_minor_unregister.
+
+BUG: kernel NULL pointer dereference, address: 00000000000000a0
+PGD 0 P4D 0
+Oops: 0002 [#1] SMP PTI
+CPU: 11 PID: 1526 Comm: modprobe Tainted: G OE 5.6.0-guchchen #1
+Hardware name: System manufacturer System Product Name/TUF Z370-PLUS GAMING II, BIOS 0411 09/21/2018
+RIP: 0010:down_write+0x15/0x40
+Code: eb de e8 7e 17 72 ff cc cc cc cc cc cc cc cc cc cc cc cc cc cc 0f 1f 44 00 00 53 48 89 fb e8 92
+d8 ff ff 31 c0 ba 01 00 00 00 <f0> 48 0f b1 13 75 0f 65 48 8b 04 25 c0 8b 01 00 48 89 43 08 5b c3
+RSP: 0018:ffffb1590386fcd0 EFLAGS: 00010246
+RAX: 0000000000000000 RBX: 00000000000000a0 RCX: 0000000000000000
+RDX: 0000000000000001 RSI: ffffffff85b2fcc2 RDI: 00000000000000a0
+RBP: ffffb1590386fd30 R08: ffffffff85b2fcc2 R09: 000000000002b3c0
+R10: ffff97a330618c40 R11: 00000000000005f6 R12: ffff97a3481beb40
+R13: 00000000000000a0 R14: ffff97a3481beb40 R15: 0000000000000000
+FS: 00007fb11a717540(0000) GS:ffff97a376cc0000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 00000000000000a0 CR3: 00000004066d6006 CR4: 00000000003606e0
+DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+Call Trace:
+ simple_recursive_removal+0x63/0x370
+ ? debugfs_remove+0x60/0x60
+ debugfs_remove+0x40/0x60
+ amdgpu_ras_fini+0x82/0x230 [amdgpu]
+ ? __kernfs_remove.part.17+0x101/0x1f0
+ ? kernfs_name_hash+0x12/0x80
+ amdgpu_device_fini+0x1c0/0x580 [amdgpu]
+ amdgpu_driver_unload_kms+0x3e/0x70 [amdgpu]
+ amdgpu_pci_remove+0x36/0x60 [amdgpu]
+ pci_device_remove+0x3b/0xb0
+ device_release_driver_internal+0xe5/0x1c0
+ driver_detach+0x46/0x90
+ bus_remove_driver+0x58/0xd0
+ pci_unregister_driver+0x29/0x90
+ amdgpu_exit+0x11/0x25 [amdgpu]
+ __x64_sys_delete_module+0x13d/0x210
+ do_syscall_64+0x5f/0x250
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Signed-off-by: Guchun Chen <guchun.chen@amd.com>
+Reviewed-by: Tao Zhou <tao.zhou1@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+index 20a7d75b2eb88..3f47f35eedff1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+@@ -1240,7 +1240,6 @@ void amdgpu_ras_debugfs_remove(struct amdgpu_device *adev,
+ if (!obj || !obj->ent)
+ return;
+
+- debugfs_remove(obj->ent);
+ obj->ent = NULL;
+ put_obj(obj);
+ }
+@@ -1254,7 +1253,6 @@ static void amdgpu_ras_debugfs_remove_all(struct amdgpu_device *adev)
+ amdgpu_ras_debugfs_remove(adev, &obj->head);
+ }
+
+- debugfs_remove_recursive(con->dir);
+ con->dir = NULL;
+ }
+ /* debugfs end */
+--
+2.25.1
+
--- /dev/null
+From 016cb05c607a436834d7a34a2585e9f416f94bac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Aug 2020 13:54:56 +0800
+Subject: drm/amdkfd: fix the wrong sdma instance query for renoir
+
+From: Huang Rui <ray.huang@amd.com>
+
+[ Upstream commit 34174b89bfa495bed9cddcc504fb38feca90fab7 ]
+
+Renoir only has one sdma instance, it will get failed once query the
+sdma1 registers. So use switch-case instead of static register array.
+
+Signed-off-by: Huang Rui <ray.huang@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 31 +++++++++++++------
+ 1 file changed, 22 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+index c7fd0c47b2545..1102de76d8767 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c
+@@ -195,19 +195,32 @@ static uint32_t get_sdma_rlc_reg_offset(struct amdgpu_device *adev,
+ unsigned int engine_id,
+ unsigned int queue_id)
+ {
+- uint32_t sdma_engine_reg_base[2] = {
+- SOC15_REG_OFFSET(SDMA0, 0,
+- mmSDMA0_RLC0_RB_CNTL) - mmSDMA0_RLC0_RB_CNTL,
+- SOC15_REG_OFFSET(SDMA1, 0,
+- mmSDMA1_RLC0_RB_CNTL) - mmSDMA1_RLC0_RB_CNTL
+- };
+- uint32_t retval = sdma_engine_reg_base[engine_id]
++ uint32_t sdma_engine_reg_base = 0;
++ uint32_t sdma_rlc_reg_offset;
++
++ switch (engine_id) {
++ default:
++ dev_warn(adev->dev,
++ "Invalid sdma engine id (%d), using engine id 0\n",
++ engine_id);
++ fallthrough;
++ case 0:
++ sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA0, 0,
++ mmSDMA0_RLC0_RB_CNTL) - mmSDMA0_RLC0_RB_CNTL;
++ break;
++ case 1:
++ sdma_engine_reg_base = SOC15_REG_OFFSET(SDMA1, 0,
++ mmSDMA1_RLC0_RB_CNTL) - mmSDMA0_RLC0_RB_CNTL;
++ break;
++ }
++
++ sdma_rlc_reg_offset = sdma_engine_reg_base
+ + queue_id * (mmSDMA0_RLC1_RB_CNTL - mmSDMA0_RLC0_RB_CNTL);
+
+ pr_debug("RLC register offset for SDMA%d RLC%d: 0x%x\n", engine_id,
+- queue_id, retval);
++ queue_id, sdma_rlc_reg_offset);
+
+- return retval;
++ return sdma_rlc_reg_offset;
+ }
+
+ static inline struct v9_mqd *get_mqd(void *mqd)
+--
+2.25.1
+
--- /dev/null
+From f0f5cada61eec8d3b1832975153f8c63c1010500 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Aug 2020 12:55:37 +0200
+Subject: drm/etnaviv: always start/stop scheduler in timeout processing
+
+From: Lucas Stach <l.stach@pengutronix.de>
+
+[ Upstream commit 50248a3ec0f5e5debd18033eb2a29f0b793a7000 ]
+
+The drm scheduler currently expects that the stop/start sequence is always
+executed in the timeout handling, as the job at the head of the hardware
+execution list is always removed from the ring mirror before the driver
+function is called and only inserted back into the list when starting the
+scheduler.
+
+This adds some unnecessary overhead if the timeout handler determines
+that the GPU is still executing jobs normally and just wished to extend
+the timeout, but a better solution requires a major rearchitecture of the
+scheduler, which is not applicable as a fix.
+
+Fixes: 135517d3565b ("drm/scheduler: Avoid accessing freed bad job.")
+Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
+Tested-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/etnaviv/etnaviv_sched.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+index 4e3e95dce6d87..cd46c882269cc 100644
+--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
++++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
+@@ -89,12 +89,15 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
+ u32 dma_addr;
+ int change;
+
++ /* block scheduler */
++ drm_sched_stop(&gpu->sched, sched_job);
++
+ /*
+ * If the GPU managed to complete this jobs fence, the timout is
+ * spurious. Bail out.
+ */
+ if (dma_fence_is_signaled(submit->out_fence))
+- return;
++ goto out_no_timeout;
+
+ /*
+ * If the GPU is still making forward progress on the front-end (which
+@@ -105,12 +108,9 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
+ change = dma_addr - gpu->hangcheck_dma_addr;
+ if (change < 0 || change > 16) {
+ gpu->hangcheck_dma_addr = dma_addr;
+- return;
++ goto out_no_timeout;
+ }
+
+- /* block scheduler */
+- drm_sched_stop(&gpu->sched, sched_job);
+-
+ if(sched_job)
+ drm_sched_increase_karma(sched_job);
+
+@@ -120,6 +120,7 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
+
+ drm_sched_resubmit_jobs(&gpu->sched);
+
++out_no_timeout:
+ /* restart scheduler after GPU is usable again */
+ drm_sched_start(&gpu->sched, true);
+ }
+--
+2.25.1
+
--- /dev/null
+From 174c4ed8523aa6b23207b17a2fe1dc1f94835af8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Aug 2020 17:03:09 -0700
+Subject: drm/msm/adreno: fix updating ring fence
+
+From: Rob Clark <robdclark@chromium.org>
+
+[ Upstream commit f228af11dfa1d1616bc67f3a4119ab77c36181f1 ]
+
+We need to set it to the most recent completed fence, not the most
+recent submitted. Otherwise we have races where we think we can retire
+submits that the GPU is not finished with, if the GPU doesn't manage to
+overwrite the seqno before we look at it.
+
+This can show up with hang recovery if one of the submits after the
+crashing submit also hangs after it is replayed.
+
+Fixes: f97decac5f4c ("drm/msm: Support multiple ringbuffers")
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Reviewed-by: Jordan Crouse <jcrouse@codeaurora.org>
+Signed-off-by: Rob Clark <robdclark@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+index 5db06b5909438..e7b39f3ca33dc 100644
+--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+@@ -396,7 +396,7 @@ int adreno_hw_init(struct msm_gpu *gpu)
+ ring->next = ring->start;
+
+ /* reset completed fence seqno: */
+- ring->memptrs->fence = ring->seqno;
++ ring->memptrs->fence = ring->fctx->completed_fence;
+ ring->memptrs->rptr = 0;
+ }
+
+--
+2.25.1
+
--- /dev/null
+From aecf92ff68b6db87223fe9647f09f26adb66165a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 22 Jul 2020 13:18:51 +0800
+Subject: drm/virtio: fix memory leak in virtio_gpu_cleanup_object()
+
+From: Xin He <hexin.op@bytedance.com>
+
+[ Upstream commit 836b194d65782aaec4485a07d2aab52d3f698505 ]
+
+Before setting shmem->pages to NULL, kfree() should
+be called.
+
+Signed-off-by: Xin He <hexin.op@bytedance.com>
+Reviewed-by: Qi Liu <liuqi.16@bytedance.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20200722051851.72662-1-hexin.op@bytedance.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_object.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
+index 6ccbd01cd888c..703b5cd517519 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_object.c
++++ b/drivers/gpu/drm/virtio/virtgpu_object.c
+@@ -79,6 +79,7 @@ void virtio_gpu_cleanup_object(struct virtio_gpu_object *bo)
+ }
+
+ sg_free_table(shmem->pages);
++ kfree(shmem->pages);
+ shmem->pages = NULL;
+ drm_gem_shmem_unpin(&bo->base.base);
+ }
+--
+2.25.1
+
--- /dev/null
+From 2de6950a1e7b220b7a949eee8b25c3f73a4e7805 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2020 10:54:23 +0800
+Subject: ext4: abort the filesystem if failed to async write metadata buffer
+
+From: zhangyi (F) <yi.zhang@huawei.com>
+
+[ Upstream commit bc71726c725767205757821df364acff87f92ac5 ]
+
+There is a risk of filesystem inconsistency if we failed to async write
+back metadata buffer in the background. Because of current buffer's end
+io procedure is handled by end_buffer_async_write() in the block layer,
+and it only clear the buffer's uptodate flag and mark the write_io_error
+flag, so ext4 cannot detect such failure immediately. In most cases of
+getting metadata buffer (e.g. ext4_read_inode_bitmap()), although the
+buffer's data is actually uptodate, it may still read data from disk
+because the buffer's uptodate flag has been cleared. Finally, it may
+lead to on-disk filesystem inconsistency if reading old data from the
+disk successfully and write them out again.
+
+This patch detect bdev mapping->wb_err when getting journal's write
+access and mark the filesystem error if bdev's mapping->wb_err was
+increased, this could prevent further writing and potential
+inconsistency.
+
+Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
+Suggested-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20200620025427.1756360-2-yi.zhang@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/ext4.h | 3 +++
+ fs/ext4/ext4_jbd2.c | 25 +++++++++++++++++++++++++
+ fs/ext4/super.c | 17 +++++++++++++++++
+ 3 files changed, 45 insertions(+)
+
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index 42815304902b8..eec5c03534d05 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1585,6 +1585,9 @@ struct ext4_sb_info {
+ #ifdef CONFIG_EXT4_DEBUG
+ unsigned long s_simulate_fail;
+ #endif
++ /* Record the errseq of the backing block device */
++ errseq_t s_bdev_wb_err;
++ spinlock_t s_bdev_wb_lock;
+ };
+
+ static inline struct ext4_sb_info *EXT4_SB(struct super_block *sb)
+diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
+index 0c76cdd44d90d..760b9ee49dc00 100644
+--- a/fs/ext4/ext4_jbd2.c
++++ b/fs/ext4/ext4_jbd2.c
+@@ -195,6 +195,28 @@ static void ext4_journal_abort_handle(const char *caller, unsigned int line,
+ jbd2_journal_abort_handle(handle);
+ }
+
++static void ext4_check_bdev_write_error(struct super_block *sb)
++{
++ struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping;
++ struct ext4_sb_info *sbi = EXT4_SB(sb);
++ int err;
++
++ /*
++ * If the block device has write error flag, it may have failed to
++ * async write out metadata buffers in the background. In this case,
++ * we could read old data from disk and write it out again, which
++ * may lead to on-disk filesystem inconsistency.
++ */
++ if (errseq_check(&mapping->wb_err, READ_ONCE(sbi->s_bdev_wb_err))) {
++ spin_lock(&sbi->s_bdev_wb_lock);
++ err = errseq_check_and_advance(&mapping->wb_err, &sbi->s_bdev_wb_err);
++ spin_unlock(&sbi->s_bdev_wb_lock);
++ if (err)
++ ext4_error_err(sb, -err,
++ "Error while async write back metadata");
++ }
++}
++
+ int __ext4_journal_get_write_access(const char *where, unsigned int line,
+ handle_t *handle, struct buffer_head *bh)
+ {
+@@ -202,6 +224,9 @@ int __ext4_journal_get_write_access(const char *where, unsigned int line,
+
+ might_sleep();
+
++ if (bh->b_bdev->bd_super)
++ ext4_check_bdev_write_error(bh->b_bdev->bd_super);
++
+ if (ext4_handle_valid(handle)) {
+ err = jbd2_journal_get_write_access(handle, bh);
+ if (err)
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index dda967efcbc2c..c77b10257b36a 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4765,6 +4765,15 @@ no_journal:
+ }
+ #endif /* CONFIG_QUOTA */
+
++ /*
++ * Save the original bdev mapping's wb_err value which could be
++ * used to detect the metadata async write error.
++ */
++ spin_lock_init(&sbi->s_bdev_wb_lock);
++ if (!sb_rdonly(sb))
++ errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
++ &sbi->s_bdev_wb_err);
++ sb->s_bdev->bd_super = sb;
+ EXT4_SB(sb)->s_mount_state |= EXT4_ORPHAN_FS;
+ ext4_orphan_cleanup(sb, es);
+ EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
+@@ -5654,6 +5663,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ goto restore_opts;
+ }
+
++ /*
++ * Update the original bdev mapping's wb_err value
++ * which could be used to detect the metadata async
++ * write error.
++ */
++ errseq_check_and_advance(&sb->s_bdev->bd_inode->i_mapping->wb_err,
++ &sbi->s_bdev_wb_err);
++
+ /*
+ * Mounting a RDONLY partition read-write, so reread
+ * and store the current valid flag. (It may have
+--
+2.25.1
+
--- /dev/null
+From f2d6553b6410313609ab1a1ca8f487b1cc827252 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jul 2020 15:04:37 +0200
+Subject: ext4: correctly restore system zone info when remount fails
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 0f5bde1db174f6c471f0bd27198575719dabe3e5 ]
+
+When remounting filesystem fails late during remount handling and
+block_validity mount option is also changed during the remount, we fail
+to restore system zone information to a state matching the mount option.
+This is mostly harmless, just the block validity checking will not match
+the situation described by the mount option. Make sure these two are always
+consistent.
+
+Reported-by: Lukas Czerner <lczerner@redhat.com>
+Reviewed-by: Lukas Czerner <lczerner@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20200728130437.7804-7-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/block_validity.c | 8 --------
+ fs/ext4/super.c | 29 +++++++++++++++++++++--------
+ 2 files changed, 21 insertions(+), 16 deletions(-)
+
+diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c
+index e830a9d4e10d3..11aa37693e436 100644
+--- a/fs/ext4/block_validity.c
++++ b/fs/ext4/block_validity.c
+@@ -254,14 +254,6 @@ int ext4_setup_system_zone(struct super_block *sb)
+ int flex_size = ext4_flex_bg_size(sbi);
+ int ret;
+
+- if (!test_opt(sb, BLOCK_VALIDITY)) {
+- if (sbi->system_blks)
+- ext4_release_system_zone(sb);
+- return 0;
+- }
+- if (sbi->system_blks)
+- return 0;
+-
+ system_blks = kzalloc(sizeof(*system_blks), GFP_KERNEL);
+ if (!system_blks)
+ return -ENOMEM;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 54d1c09329e55..4c8253188d8df 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -4698,11 +4698,13 @@ no_journal:
+
+ ext4_set_resv_clusters(sb);
+
+- err = ext4_setup_system_zone(sb);
+- if (err) {
+- ext4_msg(sb, KERN_ERR, "failed to initialize system "
+- "zone (%d)", err);
+- goto failed_mount4a;
++ if (test_opt(sb, BLOCK_VALIDITY)) {
++ err = ext4_setup_system_zone(sb);
++ if (err) {
++ ext4_msg(sb, KERN_ERR, "failed to initialize system "
++ "zone (%d)", err);
++ goto failed_mount4a;
++ }
+ }
+
+ ext4_ext_init(sb);
+@@ -5716,9 +5718,16 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ ext4_register_li_request(sb, first_not_zeroed);
+ }
+
+- err = ext4_setup_system_zone(sb);
+- if (err)
+- goto restore_opts;
++ /*
++ * Handle creation of system zone data early because it can fail.
++ * Releasing of existing data is done when we are sure remount will
++ * succeed.
++ */
++ if (test_opt(sb, BLOCK_VALIDITY) && !sbi->system_blks) {
++ err = ext4_setup_system_zone(sb);
++ if (err)
++ goto restore_opts;
++ }
+
+ if (sbi->s_journal == NULL && !(old_sb_flags & SB_RDONLY)) {
+ err = ext4_commit_super(sb, 1);
+@@ -5740,6 +5749,8 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ }
+ }
+ #endif
++ if (!test_opt(sb, BLOCK_VALIDITY) && sbi->system_blks)
++ ext4_release_system_zone(sb);
+
+ /*
+ * Some options can be enabled by ext4 and/or by VFS mount flag
+@@ -5761,6 +5772,8 @@ restore_opts:
+ sbi->s_commit_interval = old_opts.s_commit_interval;
+ sbi->s_min_batch_time = old_opts.s_min_batch_time;
+ sbi->s_max_batch_time = old_opts.s_max_batch_time;
++ if (!test_opt(sb, BLOCK_VALIDITY) && sbi->system_blks)
++ ext4_release_system_zone(sb);
+ #ifdef CONFIG_QUOTA
+ sbi->s_jquota_fmt = old_opts.s_jquota_fmt;
+ for (i = 0; i < EXT4_MAXQUOTAS; i++) {
+--
+2.25.1
+
--- /dev/null
+From f15f198341684ef6558d3e395aa16d8a9b4476b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Jul 2020 16:07:59 +0200
+Subject: ext4: don't BUG on inconsistent journal feature
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit 11215630aada28307ba555a43138db6ac54fa825 ]
+
+A customer has reported a BUG_ON in ext4_clear_journal_err() hitting
+during an LTP testing. Either this has been caused by a test setup
+issue where the filesystem was being overwritten while LTP was mounting
+it or the journal replay has overwritten the superblock with invalid
+data. In either case it is preferable we don't take the machine down
+with a BUG_ON. So handle the situation of unexpectedly missing
+has_journal feature more gracefully. We issue warning and fail the mount
+in the cases where the race window is narrow and the failed check is
+most likely a programming error. In cases where fs corruption is more
+likely, we do full ext4_error() handling before failing mount / remount.
+
+Reviewed-by: Lukas Czerner <lczerner@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20200710140759.18031-1-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 68 ++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 47 insertions(+), 21 deletions(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 330957ed1f05c..9fdad843b30ef 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -66,10 +66,10 @@ static int ext4_load_journal(struct super_block *, struct ext4_super_block *,
+ unsigned long journal_devnum);
+ static int ext4_show_options(struct seq_file *seq, struct dentry *root);
+ static int ext4_commit_super(struct super_block *sb, int sync);
+-static void ext4_mark_recovery_complete(struct super_block *sb,
++static int ext4_mark_recovery_complete(struct super_block *sb,
+ struct ext4_super_block *es);
+-static void ext4_clear_journal_err(struct super_block *sb,
+- struct ext4_super_block *es);
++static int ext4_clear_journal_err(struct super_block *sb,
++ struct ext4_super_block *es);
+ static int ext4_sync_fs(struct super_block *sb, int wait);
+ static int ext4_remount(struct super_block *sb, int *flags, char *data);
+ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf);
+@@ -4770,7 +4770,9 @@ no_journal:
+ EXT4_SB(sb)->s_mount_state &= ~EXT4_ORPHAN_FS;
+ if (needs_recovery) {
+ ext4_msg(sb, KERN_INFO, "recovery complete");
+- ext4_mark_recovery_complete(sb, es);
++ err = ext4_mark_recovery_complete(sb, es);
++ if (err)
++ goto failed_mount8;
+ }
+ if (EXT4_SB(sb)->s_journal) {
+ if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+@@ -4813,10 +4815,8 @@ cantfind_ext4:
+ ext4_msg(sb, KERN_ERR, "VFS: Can't find ext4 filesystem");
+ goto failed_mount;
+
+-#ifdef CONFIG_QUOTA
+ failed_mount8:
+ ext4_unregister_sysfs(sb);
+-#endif
+ failed_mount7:
+ ext4_unregister_li_request(sb);
+ failed_mount6:
+@@ -4956,7 +4956,8 @@ static journal_t *ext4_get_journal(struct super_block *sb,
+ struct inode *journal_inode;
+ journal_t *journal;
+
+- BUG_ON(!ext4_has_feature_journal(sb));
++ if (WARN_ON_ONCE(!ext4_has_feature_journal(sb)))
++ return NULL;
+
+ journal_inode = ext4_get_journal_inode(sb, journal_inum);
+ if (!journal_inode)
+@@ -4986,7 +4987,8 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb,
+ struct ext4_super_block *es;
+ struct block_device *bdev;
+
+- BUG_ON(!ext4_has_feature_journal(sb));
++ if (WARN_ON_ONCE(!ext4_has_feature_journal(sb)))
++ return NULL;
+
+ bdev = ext4_blkdev_get(j_dev, sb);
+ if (bdev == NULL)
+@@ -5078,7 +5080,8 @@ static int ext4_load_journal(struct super_block *sb,
+ int err = 0;
+ int really_read_only;
+
+- BUG_ON(!ext4_has_feature_journal(sb));
++ if (WARN_ON_ONCE(!ext4_has_feature_journal(sb)))
++ return -EFSCORRUPTED;
+
+ if (journal_devnum &&
+ journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+@@ -5148,7 +5151,12 @@ static int ext4_load_journal(struct super_block *sb,
+ }
+
+ EXT4_SB(sb)->s_journal = journal;
+- ext4_clear_journal_err(sb, es);
++ err = ext4_clear_journal_err(sb, es);
++ if (err) {
++ EXT4_SB(sb)->s_journal = NULL;
++ jbd2_journal_destroy(journal);
++ return err;
++ }
+
+ if (!really_read_only && journal_devnum &&
+ journal_devnum != le32_to_cpu(es->s_journal_dev)) {
+@@ -5244,26 +5252,32 @@ static int ext4_commit_super(struct super_block *sb, int sync)
+ * remounting) the filesystem readonly, then we will end up with a
+ * consistent fs on disk. Record that fact.
+ */
+-static void ext4_mark_recovery_complete(struct super_block *sb,
+- struct ext4_super_block *es)
++static int ext4_mark_recovery_complete(struct super_block *sb,
++ struct ext4_super_block *es)
+ {
++ int err;
+ journal_t *journal = EXT4_SB(sb)->s_journal;
+
+ if (!ext4_has_feature_journal(sb)) {
+- BUG_ON(journal != NULL);
+- return;
++ if (journal != NULL) {
++ ext4_error(sb, "Journal got removed while the fs was "
++ "mounted!");
++ return -EFSCORRUPTED;
++ }
++ return 0;
+ }
+ jbd2_journal_lock_updates(journal);
+- if (jbd2_journal_flush(journal) < 0)
++ err = jbd2_journal_flush(journal);
++ if (err < 0)
+ goto out;
+
+ if (ext4_has_feature_journal_needs_recovery(sb) && sb_rdonly(sb)) {
+ ext4_clear_feature_journal_needs_recovery(sb);
+ ext4_commit_super(sb, 1);
+ }
+-
+ out:
+ jbd2_journal_unlock_updates(journal);
++ return err;
+ }
+
+ /*
+@@ -5271,14 +5285,17 @@ out:
+ * has recorded an error from a previous lifetime, move that error to the
+ * main filesystem now.
+ */
+-static void ext4_clear_journal_err(struct super_block *sb,
++static int ext4_clear_journal_err(struct super_block *sb,
+ struct ext4_super_block *es)
+ {
+ journal_t *journal;
+ int j_errno;
+ const char *errstr;
+
+- BUG_ON(!ext4_has_feature_journal(sb));
++ if (!ext4_has_feature_journal(sb)) {
++ ext4_error(sb, "Journal got removed while the fs was mounted!");
++ return -EFSCORRUPTED;
++ }
+
+ journal = EXT4_SB(sb)->s_journal;
+
+@@ -5303,6 +5320,7 @@ static void ext4_clear_journal_err(struct super_block *sb,
+ jbd2_journal_clear_err(journal);
+ jbd2_journal_update_sb_errno(journal);
+ }
++ return 0;
+ }
+
+ /*
+@@ -5573,8 +5591,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ (sbi->s_mount_state & EXT4_VALID_FS))
+ es->s_state = cpu_to_le16(sbi->s_mount_state);
+
+- if (sbi->s_journal)
++ if (sbi->s_journal) {
++ /*
++ * We let remount-ro finish even if marking fs
++ * as clean failed...
++ */
+ ext4_mark_recovery_complete(sb, es);
++ }
+ if (sbi->s_mmp_tsk)
+ kthread_stop(sbi->s_mmp_tsk);
+ } else {
+@@ -5622,8 +5645,11 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ * been changed by e2fsck since we originally mounted
+ * the partition.)
+ */
+- if (sbi->s_journal)
+- ext4_clear_journal_err(sb, es);
++ if (sbi->s_journal) {
++ err = ext4_clear_journal_err(sb, es);
++ if (err)
++ goto restore_opts;
++ }
+ sbi->s_mount_state = le16_to_cpu(es->s_state);
+
+ err = ext4_setup_super(sb, es, 0);
+--
+2.25.1
+
--- /dev/null
+From e9c1b749f8ff50ad1c6a0021bb70474773ebf1d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Jul 2020 15:04:32 +0200
+Subject: ext4: handle error of ext4_setup_system_zone() on remount
+
+From: Jan Kara <jack@suse.cz>
+
+[ Upstream commit d176b1f62f242ab259ff665a26fbac69db1aecba ]
+
+ext4_setup_system_zone() can fail. Handle the failure in ext4_remount().
+
+Reviewed-by: Lukas Czerner <lczerner@redhat.com>
+Signed-off-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20200728130437.7804-2-jack@suse.cz
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 85849e5b31b28..54d1c09329e55 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5716,7 +5716,10 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ ext4_register_li_request(sb, first_not_zeroed);
+ }
+
+- ext4_setup_system_zone(sb);
++ err = ext4_setup_system_zone(sb);
++ if (err)
++ goto restore_opts;
++
+ if (sbi->s_journal == NULL && !(old_sb_flags & SB_RDONLY)) {
+ err = ext4_commit_super(sb, 1);
+ if (err)
+--
+2.25.1
+
--- /dev/null
+From d2dc27f8fa6acb0a6e34ea4e276b6364be046016 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2020 17:05:26 +0200
+Subject: ext4: handle option set by mount flags correctly
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+[ Upstream commit f25391ebb475d3ffb3aa61bb90e3594c841749ef ]
+
+Currently there is a problem with mount options that can be both set by
+vfs using mount flags or by a string parsing in ext4.
+
+i_version/iversion options gets lost after remount, for example
+
+$ mount -o i_version /dev/pmem0 /mnt
+$ grep pmem0 /proc/self/mountinfo | grep i_version
+310 95 259:0 / /mnt rw,relatime shared:163 - ext4 /dev/pmem0 rw,seclabel,i_version
+$ mount -o remount,ro /mnt
+$ grep pmem0 /proc/self/mountinfo | grep i_version
+
+nolazytime gets ignored by ext4 on remount, for example
+
+$ mount -o lazytime /dev/pmem0 /mnt
+$ grep pmem0 /proc/self/mountinfo | grep lazytime
+310 95 259:0 / /mnt rw,relatime shared:163 - ext4 /dev/pmem0 rw,lazytime,seclabel
+$ mount -o remount,nolazytime /mnt
+$ grep pmem0 /proc/self/mountinfo | grep lazytime
+310 95 259:0 / /mnt rw,relatime shared:163 - ext4 /dev/pmem0 rw,lazytime,seclabel
+
+Fix it by applying the SB_LAZYTIME and SB_I_VERSION flags from *flags to
+s_flags before we parse the option and use the resulting state of the
+same flags in *flags at the end of successful remount.
+
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Reviewed-by: Ritesh Harjani <riteshh@linux.ibm.com>
+Link: https://lore.kernel.org/r/20200723150526.19931-1-lczerner@redhat.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 21 ++++++++++++++++-----
+ 1 file changed, 16 insertions(+), 5 deletions(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index c77b10257b36a..85849e5b31b28 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5487,7 +5487,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ {
+ struct ext4_super_block *es;
+ struct ext4_sb_info *sbi = EXT4_SB(sb);
+- unsigned long old_sb_flags;
++ unsigned long old_sb_flags, vfs_flags;
+ struct ext4_mount_options old_opts;
+ int enable_quota = 0;
+ ext4_group_t g;
+@@ -5530,6 +5530,14 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ if (sbi->s_journal && sbi->s_journal->j_task->io_context)
+ journal_ioprio = sbi->s_journal->j_task->io_context->ioprio;
+
++ /*
++ * Some options can be enabled by ext4 and/or by VFS mount flag
++ * either way we need to make sure it matches in both *flags and
++ * s_flags. Copy those selected flags from *flags to s_flags
++ */
++ vfs_flags = SB_LAZYTIME | SB_I_VERSION;
++ sb->s_flags = (sb->s_flags & ~vfs_flags) | (*flags & vfs_flags);
++
+ if (!parse_options(data, sb, NULL, &journal_ioprio, 1)) {
+ err = -EINVAL;
+ goto restore_opts;
+@@ -5583,9 +5591,6 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ set_task_ioprio(sbi->s_journal->j_task, journal_ioprio);
+ }
+
+- if (*flags & SB_LAZYTIME)
+- sb->s_flags |= SB_LAZYTIME;
+-
+ if ((bool)(*flags & SB_RDONLY) != sb_rdonly(sb)) {
+ if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) {
+ err = -EROFS;
+@@ -5733,7 +5738,13 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data)
+ }
+ #endif
+
+- *flags = (*flags & ~SB_LAZYTIME) | (sb->s_flags & SB_LAZYTIME);
++ /*
++ * Some options can be enabled by ext4 and/or by VFS mount flag
++ * either way we need to make sure it matches in both *flags and
++ * s_flags. Copy those selected flags from s_flags to *flags
++ */
++ *flags = (*flags & ~vfs_flags) | (sb->s_flags & vfs_flags);
++
+ ext4_msg(sb, KERN_INFO, "re-mounted. Opts: %s", orig_data);
+ kfree(orig_data);
+ return 0;
+--
+2.25.1
+
--- /dev/null
+From c35e48a0babf8db4dd8aa578fc9194354d79d2b3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Jul 2020 11:06:05 +0200
+Subject: ext4: handle read only external journal device
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+[ Upstream commit 273108fa5015eeffc4bacfa5ce272af3434b96e4 ]
+
+Ext4 uses blkdev_get_by_dev() to get the block_device for journal device
+which does check to see if the read-only block device was opened
+read-only.
+
+As a result ext4 will hapily proceed mounting the file system with
+external journal on read-only device. This is bad as we would not be
+able to use the journal leading to errors later on.
+
+Instead of simply failing to mount file system in this case, treat it in
+a similar way we treat internal journal on read-only device. Allow to
+mount with -o noload in read-only mode.
+
+This can be reproduced easily like this:
+
+mke2fs -F -O journal_dev $JOURNAL_DEV 100M
+mkfs.$FSTYPE -F -J device=$JOURNAL_DEV $FS_DEV
+blockdev --setro $JOURNAL_DEV
+mount $FS_DEV $MNT
+touch $MNT/file
+umount $MNT
+
+leading to error like this
+
+[ 1307.318713] ------------[ cut here ]------------
+[ 1307.323362] generic_make_request: Trying to write to read-only block-device dm-2 (partno 0)
+[ 1307.331741] WARNING: CPU: 36 PID: 3224 at block/blk-core.c:855 generic_make_request_checks+0x2c3/0x580
+[ 1307.341041] Modules linked in: ext4 mbcache jbd2 rfkill intel_rapl_msr intel_rapl_common isst_if_commd
+[ 1307.419445] CPU: 36 PID: 3224 Comm: jbd2/dm-2 Tainted: G W I 5.8.0-rc5 #2
+[ 1307.427359] Hardware name: Dell Inc. PowerEdge R740/01KPX8, BIOS 2.3.10 08/15/2019
+[ 1307.434932] RIP: 0010:generic_make_request_checks+0x2c3/0x580
+[ 1307.440676] Code: 94 03 00 00 48 89 df 48 8d 74 24 08 c6 05 cf 2b 18 01 01 e8 7f a4 ff ff 48 c7 c7 50e
+[ 1307.459420] RSP: 0018:ffffc0d70eb5fb48 EFLAGS: 00010286
+[ 1307.464646] RAX: 0000000000000000 RBX: ffff9b33b2978300 RCX: 0000000000000000
+[ 1307.471780] RDX: ffff9b33e12a81e0 RSI: ffff9b33e1298000 RDI: ffff9b33e1298000
+[ 1307.478913] RBP: ffff9b7b9679e0c0 R08: 0000000000000837 R09: 0000000000000024
+[ 1307.486044] R10: 0000000000000000 R11: ffffc0d70eb5f9f0 R12: 0000000000000400
+[ 1307.493177] R13: 0000000000000000 R14: 0000000000000001 R15: 0000000000000000
+[ 1307.500308] FS: 0000000000000000(0000) GS:ffff9b33e1280000(0000) knlGS:0000000000000000
+[ 1307.508396] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1307.514142] CR2: 000055eaf4109000 CR3: 0000003dee40a006 CR4: 00000000007606e0
+[ 1307.521273] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 1307.528407] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 1307.535538] PKRU: 55555554
+[ 1307.538250] Call Trace:
+[ 1307.540708] generic_make_request+0x30/0x340
+[ 1307.544985] submit_bio+0x43/0x190
+[ 1307.548393] ? bio_add_page+0x62/0x90
+[ 1307.552068] submit_bh_wbc+0x16a/0x190
+[ 1307.555833] jbd2_write_superblock+0xec/0x200 [jbd2]
+[ 1307.560803] jbd2_journal_update_sb_log_tail+0x65/0xc0 [jbd2]
+[ 1307.566557] jbd2_journal_commit_transaction+0x2ae/0x1860 [jbd2]
+[ 1307.572566] ? check_preempt_curr+0x7a/0x90
+[ 1307.576756] ? update_curr+0xe1/0x1d0
+[ 1307.580421] ? account_entity_dequeue+0x7b/0xb0
+[ 1307.584955] ? newidle_balance+0x231/0x3d0
+[ 1307.589056] ? __switch_to_asm+0x42/0x70
+[ 1307.592986] ? __switch_to_asm+0x36/0x70
+[ 1307.596918] ? lock_timer_base+0x67/0x80
+[ 1307.600851] kjournald2+0xbd/0x270 [jbd2]
+[ 1307.604873] ? finish_wait+0x80/0x80
+[ 1307.608460] ? commit_timeout+0x10/0x10 [jbd2]
+[ 1307.612915] kthread+0x114/0x130
+[ 1307.616152] ? kthread_park+0x80/0x80
+[ 1307.619816] ret_from_fork+0x22/0x30
+[ 1307.623400] ---[ end trace 27490236265b1630 ]---
+
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Reviewed-by: Andreas Dilger <adilger@dilger.ca>
+Link: https://lore.kernel.org/r/20200717090605.2612-1-lczerner@redhat.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/super.c | 51 ++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 33 insertions(+), 18 deletions(-)
+
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 9fdad843b30ef..dda967efcbc2c 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5079,6 +5079,7 @@ static int ext4_load_journal(struct super_block *sb,
+ dev_t journal_dev;
+ int err = 0;
+ int really_read_only;
++ int journal_dev_ro;
+
+ if (WARN_ON_ONCE(!ext4_has_feature_journal(sb)))
+ return -EFSCORRUPTED;
+@@ -5091,7 +5092,31 @@ static int ext4_load_journal(struct super_block *sb,
+ } else
+ journal_dev = new_decode_dev(le32_to_cpu(es->s_journal_dev));
+
+- really_read_only = bdev_read_only(sb->s_bdev);
++ if (journal_inum && journal_dev) {
++ ext4_msg(sb, KERN_ERR,
++ "filesystem has both journal inode and journal device!");
++ return -EINVAL;
++ }
++
++ if (journal_inum) {
++ journal = ext4_get_journal(sb, journal_inum);
++ if (!journal)
++ return -EINVAL;
++ } else {
++ journal = ext4_get_dev_journal(sb, journal_dev);
++ if (!journal)
++ return -EINVAL;
++ }
++
++ journal_dev_ro = bdev_read_only(journal->j_dev);
++ really_read_only = bdev_read_only(sb->s_bdev) | journal_dev_ro;
++
++ if (journal_dev_ro && !sb_rdonly(sb)) {
++ ext4_msg(sb, KERN_ERR,
++ "journal device read-only, try mounting with '-o ro'");
++ err = -EROFS;
++ goto err_out;
++ }
+
+ /*
+ * Are we loading a blank journal or performing recovery after a
+@@ -5106,27 +5131,14 @@ static int ext4_load_journal(struct super_block *sb,
+ ext4_msg(sb, KERN_ERR, "write access "
+ "unavailable, cannot proceed "
+ "(try mounting with noload)");
+- return -EROFS;
++ err = -EROFS;
++ goto err_out;
+ }
+ ext4_msg(sb, KERN_INFO, "write access will "
+ "be enabled during recovery");
+ }
+ }
+
+- if (journal_inum && journal_dev) {
+- ext4_msg(sb, KERN_ERR, "filesystem has both journal "
+- "and inode journals!");
+- return -EINVAL;
+- }
+-
+- if (journal_inum) {
+- if (!(journal = ext4_get_journal(sb, journal_inum)))
+- return -EINVAL;
+- } else {
+- if (!(journal = ext4_get_dev_journal(sb, journal_dev)))
+- return -EINVAL;
+- }
+-
+ if (!(journal->j_flags & JBD2_BARRIER))
+ ext4_msg(sb, KERN_INFO, "barriers disabled");
+
+@@ -5146,8 +5158,7 @@ static int ext4_load_journal(struct super_block *sb,
+
+ if (err) {
+ ext4_msg(sb, KERN_ERR, "error loading journal");
+- jbd2_journal_destroy(journal);
+- return err;
++ goto err_out;
+ }
+
+ EXT4_SB(sb)->s_journal = journal;
+@@ -5167,6 +5178,10 @@ static int ext4_load_journal(struct super_block *sb,
+ }
+
+ return 0;
++
++err_out:
++ jbd2_journal_destroy(journal);
++ return err;
+ }
+
+ static int ext4_commit_super(struct super_block *sb, int sync)
+--
+2.25.1
+
--- /dev/null
+From c942966aba06efba2bb0acf56b222f30b7ddbe56 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Aug 2020 15:36:15 +0800
+Subject: ext4: limit the length of per-inode prealloc list
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: brookxu <brookxu.cn@gmail.com>
+
+[ Upstream commit 27bc446e2def38db3244a6eb4bb1d6312936610a ]
+
+In the scenario of writing sparse files, the per-inode prealloc list may
+be very long, resulting in high overhead for ext4_mb_use_preallocated().
+To circumvent this problem, we limit the maximum length of per-inode
+prealloc list to 512 and allow users to modify it.
+
+After patching, we observed that the sys ratio of cpu has dropped, and
+the system throughput has increased significantly. We created a process
+to write the sparse file, and the running time of the process on the
+fixed kernel was significantly reduced, as follows:
+
+Running time on unfixed kernel:
+[root@TENCENT64 ~]# time taskset 0x01 ./sparse /data1/sparce.dat
+real 0m2.051s
+user 0m0.008s
+sys 0m2.026s
+
+Running time on fixed kernel:
+[root@TENCENT64 ~]# time taskset 0x01 ./sparse /data1/sparce.dat
+real 0m0.471s
+user 0m0.004s
+sys 0m0.395s
+
+Signed-off-by: Chunguang Xu <brookxu@tencent.com>
+Link: https://lore.kernel.org/r/d7a98178-056b-6db5-6bce-4ead23f4a257@gmail.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/admin-guide/ext4.rst | 3 ++
+ fs/ext4/ext4.h | 4 +-
+ fs/ext4/extents.c | 10 ++--
+ fs/ext4/file.c | 2 +-
+ fs/ext4/indirect.c | 2 +-
+ fs/ext4/inode.c | 6 +--
+ fs/ext4/ioctl.c | 2 +-
+ fs/ext4/mballoc.c | 74 ++++++++++++++++++++++++++----
+ fs/ext4/mballoc.h | 4 ++
+ fs/ext4/move_extent.c | 4 +-
+ fs/ext4/super.c | 3 +-
+ fs/ext4/sysfs.c | 2 +
+ include/trace/events/ext4.h | 17 ++++---
+ 13 files changed, 104 insertions(+), 29 deletions(-)
+
+diff --git a/Documentation/admin-guide/ext4.rst b/Documentation/admin-guide/ext4.rst
+index 9443fcef18760..f37d0743fd668 100644
+--- a/Documentation/admin-guide/ext4.rst
++++ b/Documentation/admin-guide/ext4.rst
+@@ -482,6 +482,9 @@ Files in /sys/fs/ext4/<devname>:
+ multiple of this tuning parameter if the stripe size is not set in the
+ ext4 superblock
+
++ mb_max_inode_prealloc
++ The maximum length of per-inode ext4_prealloc_space list.
++
+ mb_max_to_scan
+ The maximum number of extents the multiblock allocator will search to
+ find the best extent.
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index eec5c03534d05..ff46defc65683 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -1054,6 +1054,7 @@ struct ext4_inode_info {
+ struct timespec64 i_crtime;
+
+ /* mballoc */
++ atomic_t i_prealloc_active;
+ struct list_head i_prealloc_list;
+ spinlock_t i_prealloc_lock;
+
+@@ -1501,6 +1502,7 @@ struct ext4_sb_info {
+ unsigned int s_mb_stats;
+ unsigned int s_mb_order2_reqs;
+ unsigned int s_mb_group_prealloc;
++ unsigned int s_mb_max_inode_prealloc;
+ unsigned int s_max_dir_size_kb;
+ /* where last allocation was done - for stream allocation */
+ unsigned long s_mb_last_group;
+@@ -2654,7 +2656,7 @@ extern int ext4_mb_release(struct super_block *);
+ extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *,
+ struct ext4_allocation_request *, int *);
+ extern int ext4_mb_reserve_blocks(struct super_block *, int);
+-extern void ext4_discard_preallocations(struct inode *);
++extern void ext4_discard_preallocations(struct inode *, unsigned int);
+ extern int __init ext4_init_mballoc(void);
+ extern void ext4_exit_mballoc(void);
+ extern void ext4_free_blocks(handle_t *handle, struct inode *inode,
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index d75054570e44c..11a321dd11e7e 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -100,7 +100,7 @@ static int ext4_ext_trunc_restart_fn(struct inode *inode, int *dropped)
+ * i_mutex. So we can safely drop the i_data_sem here.
+ */
+ BUG_ON(EXT4_JOURNAL(inode) == NULL);
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+ up_write(&EXT4_I(inode)->i_data_sem);
+ *dropped = 1;
+ return 0;
+@@ -4268,7 +4268,7 @@ got_allocated_blocks:
+ * not a good idea to call discard here directly,
+ * but otherwise we'd need to call it every free().
+ */
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+ if (flags & EXT4_GET_BLOCKS_DELALLOC_RESERVE)
+ fb_flags = EXT4_FREE_BLOCKS_NO_QUOT_UPDATE;
+ ext4_free_blocks(handle, inode, NULL, newblock,
+@@ -5295,7 +5295,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
+ }
+
+ down_write(&EXT4_I(inode)->i_data_sem);
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+
+ ret = ext4_es_remove_extent(inode, punch_start,
+ EXT_MAX_BLOCKS - punch_start);
+@@ -5309,7 +5309,7 @@ static int ext4_collapse_range(struct inode *inode, loff_t offset, loff_t len)
+ up_write(&EXT4_I(inode)->i_data_sem);
+ goto out_stop;
+ }
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+
+ ret = ext4_ext_shift_extents(inode, handle, punch_stop,
+ punch_stop - punch_start, SHIFT_LEFT);
+@@ -5441,7 +5441,7 @@ static int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
+ goto out_stop;
+
+ down_write(&EXT4_I(inode)->i_data_sem);
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+
+ path = ext4_find_extent(inode, offset_lblk, NULL, 0);
+ if (IS_ERR(path)) {
+diff --git a/fs/ext4/file.c b/fs/ext4/file.c
+index 8f742b53f1d40..4ee9a4dc01a88 100644
+--- a/fs/ext4/file.c
++++ b/fs/ext4/file.c
+@@ -148,7 +148,7 @@ static int ext4_release_file(struct inode *inode, struct file *filp)
+ !EXT4_I(inode)->i_reserved_data_blocks)
+ {
+ down_write(&EXT4_I(inode)->i_data_sem);
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+ up_write(&EXT4_I(inode)->i_data_sem);
+ }
+ if (is_dx(inode) && filp->private_data)
+diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
+index 4026418257121..e8ca405673923 100644
+--- a/fs/ext4/indirect.c
++++ b/fs/ext4/indirect.c
+@@ -696,7 +696,7 @@ static int ext4_ind_trunc_restart_fn(handle_t *handle, struct inode *inode,
+ * i_mutex. So we can safely drop the i_data_sem here.
+ */
+ BUG_ON(EXT4_JOURNAL(inode) == NULL);
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+ up_write(&EXT4_I(inode)->i_data_sem);
+ *dropped = 1;
+ return 0;
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 92573f8540ab7..9c0629ffb4261 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -383,7 +383,7 @@ void ext4_da_update_reserve_space(struct inode *inode,
+ */
+ if ((ei->i_reserved_data_blocks == 0) &&
+ !inode_is_open_for_write(inode))
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+ }
+
+ static int __check_block_validity(struct inode *inode, const char *func,
+@@ -4055,7 +4055,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
+ if (stop_block > first_block) {
+
+ down_write(&EXT4_I(inode)->i_data_sem);
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+
+ ret = ext4_es_remove_extent(inode, first_block,
+ stop_block - first_block);
+@@ -4210,7 +4210,7 @@ int ext4_truncate(struct inode *inode)
+
+ down_write(&EXT4_I(inode)->i_data_sem);
+
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+
+ if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
+ err = ext4_ext_truncate(handle, inode);
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index 999cf6add39c6..a5fcc238c6693 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -202,7 +202,7 @@ static long swap_inode_boot_loader(struct super_block *sb,
+ reset_inode_seed(inode);
+ reset_inode_seed(inode_bl);
+
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+
+ err = ext4_mark_inode_dirty(handle, inode);
+ if (err < 0) {
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index ba5371b35b09e..e88eff999bd15 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2755,6 +2755,7 @@ int ext4_mb_init(struct super_block *sb)
+ sbi->s_mb_stats = MB_DEFAULT_STATS;
+ sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD;
+ sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS;
++ sbi->s_mb_max_inode_prealloc = MB_DEFAULT_MAX_INODE_PREALLOC;
+ /*
+ * The default group preallocation is 512, which for 4k block
+ * sizes translates to 2 megabytes. However for bigalloc file
+@@ -3693,6 +3694,26 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
+ mb_debug(sb, "preallocated %d for group %u\n", preallocated, group);
+ }
+
++static void ext4_mb_mark_pa_deleted(struct super_block *sb,
++ struct ext4_prealloc_space *pa)
++{
++ struct ext4_inode_info *ei;
++
++ if (pa->pa_deleted) {
++ ext4_warning(sb, "deleted pa, type:%d, pblk:%llu, lblk:%u, len:%d\n",
++ pa->pa_type, pa->pa_pstart, pa->pa_lstart,
++ pa->pa_len);
++ return;
++ }
++
++ pa->pa_deleted = 1;
++
++ if (pa->pa_type == MB_INODE_PA) {
++ ei = EXT4_I(pa->pa_inode);
++ atomic_dec(&ei->i_prealloc_active);
++ }
++}
++
+ static void ext4_mb_pa_callback(struct rcu_head *head)
+ {
+ struct ext4_prealloc_space *pa;
+@@ -3725,7 +3746,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac,
+ return;
+ }
+
+- pa->pa_deleted = 1;
++ ext4_mb_mark_pa_deleted(sb, pa);
+ spin_unlock(&pa->pa_lock);
+
+ grp_blk = pa->pa_pstart;
+@@ -3849,6 +3870,7 @@ ext4_mb_new_inode_pa(struct ext4_allocation_context *ac)
+ spin_lock(pa->pa_obj_lock);
+ list_add_rcu(&pa->pa_inode_list, &ei->i_prealloc_list);
+ spin_unlock(pa->pa_obj_lock);
++ atomic_inc(&ei->i_prealloc_active);
+ }
+
+ /*
+@@ -4059,7 +4081,7 @@ repeat:
+ }
+
+ /* seems this one can be freed ... */
+- pa->pa_deleted = 1;
++ ext4_mb_mark_pa_deleted(sb, pa);
+
+ /* we can trust pa_free ... */
+ free += pa->pa_free;
+@@ -4122,7 +4144,7 @@ out_dbg:
+ *
+ * FIXME!! Make sure it is valid at all the call sites
+ */
+-void ext4_discard_preallocations(struct inode *inode)
++void ext4_discard_preallocations(struct inode *inode, unsigned int needed)
+ {
+ struct ext4_inode_info *ei = EXT4_I(inode);
+ struct super_block *sb = inode->i_sb;
+@@ -4140,15 +4162,19 @@ void ext4_discard_preallocations(struct inode *inode)
+
+ mb_debug(sb, "discard preallocation for inode %lu\n",
+ inode->i_ino);
+- trace_ext4_discard_preallocations(inode);
++ trace_ext4_discard_preallocations(inode,
++ atomic_read(&ei->i_prealloc_active), needed);
+
+ INIT_LIST_HEAD(&list);
+
++ if (needed == 0)
++ needed = UINT_MAX;
++
+ repeat:
+ /* first, collect all pa's in the inode */
+ spin_lock(&ei->i_prealloc_lock);
+- while (!list_empty(&ei->i_prealloc_list)) {
+- pa = list_entry(ei->i_prealloc_list.next,
++ while (!list_empty(&ei->i_prealloc_list) && needed) {
++ pa = list_entry(ei->i_prealloc_list.prev,
+ struct ext4_prealloc_space, pa_inode_list);
+ BUG_ON(pa->pa_obj_lock != &ei->i_prealloc_lock);
+ spin_lock(&pa->pa_lock);
+@@ -4165,10 +4191,11 @@ repeat:
+
+ }
+ if (pa->pa_deleted == 0) {
+- pa->pa_deleted = 1;
++ ext4_mb_mark_pa_deleted(sb, pa);
+ spin_unlock(&pa->pa_lock);
+ list_del_rcu(&pa->pa_inode_list);
+ list_add(&pa->u.pa_tmp_list, &list);
++ needed--;
+ continue;
+ }
+
+@@ -4469,7 +4496,7 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
+ BUG_ON(pa->pa_type != MB_GROUP_PA);
+
+ /* seems this one can be freed ... */
+- pa->pa_deleted = 1;
++ ext4_mb_mark_pa_deleted(sb, pa);
+ spin_unlock(&pa->pa_lock);
+
+ list_del_rcu(&pa->pa_inode_list);
+@@ -4567,11 +4594,30 @@ static void ext4_mb_add_n_trim(struct ext4_allocation_context *ac)
+ return ;
+ }
+
++/*
++ * if per-inode prealloc list is too long, trim some PA
++ */
++static void ext4_mb_trim_inode_pa(struct inode *inode)
++{
++ struct ext4_inode_info *ei = EXT4_I(inode);
++ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
++ int count, delta;
++
++ count = atomic_read(&ei->i_prealloc_active);
++ delta = (sbi->s_mb_max_inode_prealloc >> 2) + 1;
++ if (count > sbi->s_mb_max_inode_prealloc + delta) {
++ count -= sbi->s_mb_max_inode_prealloc;
++ ext4_discard_preallocations(inode, count);
++ }
++}
++
+ /*
+ * release all resource we used in allocation
+ */
+ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
+ {
++ struct inode *inode = ac->ac_inode;
++ struct ext4_inode_info *ei = EXT4_I(inode);
+ struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb);
+ struct ext4_prealloc_space *pa = ac->ac_pa;
+ if (pa) {
+@@ -4598,6 +4644,17 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
+ spin_unlock(pa->pa_obj_lock);
+ ext4_mb_add_n_trim(ac);
+ }
++
++ if (pa->pa_type == MB_INODE_PA) {
++ /*
++ * treat per-inode prealloc list as a lru list, then try
++ * to trim the least recently used PA.
++ */
++ spin_lock(pa->pa_obj_lock);
++ list_move(&pa->pa_inode_list, &ei->i_prealloc_list);
++ spin_unlock(pa->pa_obj_lock);
++ }
++
+ ext4_mb_put_pa(ac, ac->ac_sb, pa);
+ }
+ if (ac->ac_bitmap_page)
+@@ -4607,6 +4664,7 @@ static int ext4_mb_release_context(struct ext4_allocation_context *ac)
+ if (ac->ac_flags & EXT4_MB_HINT_GROUP_ALLOC)
+ mutex_unlock(&ac->ac_lg->lg_mutex);
+ ext4_mb_collect_stats(ac);
++ ext4_mb_trim_inode_pa(inode);
+ return 0;
+ }
+
+diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h
+index 6b4d17c2935d6..e75b4749aa1c2 100644
+--- a/fs/ext4/mballoc.h
++++ b/fs/ext4/mballoc.h
+@@ -73,6 +73,10 @@
+ */
+ #define MB_DEFAULT_GROUP_PREALLOC 512
+
++/*
++ * maximum length of inode prealloc list
++ */
++#define MB_DEFAULT_MAX_INODE_PREALLOC 512
+
+ struct ext4_free_data {
+ /* this links the free block information from sb_info */
+diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
+index 1ed86fb6c3026..0d601b8228753 100644
+--- a/fs/ext4/move_extent.c
++++ b/fs/ext4/move_extent.c
+@@ -686,8 +686,8 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
+
+ out:
+ if (*moved_len) {
+- ext4_discard_preallocations(orig_inode);
+- ext4_discard_preallocations(donor_inode);
++ ext4_discard_preallocations(orig_inode, 0);
++ ext4_discard_preallocations(donor_inode, 0);
+ }
+
+ ext4_ext_drop_refs(path);
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index f3614299ffd09..0b38bf29c07e0 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -1123,6 +1123,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
+ inode_set_iversion(&ei->vfs_inode, 1);
+ spin_lock_init(&ei->i_raw_lock);
+ INIT_LIST_HEAD(&ei->i_prealloc_list);
++ atomic_set(&ei->i_prealloc_active, 0);
+ spin_lock_init(&ei->i_prealloc_lock);
+ ext4_es_init_tree(&ei->i_es_tree);
+ rwlock_init(&ei->i_es_lock);
+@@ -1216,7 +1217,7 @@ void ext4_clear_inode(struct inode *inode)
+ {
+ invalidate_inode_buffers(inode);
+ clear_inode(inode);
+- ext4_discard_preallocations(inode);
++ ext4_discard_preallocations(inode, 0);
+ ext4_es_remove_extent(inode, 0, EXT_MAX_BLOCKS);
+ dquot_drop(inode);
+ if (EXT4_I(inode)->jinode) {
+diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
+index 6c9fc9e21c138..92f04e9e94413 100644
+--- a/fs/ext4/sysfs.c
++++ b/fs/ext4/sysfs.c
+@@ -215,6 +215,7 @@ EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan);
+ EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs);
+ EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request);
+ EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc);
++EXT4_RW_ATTR_SBI_UI(mb_max_inode_prealloc, s_mb_max_inode_prealloc);
+ EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb);
+ EXT4_ATTR(trigger_fs_error, 0200, trigger_test_error);
+ EXT4_RW_ATTR_SBI_UI(err_ratelimit_interval_ms, s_err_ratelimit_state.interval);
+@@ -257,6 +258,7 @@ static struct attribute *ext4_attrs[] = {
+ ATTR_LIST(mb_order2_req),
+ ATTR_LIST(mb_stream_req),
+ ATTR_LIST(mb_group_prealloc),
++ ATTR_LIST(mb_max_inode_prealloc),
+ ATTR_LIST(max_writeback_mb_bump),
+ ATTR_LIST(extent_max_zeroout_kb),
+ ATTR_LIST(trigger_fs_error),
+diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
+index cc41d692ae8ed..628db6a07fda0 100644
+--- a/include/trace/events/ext4.h
++++ b/include/trace/events/ext4.h
+@@ -746,24 +746,29 @@ TRACE_EVENT(ext4_mb_release_group_pa,
+ );
+
+ TRACE_EVENT(ext4_discard_preallocations,
+- TP_PROTO(struct inode *inode),
++ TP_PROTO(struct inode *inode, unsigned int len, unsigned int needed),
+
+- TP_ARGS(inode),
++ TP_ARGS(inode, len, needed),
+
+ TP_STRUCT__entry(
+- __field( dev_t, dev )
+- __field( ino_t, ino )
++ __field( dev_t, dev )
++ __field( ino_t, ino )
++ __field( unsigned int, len )
++ __field( unsigned int, needed )
+
+ ),
+
+ TP_fast_assign(
+ __entry->dev = inode->i_sb->s_dev;
+ __entry->ino = inode->i_ino;
++ __entry->len = len;
++ __entry->needed = needed;
+ ),
+
+- TP_printk("dev %d,%d ino %lu",
++ TP_printk("dev %d,%d ino %lu len: %u needed %u",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+- (unsigned long) __entry->ino)
++ (unsigned long) __entry->ino, __entry->len,
++ __entry->needed)
+ );
+
+ TRACE_EVENT(ext4_mb_discard_preallocations,
+--
+2.25.1
+
--- /dev/null
+From 0b4218e04f611ac5aa132b8e69fc6251d013c1e8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Jun 2020 22:08:56 -0400
+Subject: ext4: skip non-loaded groups at cr=0/1 when scanning for good groups
+
+From: Alex Zhuravlev <azhuravlev@whamcloud.com>
+
+[ Upstream commit c1d2c7d47e15482bb23cda83a5021e60f624a09c ]
+
+cr=0 is supposed to be an optimization to save CPU cycles, but if
+buddy data (in memory) is not initialized then all this makes no sense
+as we have to do sync IO taking a lot of cycles. Also, at cr=0
+mballoc doesn't choose any available chunk. cr=1 also skips groups
+using heuristic based on avg. fragment size. It's more useful to skip
+such groups and switch to cr=2 where groups will be scanned for
+available chunks. However, we always read the first block group in a
+flex_bg so metadata blocks will get read into the first flex_bg if
+possible.
+
+Using sparse image and dm-slow virtual device of 120TB was
+simulated, then the image was formatted and filled using debugfs to
+mark ~85% of available space as busy. mount process w/o the patch
+couldn't complete in half an hour (according to vmstat it would take
+~10-11 hours). With the patch applied mount took ~20 seconds.
+
+Lustre-bug-id: https://jira.whamcloud.com/browse/LU-12988
+Signed-off-by: Alex Zhuravlev <azhuravlev@whamcloud.com>
+Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
+Reviewed-by: Artem Blagodarenko <artem.blagodarenko@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ext4/mballoc.c | 21 ++++++++++++++++++++-
+ 1 file changed, 20 insertions(+), 1 deletion(-)
+
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 38719c156573c..ba5371b35b09e 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2177,6 +2177,7 @@ static int ext4_mb_good_group_nolock(struct ext4_allocation_context *ac,
+ {
+ struct ext4_group_info *grp = ext4_get_group_info(ac->ac_sb, group);
+ struct super_block *sb = ac->ac_sb;
++ struct ext4_sb_info *sbi = EXT4_SB(sb);
+ bool should_lock = ac->ac_flags & EXT4_MB_STRICT_CHECK;
+ ext4_grpblk_t free;
+ int ret = 0;
+@@ -2195,7 +2196,25 @@ static int ext4_mb_good_group_nolock(struct ext4_allocation_context *ac,
+
+ /* We only do this if the grp has never been initialized */
+ if (unlikely(EXT4_MB_GRP_NEED_INIT(grp))) {
+- ret = ext4_mb_init_group(ac->ac_sb, group, GFP_NOFS);
++ struct ext4_group_desc *gdp =
++ ext4_get_group_desc(sb, group, NULL);
++ int ret;
++
++ /* cr=0/1 is a very optimistic search to find large
++ * good chunks almost for free. If buddy data is not
++ * ready, then this optimization makes no sense. But
++ * we never skip the first block group in a flex_bg,
++ * since this gets used for metadata block allocation,
++ * and we want to make sure we locate metadata blocks
++ * in the first block group in the flex_bg if possible.
++ */
++ if (cr < 2 &&
++ (!sbi->s_log_groups_per_flex ||
++ ((group & ((1 << sbi->s_log_groups_per_flex) - 1)) != 0)) &&
++ !(ext4_has_group_desc_csum(sb) &&
++ (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))))
++ return 0;
++ ret = ext4_mb_init_group(sb, group, GFP_NOFS);
+ if (ret)
+ return ret;
+ }
+--
+2.25.1
+
--- /dev/null
+From 210597e4f50ed3240f899f8a0c102323567d92f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 31 Jul 2020 12:10:25 -0400
+Subject: fs: prevent BUG_ON in submit_bh_wbc()
+
+From: Xianting Tian <xianting_tian@126.com>
+
+[ Upstream commit 377254b2cd2252c7c3151b113cbdf93a7736c2e9 ]
+
+If a device is hot-removed --- for example, when a physical device is
+unplugged from pcie slot or a nbd device's network is shutdown ---
+this can result in a BUG_ON() crash in submit_bh_wbc(). This is
+because the when the block device dies, the buffer heads will have
+their Buffer_Mapped flag get cleared, leading to the crash in
+submit_bh_wbc.
+
+We had attempted to work around this problem in commit a17712c8
+("ext4: check superblock mapped prior to committing"). Unfortunately,
+it's still possible to hit the BUG_ON(!buffer_mapped(bh)) if the
+device dies between when the work-around check in ext4_commit_super()
+and when submit_bh_wbh() is finally called:
+
+Code path:
+ext4_commit_super
+ judge if 'buffer_mapped(sbh)' is false, return <== commit a17712c8
+ lock_buffer(sbh)
+ ...
+ unlock_buffer(sbh)
+ __sync_dirty_buffer(sbh,...
+ lock_buffer(sbh)
+ judge if 'buffer_mapped(sbh))' is false, return <== added by this patch
+ submit_bh(...,sbh)
+ submit_bh_wbc(...,sbh,...)
+
+[100722.966497] kernel BUG at fs/buffer.c:3095! <== BUG_ON(!buffer_mapped(bh))' in submit_bh_wbc()
+[100722.966503] invalid opcode: 0000 [#1] SMP
+[100722.966566] task: ffff8817e15a9e40 task.stack: ffffc90024744000
+[100722.966574] RIP: 0010:submit_bh_wbc+0x180/0x190
+[100722.966575] RSP: 0018:ffffc90024747a90 EFLAGS: 00010246
+[100722.966576] RAX: 0000000000620005 RBX: ffff8818a80603a8 RCX: 0000000000000000
+[100722.966576] RDX: ffff8818a80603a8 RSI: 0000000000020800 RDI: 0000000000000001
+[100722.966577] RBP: ffffc90024747ac0 R08: 0000000000000000 R09: ffff88207f94170d
+[100722.966578] R10: 00000000000437c8 R11: 0000000000000001 R12: 0000000000020800
+[100722.966578] R13: 0000000000000001 R14: 000000000bf9a438 R15: ffff88195f333000
+[100722.966580] FS: 00007fa2eee27700(0000) GS:ffff88203d840000(0000) knlGS:0000000000000000
+[100722.966580] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[100722.966581] CR2: 0000000000f0b008 CR3: 000000201a622003 CR4: 00000000007606e0
+[100722.966582] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[100722.966583] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[100722.966583] PKRU: 55555554
+[100722.966583] Call Trace:
+[100722.966588] __sync_dirty_buffer+0x6e/0xd0
+[100722.966614] ext4_commit_super+0x1d8/0x290 [ext4]
+[100722.966626] __ext4_std_error+0x78/0x100 [ext4]
+[100722.966635] ? __ext4_journal_get_write_access+0xca/0x120 [ext4]
+[100722.966646] ext4_reserve_inode_write+0x58/0xb0 [ext4]
+[100722.966655] ? ext4_dirty_inode+0x48/0x70 [ext4]
+[100722.966663] ext4_mark_inode_dirty+0x53/0x1e0 [ext4]
+[100722.966671] ? __ext4_journal_start_sb+0x6d/0xf0 [ext4]
+[100722.966679] ext4_dirty_inode+0x48/0x70 [ext4]
+[100722.966682] __mark_inode_dirty+0x17f/0x350
+[100722.966686] generic_update_time+0x87/0xd0
+[100722.966687] touch_atime+0xa9/0xd0
+[100722.966690] generic_file_read_iter+0xa09/0xcd0
+[100722.966694] ? page_cache_tree_insert+0xb0/0xb0
+[100722.966704] ext4_file_read_iter+0x4a/0x100 [ext4]
+[100722.966707] ? __inode_security_revalidate+0x4f/0x60
+[100722.966709] __vfs_read+0xec/0x160
+[100722.966711] vfs_read+0x8c/0x130
+[100722.966712] SyS_pread64+0x87/0xb0
+[100722.966716] do_syscall_64+0x67/0x1b0
+[100722.966719] entry_SYSCALL64_slow_path+0x25/0x25
+
+To address this, add the check of 'buffer_mapped(bh)' to
+__sync_dirty_buffer(). This also has the benefit of fixing this for
+other file systems.
+
+With this addition, we can drop the workaround in ext4_commit_supper().
+
+[ Commit description rewritten by tytso. ]
+
+Signed-off-by: Xianting Tian <xianting_tian@126.com>
+Link: https://lore.kernel.org/r/1596211825-8750-1-git-send-email-xianting_tian@126.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/buffer.c | 9 +++++++++
+ fs/ext4/super.c | 7 -------
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/fs/buffer.c b/fs/buffer.c
+index 64fe82ec65ff1..75a8849abb5d2 100644
+--- a/fs/buffer.c
++++ b/fs/buffer.c
+@@ -3160,6 +3160,15 @@ int __sync_dirty_buffer(struct buffer_head *bh, int op_flags)
+ WARN_ON(atomic_read(&bh->b_count) < 1);
+ lock_buffer(bh);
+ if (test_clear_buffer_dirty(bh)) {
++ /*
++ * The bh should be mapped, but it might not be if the
++ * device was hot-removed. Not much we can do but fail the I/O.
++ */
++ if (!buffer_mapped(bh)) {
++ unlock_buffer(bh);
++ return -EIO;
++ }
++
+ get_bh(bh);
+ bh->b_end_io = end_buffer_write_sync;
+ ret = submit_bh(REQ_OP_WRITE, op_flags, bh);
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 4c8253188d8df..f3614299ffd09 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -5204,13 +5204,6 @@ static int ext4_commit_super(struct super_block *sb, int sync)
+ if (!sbh || block_device_ejected(sb))
+ return error;
+
+- /*
+- * The superblock bh should be mapped, but it might not be if the
+- * device was hot-removed. Not much we can do but fail the I/O.
+- */
+- if (!buffer_mapped(sbh))
+- return error;
+-
+ /*
+ * If the file system is mounted read-only, don't update the
+ * superblock write time. This avoids updating the superblock
+--
+2.25.1
+
--- /dev/null
+From e6f558a30ca0caa3452deb76c01547cea2dd7c43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Aug 2020 17:36:36 +0300
+Subject: habanalabs: Fix memory corruption in debugfs
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit eeec23cd325ad4d83927b8ee162693579cf3813f ]
+
+This has to be a long instead of a u32 because we write a long value.
+On 64 bit systems, this will cause memory corruption.
+
+Fixes: c216477363a3 ("habanalabs: add debugfs support")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Reviewed-by: Oded Gabbay <oded.gabbay@gmail.com>
+Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/habanalabs/debugfs.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/misc/habanalabs/debugfs.c b/drivers/misc/habanalabs/debugfs.c
+index 0bc036e01ee8d..6c2b9cf45e831 100644
+--- a/drivers/misc/habanalabs/debugfs.c
++++ b/drivers/misc/habanalabs/debugfs.c
+@@ -19,7 +19,7 @@
+ static struct dentry *hl_debug_root;
+
+ static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
+- u8 i2c_reg, u32 *val)
++ u8 i2c_reg, long *val)
+ {
+ struct armcp_packet pkt;
+ int rc;
+@@ -36,7 +36,7 @@ static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
+ pkt.i2c_reg = i2c_reg;
+
+ rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
+- 0, (long *) val);
++ 0, val);
+
+ if (rc)
+ dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc);
+@@ -827,7 +827,7 @@ static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
+ struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
+ struct hl_device *hdev = entry->hdev;
+ char tmp_buf[32];
+- u32 val;
++ long val;
+ ssize_t rc;
+
+ if (*ppos)
+@@ -842,7 +842,7 @@ static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
+ return rc;
+ }
+
+- sprintf(tmp_buf, "0x%02x\n", val);
++ sprintf(tmp_buf, "0x%02lx\n", val);
+ rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
+ strlen(tmp_buf));
+
+--
+2.25.1
+
--- /dev/null
+From 4d7b4d288cade7c7f58f13346cbfd4d2aaa0d9f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Aug 2020 12:20:14 -0400
+Subject: hwmon: (nct7904) Correct divide by 0
+
+From: Jason Baron <jbaron@akamai.com>
+
+[ Upstream commit 8aebbbb2d573d0b4afc08b90ac7d73dba2d9da97 ]
+
+We hit a kernel panic due to a divide by 0 in nct7904_read_fan() for
+the hwmon_fan_min case. Extend the check to hwmon_fan_input case as well
+for safety.
+
+[ 1656.545650] divide error: 0000 [#1] SMP PTI
+[ 1656.545779] CPU: 12 PID: 18010 Comm: sensors Not tainted 5.4.47 #1
+[ 1656.546065] RIP: 0010:nct7904_read+0x1e9/0x510 [nct7904]
+...
+[ 1656.546549] RAX: 0000000000149970 RBX: ffffbd6b86bcbe08 RCX: 0000000000000000
+...
+[ 1656.547548] Call Trace:
+[ 1656.547665] hwmon_attr_show+0x32/0xd0 [hwmon]
+[ 1656.547783] dev_attr_show+0x18/0x50
+[ 1656.547898] sysfs_kf_seq_show+0x99/0x120
+[ 1656.548013] seq_read+0xd8/0x3e0
+[ 1656.548127] vfs_read+0x89/0x130
+[ 1656.548234] ksys_read+0x7d/0xb0
+[ 1656.548342] do_syscall_64+0x48/0x110
+[ 1656.548451] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Fixes: d65a5102a99f5 ("hwmon: (nct7904) Convert to use new hwmon registration API")
+Signed-off-by: Jason Baron <jbaron@akamai.com>
+Link: https://lore.kernel.org/r/1598026814-2604-1-git-send-email-jbaron@akamai.com
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/nct7904.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/hwmon/nct7904.c b/drivers/hwmon/nct7904.c
+index b0425694f7022..242ff8bee78dd 100644
+--- a/drivers/hwmon/nct7904.c
++++ b/drivers/hwmon/nct7904.c
+@@ -231,7 +231,7 @@ static int nct7904_read_fan(struct device *dev, u32 attr, int channel,
+ if (ret < 0)
+ return ret;
+ cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
+- if (cnt == 0x1fff)
++ if (cnt == 0 || cnt == 0x1fff)
+ rpm = 0;
+ else
+ rpm = 1350000 / cnt;
+@@ -243,7 +243,7 @@ static int nct7904_read_fan(struct device *dev, u32 attr, int channel,
+ if (ret < 0)
+ return ret;
+ cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
+- if (cnt == 0x1fff)
++ if (cnt == 0 || cnt == 0x1fff)
+ rpm = 0;
+ else
+ rpm = 1350000 / cnt;
+--
+2.25.1
+
--- /dev/null
+From b92603b86c4e3ed68a699dc13e6d4de6ff5728c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Aug 2020 20:03:33 +0300
+Subject: i2c: core: Don't fail PRP0001 enumeration when no ID table exist
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit e3cb82c6d6f6c27ab754e13ae29bdd6b949982e2 ]
+
+When commit c64ffff7a9d1 ("i2c: core: Allow empty id_table in ACPI case
+as well") fixed the enumeration of I²C devices on ACPI enabled platforms
+when driver has no ID table, it missed the PRP0001 support.
+
+i2c_device_match() and i2c_acpi_match_device() differently match
+driver against given device. Use acpi_driver_match_device(), that is used
+in the former, in i2c_device_probe() and don't fail PRP0001 enumeration
+when no ID table exist.
+
+Fixes: c64ffff7a9d1 ("i2c: core: Allow empty id_table in ACPI case as well")
+BugLink: https://stackoverflow.com/q/63519678/2511795
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/i2c-core-base.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
+index 26f03a14a4781..4f09d4c318287 100644
+--- a/drivers/i2c/i2c-core-base.c
++++ b/drivers/i2c/i2c-core-base.c
+@@ -354,7 +354,7 @@ static int i2c_device_probe(struct device *dev)
+ * or ACPI ID table is supplied for the probing device.
+ */
+ if (!driver->id_table &&
+- !i2c_acpi_match_device(dev->driver->acpi_match_table, client) &&
++ !acpi_driver_match_device(dev, dev->driver) &&
+ !i2c_of_match_device(dev->driver->of_match_table, client)) {
+ status = -ENODEV;
+ goto put_sync_adapter;
+--
+2.25.1
+
--- /dev/null
+From 0ca52cf2847e44fb9dcafec224a178cb0e0bcd03 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Aug 2020 14:19:30 +0200
+Subject: i2c: rcar: in slave mode, clear NACK earlier
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+[ Upstream commit 914a7b3563b8fb92f976619bbd0fa3a4a708baae ]
+
+Currently, a NACK in slave mode is set/cleared when SCL is held low by
+the IP core right before the bit is about to be pushed out. This is too
+late for clearing and then a NACK from the previous byte is still used
+for the current one. Now, let's clear the NACK right after we detected
+the STOP condition following the NACK.
+
+Fixes: de20d1857dd6 ("i2c: rcar: add slave support")
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-rcar.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c
+index 9e883474db8ce..c7c543483b08c 100644
+--- a/drivers/i2c/busses/i2c-rcar.c
++++ b/drivers/i2c/busses/i2c-rcar.c
+@@ -590,6 +590,7 @@ static bool rcar_i2c_slave_irq(struct rcar_i2c_priv *priv)
+ /* master sent stop */
+ if (ssr_filtered & SSR) {
+ i2c_slave_event(priv->slave, I2C_SLAVE_STOP, &value);
++ rcar_i2c_write(priv, ICSCR, SIE | SDBS); /* clear our NACK */
+ rcar_i2c_write(priv, ICSIER, SAR);
+ rcar_i2c_write(priv, ICSSR, ~SSR & 0xff);
+ }
+--
+2.25.1
+
--- /dev/null
+From b4b0cb6240a6e1973db3f3205f81c33d3277cad8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 20 Jun 2020 10:54:26 +0800
+Subject: jbd2: abort journal if free a async write error metadata buffer
+
+From: zhangyi (F) <yi.zhang@huawei.com>
+
+[ Upstream commit c044f3d8360d2ecf831ba2cc9f08cf9fb2c699fb ]
+
+If we free a metadata buffer which has been failed to async write out
+in the background, the jbd2 checkpoint procedure will not detect this
+failure in jbd2_log_do_checkpoint(), so it may lead to filesystem
+inconsistency after cleanup journal tail. This patch abort the journal
+if free a buffer has write_io_error flag to prevent potential further
+inconsistency.
+
+Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
+Link: https://lore.kernel.org/r/20200620025427.1756360-5-yi.zhang@huawei.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index e65e0aca28261..6250c9faa4cbe 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -2120,6 +2120,7 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal,
+ {
+ struct buffer_head *head;
+ struct buffer_head *bh;
++ bool has_write_io_error = false;
+ int ret = 0;
+
+ J_ASSERT(PageLocked(page));
+@@ -2144,11 +2145,26 @@ int jbd2_journal_try_to_free_buffers(journal_t *journal,
+ jbd2_journal_put_journal_head(jh);
+ if (buffer_jbd(bh))
+ goto busy;
++
++ /*
++ * If we free a metadata buffer which has been failed to
++ * write out, the jbd2 checkpoint procedure will not detect
++ * this failure and may lead to filesystem inconsistency
++ * after cleanup journal tail.
++ */
++ if (buffer_write_io_error(bh)) {
++ pr_err("JBD2: Error while async write back metadata bh %llu.",
++ (unsigned long long)bh->b_blocknr);
++ has_write_io_error = true;
++ }
+ } while ((bh = bh->b_this_page) != head);
+
+ ret = try_to_free_buffers(page);
+
+ busy:
++ if (has_write_io_error)
++ jbd2_journal_abort(journal, -EIO);
++
+ return ret;
+ }
+
+--
+2.25.1
+
--- /dev/null
+From 978725ff0ee3754485d589001655ea2812657d9a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jun 2020 11:25:49 +0200
+Subject: jbd2: make sure jh have b_transaction set in refile/unfile_buffer
+
+From: Lukas Czerner <lczerner@redhat.com>
+
+[ Upstream commit 24dc9864914eb5813173cfa53313fcd02e4aea7d ]
+
+Callers of __jbd2_journal_unfile_buffer() and
+__jbd2_journal_refile_buffer() assume that the b_transaction is set. In
+fact if it's not, we can end up with journal_head refcounting errors
+leading to crash much later that might be very hard to track down. Add
+asserts to make sure that is the case.
+
+We also make sure that b_next_transaction is NULL in
+__jbd2_journal_unfile_buffer() since the callers expect that as well and
+we should not get into that stage in this state anyway, leading to
+problems later on if we do.
+
+Tested with fstests.
+
+Signed-off-by: Lukas Czerner <lczerner@redhat.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Link: https://lore.kernel.org/r/20200617092549.6712-1-lczerner@redhat.com
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/jbd2/transaction.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index e91aad3637a23..e65e0aca28261 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -2026,6 +2026,9 @@ static void __jbd2_journal_temp_unlink_buffer(struct journal_head *jh)
+ */
+ static void __jbd2_journal_unfile_buffer(struct journal_head *jh)
+ {
++ J_ASSERT_JH(jh, jh->b_transaction != NULL);
++ J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
++
+ __jbd2_journal_temp_unlink_buffer(jh);
+ jh->b_transaction = NULL;
+ }
+@@ -2572,6 +2575,13 @@ bool __jbd2_journal_refile_buffer(struct journal_head *jh)
+
+ was_dirty = test_clear_buffer_jbddirty(bh);
+ __jbd2_journal_temp_unlink_buffer(jh);
++
++ /*
++ * b_transaction must be set, otherwise the new b_transaction won't
++ * be holding jh reference
++ */
++ J_ASSERT_JH(jh, jh->b_transaction != NULL);
++
+ /*
+ * We set b_transaction here because b_next_transaction will inherit
+ * our jh reference and thus __jbd2_journal_file_buffer() must not
+--
+2.25.1
+
--- /dev/null
+From db9940e83d34f1d40f255b1c6197719862aac7b1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Aug 2020 13:05:34 +0200
+Subject: libbpf: Fix map index used in error message
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit 1e891e513e16c145cc9b45b1fdb8bf4a4f2f9557 ]
+
+The error message emitted by bpf_object__init_user_btf_maps() was using the
+wrong section ID.
+
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Yonghong Song <yhs@fb.com>
+Link: https://lore.kernel.org/bpf/20200819110534.9058-1-toke@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index e0b88f0013b74..3ac0094706b81 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -2237,7 +2237,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict,
+ data = elf_getdata(scn, NULL);
+ if (!scn || !data) {
+ pr_warn("failed to get Elf_Data from map section %d (%s)\n",
+- obj->efile.maps_shndx, MAPS_ELF_SEC);
++ obj->efile.btf_maps_shndx, MAPS_ELF_SEC);
+ return -EINVAL;
+ }
+
+--
+2.25.1
+
--- /dev/null
+From 168c6f37311efaf29d9a789ce4e8249a362a1bd6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Aug 2020 16:39:10 +0200
+Subject: libbpf: Handle GCC built-in types for Arm NEON
+
+From: Jean-Philippe Brucker <jean-philippe@linaro.org>
+
+[ Upstream commit 702eddc77a905782083b14ccd05b23840675fd18 ]
+
+When building Arm NEON (SIMD) code from lib/raid6/neon.uc, GCC emits
+DWARF information using a base type "__Poly8_t", which is internal to
+GCC and not recognized by Clang. This causes build failures when
+building with Clang a vmlinux.h generated from an arm64 kernel that was
+built with GCC.
+
+ vmlinux.h:47284:9: error: unknown type name '__Poly8_t'
+ typedef __Poly8_t poly8x16_t[16];
+ ^~~~~~~~~
+
+The polyX_t types are defined as unsigned integers in the "Arm C
+Language Extension" document (101028_Q220_00_en). Emit typedefs based on
+standard integer types for the GCC internal types, similar to those
+emitted by Clang.
+
+Including linux/kernel.h to use ARRAY_SIZE() incidentally redefined
+max(), causing a build bug due to different types, hence the seemingly
+unrelated change.
+
+Reported-by: Jakov Petrina <jakov.petrina@sartura.hr>
+Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Andrii Nakryiko <andriin@fb.com>
+Link: https://lore.kernel.org/bpf/20200812143909.3293280-1-jean-philippe@linaro.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/btf_dump.c | 35 ++++++++++++++++++++++++++++++++++-
+ 1 file changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c
+index bbb4303172606..4edf76c5a7101 100644
+--- a/tools/lib/bpf/btf_dump.c
++++ b/tools/lib/bpf/btf_dump.c
+@@ -13,6 +13,7 @@
+ #include <errno.h>
+ #include <linux/err.h>
+ #include <linux/btf.h>
++#include <linux/kernel.h>
+ #include "btf.h"
+ #include "hashmap.h"
+ #include "libbpf.h"
+@@ -548,6 +549,9 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
+ }
+ }
+
++static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
++ const struct btf_type *t);
++
+ static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
+ const struct btf_type *t);
+ static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id,
+@@ -670,6 +674,9 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
+
+ switch (kind) {
+ case BTF_KIND_INT:
++ /* Emit type alias definitions if necessary */
++ btf_dump_emit_missing_aliases(d, id, t);
++
+ tstate->emit_state = EMITTED;
+ break;
+ case BTF_KIND_ENUM:
+@@ -869,7 +876,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
+ btf_dump_printf(d, ": %d", m_sz);
+ off = m_off + m_sz;
+ } else {
+- m_sz = max(0, btf__resolve_size(d->btf, m->type));
++ m_sz = max(0LL, btf__resolve_size(d->btf, m->type));
+ off = m_off + m_sz * 8;
+ }
+ btf_dump_printf(d, ";");
+@@ -889,6 +896,32 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
+ btf_dump_printf(d, " __attribute__((packed))");
+ }
+
++static const char *missing_base_types[][2] = {
++ /*
++ * GCC emits typedefs to its internal __PolyX_t types when compiling Arm
++ * SIMD intrinsics. Alias them to standard base types.
++ */
++ { "__Poly8_t", "unsigned char" },
++ { "__Poly16_t", "unsigned short" },
++ { "__Poly64_t", "unsigned long long" },
++ { "__Poly128_t", "unsigned __int128" },
++};
++
++static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
++ const struct btf_type *t)
++{
++ const char *name = btf_dump_type_name(d, id);
++ int i;
++
++ for (i = 0; i < ARRAY_SIZE(missing_base_types); i++) {
++ if (strcmp(name, missing_base_types[i][0]) == 0) {
++ btf_dump_printf(d, "typedef %s %s;\n\n",
++ missing_base_types[i][1], name);
++ break;
++ }
++ }
++}
++
+ static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
+ const struct btf_type *t)
+ {
+--
+2.25.1
+
--- /dev/null
+From 391a03461ada510c5c97b01a50027da1c54b4d01 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 16:29:05 +0200
+Subject: libbpf: Prevent overriding errno when logging errors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit 23ab656be263813acc3c20623757d3cd1496d9e1 ]
+
+Turns out there were a few more instances where libbpf didn't save the
+errno before writing an error message, causing errno to be overridden by
+the printf() return and the error disappearing if logging is enabled.
+
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Andrii Nakryiko <andriin@fb.com>
+Link: https://lore.kernel.org/bpf/20200813142905.160381-1-toke@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/bpf/libbpf.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
+index e7642a6e39f9e..e0b88f0013b74 100644
+--- a/tools/lib/bpf/libbpf.c
++++ b/tools/lib/bpf/libbpf.c
+@@ -3319,10 +3319,11 @@ bpf_object__probe_global_data(struct bpf_object *obj)
+
+ map = bpf_create_map_xattr(&map_attr);
+ if (map < 0) {
+- cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
++ ret = -errno;
++ cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg));
+ pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n",
+- __func__, cp, errno);
+- return -errno;
++ __func__, cp, -ret);
++ return ret;
+ }
+
+ insns[0].imm = map;
+@@ -5779,9 +5780,10 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
+ }
+
+ if (bpf_obj_pin(prog->instances.fds[instance], path)) {
+- cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
++ err = -errno;
++ cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));
+ pr_warn("failed to pin program: %s\n", cp);
+- return -errno;
++ return err;
+ }
+ pr_debug("pinned program '%s'\n", path);
+
+--
+2.25.1
+
--- /dev/null
+From d0558f7c8b64a8df5975dda46189a9041d0c4d65 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Aug 2020 10:51:34 +0200
+Subject: macvlan: validate setting of multiple remote source MAC addresses
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alvin Šipraga <alsi@bang-olufsen.dk>
+
+[ Upstream commit 8b61fba503904acae24aeb2bd5569b4d6544d48f ]
+
+Remote source MAC addresses can be set on a 'source mode' macvlan
+interface via the IFLA_MACVLAN_MACADDR_DATA attribute. This commit
+tightens the validation of these MAC addresses to match the validation
+already performed when setting or adding a single MAC address via the
+IFLA_MACVLAN_MACADDR attribute.
+
+iproute2 uses IFLA_MACVLAN_MACADDR_DATA for its 'macvlan macaddr set'
+command, and IFLA_MACVLAN_MACADDR for its 'macvlan macaddr add' command,
+which demonstrates the inconsistent behaviour that this commit
+addresses:
+
+ # ip link add link eth0 name macvlan0 type macvlan mode source
+ # ip link set link dev macvlan0 type macvlan macaddr add 01:00:00:00:00:00
+ RTNETLINK answers: Cannot assign requested address
+ # ip link set link dev macvlan0 type macvlan macaddr set 01:00:00:00:00:00
+ # ip -d link show macvlan0
+ 5: macvlan0@eth0: <BROADCAST,MULTICAST,DYNAMIC,UP,LOWER_UP> mtu 1500 ...
+ link/ether 2e:ac:fd:2d:69:f8 brd ff:ff:ff:ff:ff:ff promiscuity 0
+ macvlan mode source remotes (1) 01:00:00:00:00:00 numtxqueues 1 ...
+
+With this change, the 'set' command will (rightly) fail in the same way
+as the 'add' command.
+
+Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/macvlan.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
+index 4942f6112e51f..5da04e9979894 100644
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1269,6 +1269,9 @@ static void macvlan_port_destroy(struct net_device *dev)
+ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
+ struct netlink_ext_ack *extack)
+ {
++ struct nlattr *nla, *head;
++ int rem, len;
++
+ if (tb[IFLA_ADDRESS]) {
+ if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
+ return -EINVAL;
+@@ -1316,6 +1319,20 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
+ return -EADDRNOTAVAIL;
+ }
+
++ if (data[IFLA_MACVLAN_MACADDR_DATA]) {
++ head = nla_data(data[IFLA_MACVLAN_MACADDR_DATA]);
++ len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
++
++ nla_for_each_attr(nla, head, len, rem) {
++ if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
++ nla_len(nla) != ETH_ALEN)
++ return -EINVAL;
++
++ if (!is_valid_ether_addr(nla_data(nla)))
++ return -EADDRNOTAVAIL;
++ }
++ }
++
+ if (data[IFLA_MACVLAN_MACADDR_COUNT])
+ return -EINVAL;
+
+@@ -1372,10 +1389,6 @@ static int macvlan_changelink_sources(struct macvlan_dev *vlan, u32 mode,
+ len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
+
+ nla_for_each_attr(nla, head, len, rem) {
+- if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
+- nla_len(nla) != ETH_ALEN)
+- continue;
+-
+ addr = nla_data(nla);
+ ret = macvlan_hash_add_source(vlan, addr);
+ if (ret)
+--
+2.25.1
+
--- /dev/null
+From c342ceb0fb775302026fe876afafc7c7cbc8e2a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 19 Aug 2020 00:22:41 +0530
+Subject: net: gianfar: Add of_node_put() before goto statement
+
+From: Sumera Priyadarsini <sylphrenadin@gmail.com>
+
+[ Upstream commit 989e4da042ca4a56bbaca9223d1a93639ad11e17 ]
+
+Every iteration of for_each_available_child_of_node() decrements
+reference count of the previous node, however when control
+is transferred from the middle of the loop, as in the case of
+a return or break or goto, there is no decrement thus ultimately
+resulting in a memory leak.
+
+Fix a potential memory leak in gianfar.c by inserting of_node_put()
+before the goto statement.
+
+Issue found with Coccinelle.
+
+Signed-off-by: Sumera Priyadarsini <sylphrenadin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/freescale/gianfar.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
+index b513b8c5c3b5e..41dd3d0f34524 100644
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -750,8 +750,10 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+ continue;
+
+ err = gfar_parse_group(child, priv, model);
+- if (err)
++ if (err) {
++ of_node_put(child);
+ goto err_grp_init;
++ }
+ }
+ } else { /* SQ_SG_MODE */
+ err = gfar_parse_group(np, priv, model);
+--
+2.25.1
+
--- /dev/null
+From 4cdee1d8276a5f236079fd1a550112fae242ad59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Aug 2020 13:52:15 +0200
+Subject: netfilter: avoid ipv6 -> nf_defrag_ipv6 module dependency
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 2404b73c3f1a5f15726c6ecd226b56f6f992767f ]
+
+nf_ct_frag6_gather is part of nf_defrag_ipv6.ko, not ipv6 core.
+
+The current use of the netfilter ipv6 stub indirections causes a module
+dependency between ipv6 and nf_defrag_ipv6.
+
+This prevents nf_defrag_ipv6 module from being removed because ipv6 can't
+be unloaded.
+
+Remove the indirection and always use a direct call. This creates a
+depency from nf_conntrack_bridge to nf_defrag_ipv6 instead:
+
+modinfo nf_conntrack
+depends: nf_conntrack,nf_defrag_ipv6,bridge
+
+.. and nf_conntrack already depends on nf_defrag_ipv6 anyway.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netfilter_ipv6.h | 18 ------------------
+ net/bridge/netfilter/nf_conntrack_bridge.c | 8 ++++++--
+ net/ipv6/netfilter.c | 3 ---
+ 3 files changed, 6 insertions(+), 23 deletions(-)
+
+diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
+index aac42c28fe62d..9b67394471e1c 100644
+--- a/include/linux/netfilter_ipv6.h
++++ b/include/linux/netfilter_ipv6.h
+@@ -58,7 +58,6 @@ struct nf_ipv6_ops {
+ int (*output)(struct net *, struct sock *, struct sk_buff *));
+ int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry);
+ #if IS_MODULE(CONFIG_IPV6)
+- int (*br_defrag)(struct net *net, struct sk_buff *skb, u32 user);
+ int (*br_fragment)(struct net *net, struct sock *sk,
+ struct sk_buff *skb,
+ struct nf_bridge_frag_data *data,
+@@ -117,23 +116,6 @@ static inline int nf_ip6_route(struct net *net, struct dst_entry **dst,
+
+ #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
+
+-static inline int nf_ipv6_br_defrag(struct net *net, struct sk_buff *skb,
+- u32 user)
+-{
+-#if IS_MODULE(CONFIG_IPV6)
+- const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
+-
+- if (!v6_ops)
+- return 1;
+-
+- return v6_ops->br_defrag(net, skb, user);
+-#elif IS_BUILTIN(CONFIG_IPV6)
+- return nf_ct_frag6_gather(net, skb, user);
+-#else
+- return 1;
+-#endif
+-}
+-
+ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+ struct nf_bridge_frag_data *data,
+ int (*output)(struct net *, struct sock *sk,
+diff --git a/net/bridge/netfilter/nf_conntrack_bridge.c b/net/bridge/netfilter/nf_conntrack_bridge.c
+index 8096732223828..8d033a75a766e 100644
+--- a/net/bridge/netfilter/nf_conntrack_bridge.c
++++ b/net/bridge/netfilter/nf_conntrack_bridge.c
+@@ -168,6 +168,7 @@ static unsigned int nf_ct_br_defrag4(struct sk_buff *skb,
+ static unsigned int nf_ct_br_defrag6(struct sk_buff *skb,
+ const struct nf_hook_state *state)
+ {
++#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
+ u16 zone_id = NF_CT_DEFAULT_ZONE_ID;
+ enum ip_conntrack_info ctinfo;
+ struct br_input_skb_cb cb;
+@@ -180,14 +181,17 @@ static unsigned int nf_ct_br_defrag6(struct sk_buff *skb,
+
+ br_skb_cb_save(skb, &cb, sizeof(struct inet6_skb_parm));
+
+- err = nf_ipv6_br_defrag(state->net, skb,
+- IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone_id);
++ err = nf_ct_frag6_gather(state->net, skb,
++ IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone_id);
+ /* queued */
+ if (err == -EINPROGRESS)
+ return NF_STOLEN;
+
+ br_skb_cb_restore(skb, &cb, IP6CB(skb)->frag_max_size);
+ return err == 0 ? NF_ACCEPT : NF_DROP;
++#else
++ return NF_ACCEPT;
++#endif
+ }
+
+ static int nf_ct_br_ip_check(const struct sk_buff *skb)
+diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
+index 409e79b84a830..6d0e942d082d4 100644
+--- a/net/ipv6/netfilter.c
++++ b/net/ipv6/netfilter.c
+@@ -245,9 +245,6 @@ static const struct nf_ipv6_ops ipv6ops = {
+ .route_input = ip6_route_input,
+ .fragment = ip6_fragment,
+ .reroute = nf_ip6_reroute,
+-#if IS_MODULE(CONFIG_IPV6) && IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
+- .br_defrag = nf_ct_frag6_gather,
+-#endif
+ #if IS_MODULE(CONFIG_IPV6)
+ .br_fragment = br_ip6_fragment,
+ #endif
+--
+2.25.1
+
--- /dev/null
+From 682c09b640b921bdb379b74bdf2df042771de11d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Aug 2020 15:10:11 -0400
+Subject: nfsd: fix oops on mixed NFSv4/NFSv3 client access
+
+From: J. Bruce Fields <bfields@redhat.com>
+
+[ Upstream commit 34b09af4f54e6485e28f138ccad159611a240cc1 ]
+
+If an NFSv2/v3 client breaks an NFSv4 client's delegation, it will hit a
+NULL dereference in nfsd_breaker_owns_lease().
+
+Easily reproduceable with for example
+
+ mount -overs=4.2 server:/export /mnt/
+ sleep 1h </mnt/file &
+ mount -overs=3 server:/export /mnt2/
+ touch /mnt2/file
+
+Reported-by: Robert Dinse <nanook@eskimo.com>
+Fixes: 28df3d1539de50 ("nfsd: clients don't need to break their own delegations")
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=208807
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/nfsd/nfs4state.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index c9056316a0b35..cea682ce8aa12 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -4597,6 +4597,8 @@ static bool nfsd_breaker_owns_lease(struct file_lock *fl)
+ if (!i_am_nfsd())
+ return NULL;
+ rqst = kthread_data(current);
++ if (!rqst->rq_lease_breaker)
++ return NULL;
+ clp = *(rqst->rq_lease_breaker);
+ return dl->dl_stid.sc_client == clp;
+ }
+--
+2.25.1
+
--- /dev/null
+From ffbd18080f2dfc75585e8804be4b98b01f9ef90c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Aug 2020 04:34:42 -0400
+Subject: null_blk: fix passing of REQ_FUA flag in null_handle_rq
+
+From: Hou Pu <houpu@bytedance.com>
+
+[ Upstream commit 2d62e6b038e729c3e4bfbfcfbd44800ef0883680 ]
+
+REQ_FUA should be checked using rq->cmd_flags instead of req_op().
+
+Fixes: deb78b419dfda ("nullb: emulate cache")
+Signed-off-by: Hou Pu <houpu@bytedance.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/null_blk_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/block/null_blk_main.c b/drivers/block/null_blk_main.c
+index 87b31f9ca362e..8cf13ea11cd2c 100644
+--- a/drivers/block/null_blk_main.c
++++ b/drivers/block/null_blk_main.c
+@@ -1139,7 +1139,7 @@ static int null_handle_rq(struct nullb_cmd *cmd)
+ len = bvec.bv_len;
+ err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset,
+ op_is_write(req_op(rq)), sector,
+- req_op(rq) & REQ_FUA);
++ rq->cmd_flags & REQ_FUA);
+ if (err) {
+ spin_unlock_irq(&nullb->lock);
+ return err;
+--
+2.25.1
+
--- /dev/null
+From 27e10bb8ef20d84f1e4c917050998b84b0813e49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 2 Aug 2020 19:15:45 +0800
+Subject: nvme-fc: Fix wrong return value in __nvme_fc_init_request()
+
+From: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+
+[ Upstream commit f34448cd0dc697723fb5f4118f8431d9233b370d ]
+
+On an error exit path, a negative error code should be returned
+instead of a positive return value.
+
+Fixes: e399441de9115 ("nvme-fabrics: Add host support for FC transport")
+Cc: James Smart <jsmart2021@gmail.com>
+Signed-off-by: Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/fc.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
+index 549f5b0fb0b4b..1a2b6910509ca 100644
+--- a/drivers/nvme/host/fc.c
++++ b/drivers/nvme/host/fc.c
+@@ -2076,7 +2076,7 @@ __nvme_fc_init_request(struct nvme_fc_ctrl *ctrl,
+ if (fc_dma_mapping_error(ctrl->lport->dev, op->fcp_req.cmddma)) {
+ dev_err(ctrl->dev,
+ "FCP Op failed - cmdiu dma mapping failed.\n");
+- ret = EFAULT;
++ ret = -EFAULT;
+ goto out_on_error;
+ }
+
+@@ -2086,7 +2086,7 @@ __nvme_fc_init_request(struct nvme_fc_ctrl *ctrl,
+ if (fc_dma_mapping_error(ctrl->lport->dev, op->fcp_req.rspdma)) {
+ dev_err(ctrl->dev,
+ "FCP Op failed - rspiu dma mapping failed.\n");
+- ret = EFAULT;
++ ret = -EFAULT;
+ }
+
+ atomic_set(&op->state, FCPOP_STATE_IDLE);
+--
+2.25.1
+
--- /dev/null
+From 40b5cda3f18ad2cffc3efcf3ae5169e7869813df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 15:19:31 +0200
+Subject: nvme: multipath: round-robin: fix single non-optimized path case
+
+From: Martin Wilck <mwilck@suse.com>
+
+[ Upstream commit 93eb0381e13d249a18ed4aae203291ff977e7ffb ]
+
+If there's only one usable, non-optimized path, nvme_round_robin_path()
+returns NULL, which is wrong. Fix it by falling back to "old", like in
+the single optimized path case. Also, if the active path isn't changed,
+there's no need to re-assign the pointer.
+
+Fixes: 3f6e3246db0e ("nvme-multipath: fix logic for non-optimized paths")
+Signed-off-by: Martin Wilck <mwilck@suse.com>
+Signed-off-by: Martin George <marting@netapp.com>
+Reviewed-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/multipath.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c
+index 2672953233434..041a755f936a6 100644
+--- a/drivers/nvme/host/multipath.c
++++ b/drivers/nvme/host/multipath.c
+@@ -255,12 +255,17 @@ static struct nvme_ns *nvme_round_robin_path(struct nvme_ns_head *head,
+ fallback = ns;
+ }
+
+- /* No optimized path found, re-check the current path */
++ /*
++ * The loop above skips the current path for round-robin semantics.
++ * Fall back to the current path if either:
++ * - no other optimized path found and current is optimized,
++ * - no other usable path found and current is usable.
++ */
+ if (!nvme_path_is_disabled(old) &&
+- old->ana_state == NVME_ANA_OPTIMIZED) {
+- found = old;
+- goto out;
+- }
++ (old->ana_state == NVME_ANA_OPTIMIZED ||
++ (!fallback && old->ana_state == NVME_ANA_NONOPTIMIZED)))
++ return old;
++
+ if (!fallback)
+ return NULL;
+ found = fallback;
+--
+2.25.1
+
--- /dev/null
+From 65c3b90a82c18b91e7a6bc1e510f67efe114d368 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Jul 2020 11:51:00 -0700
+Subject: nvmet: fix a memory leak
+
+From: Sagi Grimberg <sagi@grimberg.me>
+
+[ Upstream commit 382fee1a8b623e2546a3e15e80517389e0e0673e ]
+
+We forgot to free new_model_number
+
+Fixes: 013b7ebe5a0d ("nvmet: make ctrl model configurable")
+Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/configfs.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index 419e0d4ce79b1..d84b935704a3d 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -1035,6 +1035,7 @@ static ssize_t nvmet_subsys_attr_model_store(struct config_item *item,
+ up_write(&nvmet_config_sem);
+
+ kfree_rcu(new_model, rcuhead);
++ kfree(new_model_number);
+
+ return count;
+ }
+--
+2.25.1
+
--- /dev/null
+From de6b93a85a90bc005b3f8d87373ed824f72f16e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 08:46:32 -0400
+Subject: powerpc/perf: Fix soft lockups due to missed interrupt accounting
+
+From: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+
+[ Upstream commit 17899eaf88d689529b866371344c8f269ba79b5f ]
+
+Performance monitor interrupt handler checks if any counter has
+overflown and calls record_and_restart() in core-book3s which invokes
+perf_event_overflow() to record the sample information. Apart from
+creating sample, perf_event_overflow() also does the interrupt and
+period checks via perf_event_account_interrupt().
+
+Currently we record information only if the SIAR (Sampled Instruction
+Address Register) valid bit is set (using siar_valid() check) and
+hence the interrupt check.
+
+But it is possible that we do sampling for some events that are not
+generating valid SIAR, and hence there is no chance to disable the
+event if interrupts are more than max_samples_per_tick. This leads to
+soft lockup.
+
+Fix this by adding perf_event_account_interrupt() in the invalid SIAR
+code path for a sampling event. ie if SIAR is invalid, just do
+interrupt check and don't record the sample information.
+
+Reported-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
+Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Link: https://lore.kernel.org/r/1596717992-7321-1-git-send-email-atrajeev@linux.vnet.ibm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/powerpc/perf/core-book3s.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
+index 01d70280d2872..190bc4f255b42 100644
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -2101,6 +2101,10 @@ static void record_and_restart(struct perf_event *event, unsigned long val,
+
+ if (perf_event_overflow(event, &data, regs))
+ power_pmu_stop(event, 0);
++ } else if (period) {
++ /* Account for interrupt in case of invalid SIAR */
++ if (perf_event_account_interrupt(event))
++ power_pmu_stop(event, 0);
+ }
+ }
+
+--
+2.25.1
+
--- /dev/null
+From 2822126db0b5f2818ce0a3f2a3c1257fe1197e0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 04:10:13 -0700
+Subject: Revert "scsi: qla2xxx: Fix crash on qla2x00_mailbox_command"
+
+From: Saurav Kashyap <skashyap@marvell.com>
+
+[ Upstream commit de7e6194301ad31c4ce95395eb678e51a1b907e5 ]
+
+FCoE adapter initialization failed for ISP8021 with the following patch
+applied. In addition, reproduction of the issue the patch originally tried
+to address has been unsuccessful.
+
+This reverts commit 3cb182b3fa8b7a61f05c671525494697cba39c6a.
+
+Link: https://lore.kernel.org/r/20200806111014.28434-11-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_mbx.c | 8 --------
+ 1 file changed, 8 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
+index df31ee0d59b20..fdb2ce7acb912 100644
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -333,14 +333,6 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
+ if (time_after(jiffies, wait_time))
+ break;
+
+- /*
+- * Check if it's UNLOADING, cause we cannot poll in
+- * this case, or else a NULL pointer dereference
+- * is triggered.
+- */
+- if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags)))
+- return QLA_FUNCTION_TIMEOUT;
+-
+ /* Check for pending interrupts. */
+ qla2x00_poll(ha->rsp_q_map[0]);
+
+--
+2.25.1
+
--- /dev/null
+From 8de14d5dc5c017c972c0fcd2e20f5c1719eeffa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 18 Jun 2020 16:42:45 +0200
+Subject: s390/cio: add cond_resched() in the slow_eval_known_fn() loop
+
+From: Vineeth Vijayan <vneethv@linux.ibm.com>
+
+[ Upstream commit 0b8eb2ee9da1e8c9b8082f404f3948aa82a057b2 ]
+
+The scanning through subchannels during the time of an event could
+take significant amount of time in case of platforms with lots of
+known subchannels. This might result in higher scheduling latencies
+for other tasks especially on systems with a single CPU. Add
+cond_resched() call, as the loop in slow_eval_known_fn() can be
+executed for a longer duration.
+
+Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
+Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/css.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
+index 94edbb33d0d1f..aca022239b333 100644
+--- a/drivers/s390/cio/css.c
++++ b/drivers/s390/cio/css.c
+@@ -677,6 +677,11 @@ static int slow_eval_known_fn(struct subchannel *sch, void *data)
+ rc = css_evaluate_known_subchannel(sch, 1);
+ if (rc == -EAGAIN)
+ css_schedule_eval(sch->schid);
++ /*
++ * The loop might take long time for platforms with lots of
++ * known devices. Allow scheduling here.
++ */
++ cond_resched();
+ }
+ return 0;
+ }
+--
+2.25.1
+
--- /dev/null
+From 5ae1489a09c62d0b3dde641d9922c2a772046b8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Aug 2020 15:23:33 -0500
+Subject: scsi: fcoe: Fix I/O path allocation
+
+From: Mike Christie <michael.christie@oracle.com>
+
+[ Upstream commit fa39ab5184d64563cd36f2fb5f0d3fbad83a432c ]
+
+ixgbe_fcoe_ddp_setup() can be called from the main I/O path and is called
+with a spin_lock held, so we have to use GFP_ATOMIC allocation instead of
+GFP_KERNEL.
+
+Link: https://lore.kernel.org/r/1596831813-9839-1-git-send-email-michael.christie@oracle.com
+cc: Hannes Reinecke <hare@suse.de>
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Mike Christie <michael.christie@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+index ec7a11d13fdc0..9e70b9a674409 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c
+@@ -192,7 +192,7 @@ static int ixgbe_fcoe_ddp_setup(struct net_device *netdev, u16 xid,
+ }
+
+ /* alloc the udl from per cpu ddp pool */
+- ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_KERNEL, &ddp->udp);
++ ddp->udl = dma_pool_alloc(ddp_pool->pool, GFP_ATOMIC, &ddp->udp);
+ if (!ddp->udl) {
+ e_err(drv, "failed allocated ddp context\n");
+ goto out_noddp_unmap;
+--
+2.25.1
+
--- /dev/null
+From d1fbee591668913c06e27d9298e664f5d2853453 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 04:10:11 -0700
+Subject: scsi: qla2xxx: Check if FW supports MQ before enabling
+
+From: Saurav Kashyap <skashyap@marvell.com>
+
+[ Upstream commit dffa11453313a115157b19021cc2e27ea98e624c ]
+
+OS boot during Boot from SAN was stuck at dracut emergency shell after
+enabling NVMe driver parameter. For non-MQ support the driver was enabling
+MQ. Add a check to confirm if FW supports MQ.
+
+Link: https://lore.kernel.org/r/20200806111014.28434-9-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Saurav Kashyap <skashyap@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_os.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 5c7c22d0fab4b..8b6803f4f2dc1 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -2017,6 +2017,11 @@ skip_pio:
+ /* Determine queue resources */
+ ha->max_req_queues = ha->max_rsp_queues = 1;
+ ha->msix_count = QLA_BASE_VECTORS;
++
++ /* Check if FW supports MQ or not */
++ if (!(ha->fw_attributes & BIT_6))
++ goto mqiobase_exit;
++
+ if (!ql2xmqsupport || !ql2xnvmeenable ||
+ (!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
+ goto mqiobase_exit;
+--
+2.25.1
+
--- /dev/null
+From 5e9dfa03a1e59f0afdb579898a0826b5120272b4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 04:10:07 -0700
+Subject: scsi: qla2xxx: Fix login timeout
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit abb31aeaa9b20680b0620b23fea5475ea4591e31 ]
+
+Multipath errors were seen during failback due to login timeout. The
+remote device sent LOGO, the local host tore down the session and did
+relogin. The RSCN arrived indicates remote device is going through failover
+after which the relogin is in a 20s timeout phase. At this point the
+driver is stuck in the relogin process. Add a fix to delete the session as
+part of abort/flush the login.
+
+Link: https://lore.kernel.org/r/20200806111014.28434-5-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 18 +++++++++++++++---
+ drivers/scsi/qla2xxx/qla_target.c | 2 +-
+ 2 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index 3bfb5678f6515..de9fd7f688d01 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3538,10 +3538,22 @@ login_logout:
+ }
+
+ if (fcport->scan_state != QLA_FCPORT_FOUND) {
++ bool do_delete = false;
++
++ if (fcport->scan_needed &&
++ fcport->disc_state == DSC_LOGIN_PEND) {
++ /* Cable got disconnected after we sent
++ * a login. Do delete to prevent timeout.
++ */
++ fcport->logout_on_delete = 1;
++ do_delete = true;
++ }
++
+ fcport->scan_needed = 0;
+- if ((qla_dual_mode_enabled(vha) ||
+- qla_ini_mode_enabled(vha)) &&
+- atomic_read(&fcport->state) == FCS_ONLINE) {
++ if (((qla_dual_mode_enabled(vha) ||
++ qla_ini_mode_enabled(vha)) &&
++ atomic_read(&fcport->state) == FCS_ONLINE) ||
++ do_delete) {
+ if (fcport->loop_id != FC_NO_LOOP_ID) {
+ if (fcport->flags & FCF_FCP2_DEVICE)
+ fcport->logout_on_delete = 0;
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index fbb80a043b4fe..90289162dbd4c 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -1270,7 +1270,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
+
+ qla24xx_chk_fcp_state(sess);
+
+- ql_dbg(ql_dbg_tgt, sess->vha, 0xe001,
++ ql_dbg(ql_dbg_disc, sess->vha, 0xe001,
+ "Scheduling sess %p for deletion %8phC\n",
+ sess, sess->port_name);
+
+--
+2.25.1
+
--- /dev/null
+From 0e42aacd6d956cf5340b1d7c1c9034b0d451a967 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 04:10:12 -0700
+Subject: scsi: qla2xxx: Fix null pointer access during disconnect from
+ subsystem
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 83949613fac61e8e37eadf8275bf072342302f4e ]
+
+NVMEAsync command is being submitted to QLA while the same NVMe controller
+is in the middle of reset. The reset path has deleted the association and
+freed aen_op->fcp_req.private. Add a check for this private pointer before
+issuing the command.
+
+...
+ 6 [ffffb656ca11fce0] page_fault at ffffffff8c00114e
+ [exception RIP: qla_nvme_post_cmd+394]
+ RIP: ffffffffc0d012ba RSP: ffffb656ca11fd98 RFLAGS: 00010206
+ RAX: ffff8fb039eda228 RBX: ffff8fb039eda200 RCX: 00000000000da161
+ RDX: ffffffffc0d4d0f0 RSI: ffffffffc0d26c9b RDI: ffff8fb039eda220
+ RBP: 0000000000000013 R8: ffff8fb47ff6aa80 R9: 0000000000000002
+ R10: 0000000000000000 R11: ffffb656ca11fdc8 R12: ffff8fb27d04a3b0
+ R13: ffff8fc46dd98a58 R14: 0000000000000000 R15: ffff8fc4540f0000
+ ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018
+ 7 [ffffb656ca11fe08] nvme_fc_start_fcp_op at ffffffffc0241568 [nvme_fc]
+ 8 [ffffb656ca11fe50] nvme_fc_submit_async_event at ffffffffc0241901 [nvme_fc]
+ 9 [ffffb656ca11fe68] nvme_async_event_work at ffffffffc014543d [nvme_core]
+10 [ffffb656ca11fe98] process_one_work at ffffffff8b6cd437
+11 [ffffb656ca11fed8] worker_thread at ffffffff8b6cdcef
+12 [ffffb656ca11ff10] kthread at ffffffff8b6d3402
+13 [ffffb656ca11ff50] ret_from_fork at ffffffff8c000255
+
+--
+PID: 37824 TASK: ffff8fb033063d80 CPU: 20 COMMAND: "kworker/u97:451"
+ 0 [ffffb656ce1abc28] __schedule at ffffffff8be629e3
+ 1 [ffffb656ce1abcc8] schedule at ffffffff8be62fe8
+ 2 [ffffb656ce1abcd0] schedule_timeout at ffffffff8be671ed
+ 3 [ffffb656ce1abd70] wait_for_completion at ffffffff8be639cf
+ 4 [ffffb656ce1abdd0] flush_work at ffffffff8b6ce2d5
+ 5 [ffffb656ce1abe70] nvme_stop_ctrl at ffffffffc0144900 [nvme_core]
+ 6 [ffffb656ce1abe80] nvme_fc_reset_ctrl_work at ffffffffc0243445 [nvme_fc]
+ 7 [ffffb656ce1abe98] process_one_work at ffffffff8b6cd437
+ 8 [ffffb656ce1abed8] worker_thread at ffffffff8b6cdb50
+ 9 [ffffb656ce1abf10] kthread at ffffffff8b6d3402
+10 [ffffb656ce1abf50] ret_from_fork at ffffffff8c000255
+
+Link: https://lore.kernel.org/r/20200806111014.28434-10-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_nvme.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c
+index fa695a4007f86..262dfd7635a48 100644
+--- a/drivers/scsi/qla2xxx/qla_nvme.c
++++ b/drivers/scsi/qla2xxx/qla_nvme.c
+@@ -536,6 +536,11 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
+ struct nvme_private *priv = fd->private;
+ struct qla_nvme_rport *qla_rport = rport->private;
+
++ if (!priv) {
++ /* nvme association has been torn down */
++ return rval;
++ }
++
+ fcport = qla_rport->fcport;
+
+ if (!qpair || !fcport || (qpair && !qpair->fw_started) ||
+--
+2.25.1
+
--- /dev/null
+From a4c3a37b39f2a6e13e17ff53e2ba76d3f2d215ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 04:10:04 -0700
+Subject: scsi: qla2xxx: Flush all sessions on zone disable
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 10ae30ba664822f62de169a61628e31c999c7cc8 ]
+
+On Zone Disable, certain switches would ignore all commands. This causes
+timeout for both switch scan command and abort of that command. On
+detection of this condition, all sessions will be shutdown.
+
+Link: https://lore.kernel.org/r/20200806111014.28434-2-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index df670fba2ab8a..c6b6a3250312e 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3736,6 +3736,18 @@ static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
+ unsigned long flags;
+ const char *name = sp->name;
+
++ if (res == QLA_OS_TIMER_EXPIRED) {
++ /* switch is ignoring all commands.
++ * This might be a zone disable behavior.
++ * This means we hit 64s timeout.
++ * 22s GPNFT + 44s Abort = 64s
++ */
++ ql_dbg(ql_dbg_disc, vha, 0xffff,
++ "%s: Switch Zone check please .\n",
++ name);
++ qla2x00_mark_all_devices_lost(vha);
++ }
++
+ /*
+ * We are in an Interrupt context, queue up this
+ * sp for GNNFT_DONE work. This will allow all
+--
+2.25.1
+
--- /dev/null
+From 9ca89a4114b5b76f920f75fed43b00c830b9dace Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 04:10:05 -0700
+Subject: scsi: qla2xxx: Flush I/O on zone disable
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit a117579d0205b5a0592a3a98493e2b875e4da236 ]
+
+Perform implicit logout to flush I/O on zone disable.
+
+Link: https://lore.kernel.org/r/20200806111014.28434-3-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index c6b6a3250312e..7074073446701 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -3436,7 +3436,6 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp)
+ list_for_each_entry(fcport, &vha->vp_fcports, list) {
+ if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) {
+ fcport->scan_state = QLA_FCPORT_SCAN;
+- fcport->logout_on_delete = 0;
+ }
+ }
+ goto login_logout;
+--
+2.25.1
+
--- /dev/null
+From 933157370fe7246322843b4e4c09e81e03f28a54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 6 Aug 2020 04:10:06 -0700
+Subject: scsi: qla2xxx: Indicate correct supported speeds for Mezz card
+
+From: Quinn Tran <qutran@marvell.com>
+
+[ Upstream commit 4709272f6327cc4a8ee1dc55771bcf9718346980 ]
+
+Correct the supported speeds for 16G Mezz card.
+
+Link: https://lore.kernel.org/r/20200806111014.28434-4-njavali@marvell.com
+Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
+Signed-off-by: Quinn Tran <qutran@marvell.com>
+Signed-off-by: Nilesh Javali <njavali@marvell.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/qla2xxx/qla_gs.c | 17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index 7074073446701..3bfb5678f6515 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -1505,11 +1505,11 @@ qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd,
+ static uint
+ qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha)
+ {
++ uint speeds = 0;
++
+ if (IS_CNA_CAPABLE(ha))
+ return FDMI_PORT_SPEED_10GB;
+ if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) {
+- uint speeds = 0;
+-
+ if (ha->max_supported_speed == 2) {
+ if (ha->min_supported_speed <= 6)
+ speeds |= FDMI_PORT_SPEED_64GB;
+@@ -1536,9 +1536,16 @@ qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha)
+ }
+ return speeds;
+ }
+- if (IS_QLA2031(ha))
+- return FDMI_PORT_SPEED_16GB|FDMI_PORT_SPEED_8GB|
+- FDMI_PORT_SPEED_4GB;
++ if (IS_QLA2031(ha)) {
++ if ((ha->pdev->subsystem_vendor == 0x103C) &&
++ (ha->pdev->subsystem_device == 0x8002)) {
++ speeds = FDMI_PORT_SPEED_16GB;
++ } else {
++ speeds = FDMI_PORT_SPEED_16GB|FDMI_PORT_SPEED_8GB|
++ FDMI_PORT_SPEED_4GB;
++ }
++ return speeds;
++ }
+ if (IS_QLA25XX(ha))
+ return FDMI_PORT_SPEED_8GB|FDMI_PORT_SPEED_4GB|
+ FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB;
+--
+2.25.1
+
--- /dev/null
+From a3d246135f5e8a8f9e82d78a8773689dcceec08d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 11:57:38 -0400
+Subject: scsi: scsi_debug: Fix scp is NULL errors
+
+From: Douglas Gilbert <dgilbert@interlog.com>
+
+[ Upstream commit 223f91b48079227f914657f07d2d686f7b60aa26 ]
+
+John Garry reported 'sdebug_q_cmd_complete: scp is NULL' failures that were
+mainly seen on aarch64 machines (e.g. RPi 4 with four A72 CPUs). The
+problem was tracked down to a missing critical section on a "short circuit"
+path. Namely, the time to process the current command so far has already
+exceeded the requested command duration (i.e. the number of nanoseconds in
+the ndelay parameter).
+
+The random=1 parameter setting was pivotal in finding this error. The
+failure scenario involved first taking that "short circuit" path (due to a
+very short command duration) and then taking the more likely
+hrtimer_start() path (due to a longer command duration). With random=1 each
+command's duration is taken from the uniformly distributed [0..ndelay)
+interval. The fio utility also helped by reliably generating the error
+scenario at about once per minute on a RPi 4 (64 bit OS).
+
+Link: https://lore.kernel.org/r/20200813155738.109298-1-dgilbert@interlog.com
+Reported-by: John Garry <john.garry@huawei.com>
+Reviewed-by: Lee Duncan <lduncan@suse.com>
+Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/scsi_debug.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index b0d93bf79978f..25faad7f8e617 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -5486,9 +5486,11 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
+ u64 d = ktime_get_boottime_ns() - ns_from_boot;
+
+ if (kt <= d) { /* elapsed duration >= kt */
++ spin_lock_irqsave(&sqp->qc_lock, iflags);
+ sqcp->a_cmnd = NULL;
+ atomic_dec(&devip->num_in_q);
+ clear_bit(k, sqp->in_use_bm);
++ spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+ if (new_sd_dp)
+ kfree(sd_dp);
+ /* call scsi_done() from this thread */
+--
+2.25.1
+
--- /dev/null
+From b544efcee4f92baa38016a128d823a077ecc0c1f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Aug 2020 16:18:58 +0200
+Subject: scsi: ufs: Clean up completed request without interrupt notification
+
+From: Stanley Chu <stanley.chu@mediatek.com>
+
+[ Upstream commit b10178ee7fa88b68a9e8adc06534d2605cb0ec23 ]
+
+If somehow no interrupt notification is raised for a completed request and
+its doorbell bit is cleared by host, UFS driver needs to cleanup its
+outstanding bit in ufshcd_abort(). Otherwise, system may behave abnormally
+in the following scenario:
+
+After ufshcd_abort() returns, this request will be requeued by SCSI layer
+with its outstanding bit set. Any future completed request will trigger
+ufshcd_transfer_req_compl() to handle all "completed outstanding bits". At
+this time the "abnormal outstanding bit" will be detected and the "requeued
+request" will be chosen to execute request post-processing flow. This is
+wrong because this request is still "alive".
+
+Link: https://lore.kernel.org/r/20200811141859.27399-2-huobean@gmail.com
+Reviewed-by: Can Guo <cang@codeaurora.org>
+Acked-by: Avri Altman <avri.altman@wdc.com>
+Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
+Signed-off-by: Bean Huo <beanhuo@micron.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index 6af79ff5185f6..8bc8e4e62c045 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -6541,7 +6541,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
+ /* command completed already */
+ dev_err(hba->dev, "%s: cmd at tag %d successfully cleared from DB.\n",
+ __func__, tag);
+- goto out;
++ goto cleanup;
+ } else {
+ dev_err(hba->dev,
+ "%s: no response from device. tag = %d, err %d\n",
+@@ -6575,6 +6575,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
+ goto out;
+ }
+
++cleanup:
+ scsi_dma_unmap(cmd);
+
+ spin_lock_irqsave(host->host_lock, flags);
+--
+2.25.1
+
--- /dev/null
+From 9360d412055c37af05811226117cc0ac9c74680f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 9 Aug 2020 13:07:34 +0800
+Subject: scsi: ufs: Fix possible infinite loop in ufshcd_hold
+
+From: Stanley Chu <stanley.chu@mediatek.com>
+
+[ Upstream commit 93b6c5db06028a3b55122bbb74d0715dd8ca4ae0 ]
+
+In ufshcd_suspend(), after clk-gating is suspended and link is set
+as Hibern8 state, ufshcd_hold() is still possibly invoked before
+ufshcd_suspend() returns. For example, MediaTek's suspend vops may
+issue UIC commands which would call ufshcd_hold() during the command
+issuing flow.
+
+Now if UFSHCD_CAP_HIBERN8_WITH_CLK_GATING capability is enabled,
+then ufshcd_hold() may enter infinite loops because there is no
+clk-ungating work scheduled or pending. In this case, ufshcd_hold()
+shall just bypass, and keep the link as Hibern8 state.
+
+Link: https://lore.kernel.org/r/20200809050734.18740-1-stanley.chu@mediatek.com
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Co-developed-by: Andy Teng <andy.teng@mediatek.com>
+Signed-off-by: Andy Teng <andy.teng@mediatek.com>
+Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index 136b863bc1d45..2b5acdfb17820 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -1566,6 +1566,7 @@ unblock_reqs:
+ int ufshcd_hold(struct ufs_hba *hba, bool async)
+ {
+ int rc = 0;
++ bool flush_result;
+ unsigned long flags;
+
+ if (!ufshcd_is_clkgating_allowed(hba))
+@@ -1597,7 +1598,9 @@ start:
+ break;
+ }
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+- flush_work(&hba->clk_gating.ungate_work);
++ flush_result = flush_work(&hba->clk_gating.ungate_work);
++ if (hba->clk_gating.is_suspended && !flush_result)
++ goto out;
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ goto start;
+ }
+--
+2.25.1
+
--- /dev/null
+From dc6f3bd6f09bc251872646549a01465f9f141ab1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 11 Aug 2020 16:39:36 +0300
+Subject: scsi: ufs: Improve interrupt handling for shared interrupts
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 127d5f7c4b653b8be5eb3b2c7bbe13728f9003ff ]
+
+For shared interrupts, the interrupt status might be zero, so check that
+first.
+
+Link: https://lore.kernel.org/r/20200811133936.19171-2-adrian.hunter@intel.com
+Reviewed-by: Avri Altman <avri.altman@wdc.com>
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/ufs/ufshcd.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
+index 2b5acdfb17820..6af79ff5185f6 100644
+--- a/drivers/scsi/ufs/ufshcd.c
++++ b/drivers/scsi/ufs/ufshcd.c
+@@ -5991,7 +5991,7 @@ static irqreturn_t ufshcd_sl_intr(struct ufs_hba *hba, u32 intr_status)
+ */
+ static irqreturn_t ufshcd_intr(int irq, void *__hba)
+ {
+- u32 intr_status, enabled_intr_status;
++ u32 intr_status, enabled_intr_status = 0;
+ irqreturn_t retval = IRQ_NONE;
+ struct ufs_hba *hba = __hba;
+ int retries = hba->nutrs;
+@@ -6005,7 +6005,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
+ * read, make sure we handle them by checking the interrupt status
+ * again in a loop until we process all of the reqs before returning.
+ */
+- do {
++ while (intr_status && retries--) {
+ enabled_intr_status =
+ intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+ if (intr_status)
+@@ -6014,7 +6014,7 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
+ retval |= ufshcd_sl_intr(hba, enabled_intr_status);
+
+ intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
+- } while (intr_status && --retries);
++ }
+
+ if (enabled_intr_status && retval == IRQ_NONE) {
+ dev_err(hba->dev, "%s: Unhandled interrupt 0x%08x\n",
+--
+2.25.1
+
--- /dev/null
+From 8a8552226413962999b8744d00dfb6095b801505 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 13:49:38 -0700
+Subject: selftest/bpf: Fix compilation warnings in 32-bit mode
+
+From: Andrii Nakryiko <andriin@fb.com>
+
+[ Upstream commit 9028bbcc3e12510cac13a9554f1a1e39667a4387 ]
+
+Fix compilation warnings emitted when compiling selftests for 32-bit platform
+(x86 in my case).
+
+Signed-off-by: Andrii Nakryiko <andriin@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20200813204945.1020225-3-andriin@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c | 8 ++++----
+ tools/testing/selftests/bpf/prog_tests/core_extern.c | 4 ++--
+ tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c | 6 +++---
+ tools/testing/selftests/bpf/prog_tests/flow_dissector.c | 2 +-
+ tools/testing/selftests/bpf/prog_tests/global_data.c | 6 +++---
+ tools/testing/selftests/bpf/prog_tests/prog_run_xattr.c | 2 +-
+ tools/testing/selftests/bpf/prog_tests/skb_ctx.c | 2 +-
+ tools/testing/selftests/bpf/test_btf.c | 8 ++++----
+ tools/testing/selftests/bpf/test_progs.h | 5 +++++
+ 9 files changed, 24 insertions(+), 19 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c
+index 7afa4160416f6..284d5921c3458 100644
+--- a/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c
++++ b/tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c
+@@ -159,15 +159,15 @@ void test_bpf_obj_id(void)
+ /* Check getting link info */
+ info_len = sizeof(struct bpf_link_info) * 2;
+ bzero(&link_infos[i], info_len);
+- link_infos[i].raw_tracepoint.tp_name = (__u64)&tp_name;
++ link_infos[i].raw_tracepoint.tp_name = ptr_to_u64(&tp_name);
+ link_infos[i].raw_tracepoint.tp_name_len = sizeof(tp_name);
+ err = bpf_obj_get_info_by_fd(bpf_link__fd(links[i]),
+ &link_infos[i], &info_len);
+ if (CHECK(err ||
+ link_infos[i].type != BPF_LINK_TYPE_RAW_TRACEPOINT ||
+ link_infos[i].prog_id != prog_infos[i].id ||
+- link_infos[i].raw_tracepoint.tp_name != (__u64)&tp_name ||
+- strcmp((char *)link_infos[i].raw_tracepoint.tp_name,
++ link_infos[i].raw_tracepoint.tp_name != ptr_to_u64(&tp_name) ||
++ strcmp(u64_to_ptr(link_infos[i].raw_tracepoint.tp_name),
+ "sys_enter") ||
+ info_len != sizeof(struct bpf_link_info),
+ "get-link-info(fd)",
+@@ -178,7 +178,7 @@ void test_bpf_obj_id(void)
+ link_infos[i].type, BPF_LINK_TYPE_RAW_TRACEPOINT,
+ link_infos[i].id,
+ link_infos[i].prog_id, prog_infos[i].id,
+- (char *)link_infos[i].raw_tracepoint.tp_name,
++ (const char *)u64_to_ptr(link_infos[i].raw_tracepoint.tp_name),
+ "sys_enter"))
+ goto done;
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/core_extern.c b/tools/testing/selftests/bpf/prog_tests/core_extern.c
+index b093787e94489..1931a158510e0 100644
+--- a/tools/testing/selftests/bpf/prog_tests/core_extern.c
++++ b/tools/testing/selftests/bpf/prog_tests/core_extern.c
+@@ -159,8 +159,8 @@ void test_core_extern(void)
+ exp = (uint64_t *)&t->data;
+ for (j = 0; j < n; j++) {
+ CHECK(got[j] != exp[j], "check_res",
+- "result #%d: expected %lx, but got %lx\n",
+- j, exp[j], got[j]);
++ "result #%d: expected %llx, but got %llx\n",
++ j, (__u64)exp[j], (__u64)got[j]);
+ }
+ cleanup:
+ test_core_extern__destroy(skel);
+diff --git a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
+index a895bfed55db0..197d0d217b56b 100644
+--- a/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
++++ b/tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
+@@ -16,7 +16,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
+ __u32 duration = 0, retval;
+ struct bpf_map *data_map;
+ const int zero = 0;
+- u64 *result = NULL;
++ __u64 *result = NULL;
+
+ err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
+ &pkt_obj, &pkt_fd);
+@@ -29,7 +29,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
+
+ link = calloc(sizeof(struct bpf_link *), prog_cnt);
+ prog = calloc(sizeof(struct bpf_program *), prog_cnt);
+- result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64));
++ result = malloc((prog_cnt + 32 /* spare */) * sizeof(__u64));
+ if (CHECK(!link || !prog || !result, "alloc_memory",
+ "failed to alloc memory"))
+ goto close_prog;
+@@ -72,7 +72,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
+ goto close_prog;
+
+ for (i = 0; i < prog_cnt; i++)
+- if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n",
++ if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %llu\n",
+ result[i]))
+ goto close_prog;
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
+index f11f187990e95..cd6dc80edf18e 100644
+--- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
++++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c
+@@ -591,7 +591,7 @@ void test_flow_dissector(void)
+ CHECK_ATTR(tattr.data_size_out != sizeof(flow_keys) ||
+ err || tattr.retval != 1,
+ tests[i].name,
+- "err %d errno %d retval %d duration %d size %u/%lu\n",
++ "err %d errno %d retval %d duration %d size %u/%zu\n",
+ err, errno, tattr.retval, tattr.duration,
+ tattr.data_size_out, sizeof(flow_keys));
+ CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys);
+diff --git a/tools/testing/selftests/bpf/prog_tests/global_data.c b/tools/testing/selftests/bpf/prog_tests/global_data.c
+index e3cb62b0a110e..9efa7e50eab27 100644
+--- a/tools/testing/selftests/bpf/prog_tests/global_data.c
++++ b/tools/testing/selftests/bpf/prog_tests/global_data.c
+@@ -5,7 +5,7 @@
+ static void test_global_data_number(struct bpf_object *obj, __u32 duration)
+ {
+ int i, err, map_fd;
+- uint64_t num;
++ __u64 num;
+
+ map_fd = bpf_find_map(__func__, obj, "result_number");
+ if (CHECK_FAIL(map_fd < 0))
+@@ -14,7 +14,7 @@ static void test_global_data_number(struct bpf_object *obj, __u32 duration)
+ struct {
+ char *name;
+ uint32_t key;
+- uint64_t num;
++ __u64 num;
+ } tests[] = {
+ { "relocate .bss reference", 0, 0 },
+ { "relocate .data reference", 1, 42 },
+@@ -32,7 +32,7 @@ static void test_global_data_number(struct bpf_object *obj, __u32 duration)
+ for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
+ err = bpf_map_lookup_elem(map_fd, &tests[i].key, &num);
+ CHECK(err || num != tests[i].num, tests[i].name,
+- "err %d result %lx expected %lx\n",
++ "err %d result %llx expected %llx\n",
+ err, num, tests[i].num);
+ }
+ }
+diff --git a/tools/testing/selftests/bpf/prog_tests/prog_run_xattr.c b/tools/testing/selftests/bpf/prog_tests/prog_run_xattr.c
+index dde2b7ae7bc9e..935a294f049a2 100644
+--- a/tools/testing/selftests/bpf/prog_tests/prog_run_xattr.c
++++ b/tools/testing/selftests/bpf/prog_tests/prog_run_xattr.c
+@@ -28,7 +28,7 @@ void test_prog_run_xattr(void)
+ "err %d errno %d retval %d\n", err, errno, tattr.retval);
+
+ CHECK_ATTR(tattr.data_size_out != sizeof(pkt_v4), "data_size_out",
+- "incorrect output size, want %lu have %u\n",
++ "incorrect output size, want %zu have %u\n",
+ sizeof(pkt_v4), tattr.data_size_out);
+
+ CHECK_ATTR(buf[5] != 0, "overflow",
+diff --git a/tools/testing/selftests/bpf/prog_tests/skb_ctx.c b/tools/testing/selftests/bpf/prog_tests/skb_ctx.c
+index 7021b92af3134..c61b2b69710a9 100644
+--- a/tools/testing/selftests/bpf/prog_tests/skb_ctx.c
++++ b/tools/testing/selftests/bpf/prog_tests/skb_ctx.c
+@@ -80,7 +80,7 @@ void test_skb_ctx(void)
+
+ CHECK_ATTR(tattr.ctx_size_out != sizeof(skb),
+ "ctx_size_out",
+- "incorrect output size, want %lu have %u\n",
++ "incorrect output size, want %zu have %u\n",
+ sizeof(skb), tattr.ctx_size_out);
+
+ for (i = 0; i < 5; i++)
+diff --git a/tools/testing/selftests/bpf/test_btf.c b/tools/testing/selftests/bpf/test_btf.c
+index 305fae8f80a98..c75fc6447186a 100644
+--- a/tools/testing/selftests/bpf/test_btf.c
++++ b/tools/testing/selftests/bpf/test_btf.c
+@@ -3883,7 +3883,7 @@ static int test_big_btf_info(unsigned int test_num)
+ info_garbage.garbage = 0;
+ err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
+ if (CHECK(err || info_len != sizeof(*info),
+- "err:%d errno:%d info_len:%u sizeof(*info):%lu",
++ "err:%d errno:%d info_len:%u sizeof(*info):%zu",
+ err, errno, info_len, sizeof(*info))) {
+ err = -1;
+ goto done;
+@@ -4094,7 +4094,7 @@ static int do_test_get_info(unsigned int test_num)
+ if (CHECK(err || !info.id || info_len != sizeof(info) ||
+ info.btf_size != raw_btf_size ||
+ (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
+- "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%lu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
++ "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%zu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
+ err, errno, info.id, info_len, sizeof(info),
+ raw_btf_size, info.btf_size, expected_nbytes, ret)) {
+ err = -1;
+@@ -4730,7 +4730,7 @@ ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
+
+ nexpected_line = snprintf(expected_line, line_size,
+ "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
+- "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
++ "{%llu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
+ "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
+ percpu_map ? "\tcpu" : "",
+ percpu_map ? cpu : next_key,
+@@ -4738,7 +4738,7 @@ ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
+ v->unused_bits2a,
+ v->bits28,
+ v->unused_bits2b,
+- v->ui64,
++ (__u64)v->ui64,
+ v->ui8a[0], v->ui8a[1],
+ v->ui8a[2], v->ui8a[3],
+ v->ui8a[4], v->ui8a[5],
+diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h
+index b809246039181..b5670350e3263 100644
+--- a/tools/testing/selftests/bpf/test_progs.h
++++ b/tools/testing/selftests/bpf/test_progs.h
+@@ -133,6 +133,11 @@ static inline __u64 ptr_to_u64(const void *ptr)
+ return (__u64) (unsigned long) ptr;
+ }
+
++static inline void *u64_to_ptr(__u64 ptr)
++{
++ return (void *) (unsigned long) ptr;
++}
++
+ int bpf_find_map(const char *test, struct bpf_object *obj, const char *name);
+ int compare_map_keys(int map1_fd, int map2_fd);
+ int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);
+--
+2.25.1
+
--- /dev/null
+From 716a0a6b7ca65dda2ecdb91e48808f9634d53c8a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 13:49:43 -0700
+Subject: selftests/bpf: Correct various core_reloc 64-bit assumptions
+
+From: Andrii Nakryiko <andriin@fb.com>
+
+[ Upstream commit 5705d705832f74395c5465ce93192688f543006a ]
+
+Ensure that types are memory layout- and field alignment-compatible regardless
+of 32/64-bitness mix of libbpf and BPF architecture.
+
+Signed-off-by: Andrii Nakryiko <andriin@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20200813204945.1020225-8-andriin@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/prog_tests/core_reloc.c | 20 +++---
+ .../selftests/bpf/progs/core_reloc_types.h | 69 ++++++++++---------
+ 2 files changed, 47 insertions(+), 42 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c
+index 084ed26a7d78c..a54eafc5e4b31 100644
+--- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c
++++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c
+@@ -237,8 +237,8 @@
+ .union_sz = sizeof(((type *)0)->union_field), \
+ .arr_sz = sizeof(((type *)0)->arr_field), \
+ .arr_elem_sz = sizeof(((type *)0)->arr_field[0]), \
+- .ptr_sz = sizeof(((type *)0)->ptr_field), \
+- .enum_sz = sizeof(((type *)0)->enum_field), \
++ .ptr_sz = 8, /* always 8-byte pointer for BPF */ \
++ .enum_sz = sizeof(((type *)0)->enum_field), \
+ }
+
+ #define SIZE_CASE(name) { \
+@@ -432,20 +432,20 @@ static struct core_reloc_test_case test_cases[] = {
+ .sb4 = -1,
+ .sb20 = -0x17654321,
+ .u32 = 0xBEEF,
+- .s32 = -0x3FEDCBA987654321,
++ .s32 = -0x3FEDCBA987654321LL,
+ }),
+ BITFIELDS_CASE(bitfields___bitfield_vs_int, {
+- .ub1 = 0xFEDCBA9876543210,
++ .ub1 = 0xFEDCBA9876543210LL,
+ .ub2 = 0xA6,
+- .ub7 = -0x7EDCBA987654321,
+- .sb4 = -0x6123456789ABCDE,
+- .sb20 = 0xD00D,
++ .ub7 = -0x7EDCBA987654321LL,
++ .sb4 = -0x6123456789ABCDELL,
++ .sb20 = 0xD00DLL,
+ .u32 = -0x76543,
+- .s32 = 0x0ADEADBEEFBADB0B,
++ .s32 = 0x0ADEADBEEFBADB0BLL,
+ }),
+ BITFIELDS_CASE(bitfields___just_big_enough, {
+- .ub1 = 0xF,
+- .ub2 = 0x0812345678FEDCBA,
++ .ub1 = 0xFLL,
++ .ub2 = 0x0812345678FEDCBALL,
+ }),
+ BITFIELDS_ERR_CASE(bitfields___err_too_big_bitfield),
+
+diff --git a/tools/testing/selftests/bpf/progs/core_reloc_types.h b/tools/testing/selftests/bpf/progs/core_reloc_types.h
+index 34d84717c9464..69139ed662164 100644
+--- a/tools/testing/selftests/bpf/progs/core_reloc_types.h
++++ b/tools/testing/selftests/bpf/progs/core_reloc_types.h
+@@ -1,5 +1,10 @@
+ #include <stdint.h>
+ #include <stdbool.h>
++
++void preserce_ptr_sz_fn(long x) {}
++
++#define __bpf_aligned __attribute__((aligned(8)))
++
+ /*
+ * KERNEL
+ */
+@@ -444,51 +449,51 @@ struct core_reloc_primitives {
+ char a;
+ int b;
+ enum core_reloc_primitives_enum c;
+- void *d;
+- int (*f)(const char *);
++ void *d __bpf_aligned;
++ int (*f)(const char *) __bpf_aligned;
+ };
+
+ struct core_reloc_primitives___diff_enum_def {
+ char a;
+ int b;
+- void *d;
+- int (*f)(const char *);
++ void *d __bpf_aligned;
++ int (*f)(const char *) __bpf_aligned;
+ enum {
+ X = 100,
+ Y = 200,
+- } c; /* inline enum def with differing set of values */
++ } c __bpf_aligned; /* inline enum def with differing set of values */
+ };
+
+ struct core_reloc_primitives___diff_func_proto {
+- void (*f)(int); /* incompatible function prototype */
+- void *d;
+- enum core_reloc_primitives_enum c;
++ void (*f)(int) __bpf_aligned; /* incompatible function prototype */
++ void *d __bpf_aligned;
++ enum core_reloc_primitives_enum c __bpf_aligned;
+ int b;
+ char a;
+ };
+
+ struct core_reloc_primitives___diff_ptr_type {
+- const char * const d; /* different pointee type + modifiers */
+- char a;
++ const char * const d __bpf_aligned; /* different pointee type + modifiers */
++ char a __bpf_aligned;
+ int b;
+ enum core_reloc_primitives_enum c;
+- int (*f)(const char *);
++ int (*f)(const char *) __bpf_aligned;
+ };
+
+ struct core_reloc_primitives___err_non_enum {
+ char a[1];
+ int b;
+ int c; /* int instead of enum */
+- void *d;
+- int (*f)(const char *);
++ void *d __bpf_aligned;
++ int (*f)(const char *) __bpf_aligned;
+ };
+
+ struct core_reloc_primitives___err_non_int {
+ char a[1];
+- int *b; /* ptr instead of int */
+- enum core_reloc_primitives_enum c;
+- void *d;
+- int (*f)(const char *);
++ int *b __bpf_aligned; /* ptr instead of int */
++ enum core_reloc_primitives_enum c __bpf_aligned;
++ void *d __bpf_aligned;
++ int (*f)(const char *) __bpf_aligned;
+ };
+
+ struct core_reloc_primitives___err_non_ptr {
+@@ -496,7 +501,7 @@ struct core_reloc_primitives___err_non_ptr {
+ int b;
+ enum core_reloc_primitives_enum c;
+ int d; /* int instead of ptr */
+- int (*f)(const char *);
++ int (*f)(const char *) __bpf_aligned;
+ };
+
+ /*
+@@ -507,7 +512,7 @@ struct core_reloc_mods_output {
+ };
+
+ typedef const int int_t;
+-typedef const char *char_ptr_t;
++typedef const char *char_ptr_t __bpf_aligned;
+ typedef const int arr_t[7];
+
+ struct core_reloc_mods_substruct {
+@@ -523,9 +528,9 @@ typedef struct {
+ struct core_reloc_mods {
+ int a;
+ int_t b;
+- char *c;
++ char *c __bpf_aligned;
+ char_ptr_t d;
+- int e[3];
++ int e[3] __bpf_aligned;
+ arr_t f;
+ struct core_reloc_mods_substruct g;
+ core_reloc_mods_substruct_t h;
+@@ -535,9 +540,9 @@ struct core_reloc_mods {
+ struct core_reloc_mods___mod_swap {
+ int b;
+ int_t a;
+- char *d;
++ char *d __bpf_aligned;
+ char_ptr_t c;
+- int f[3];
++ int f[3] __bpf_aligned;
+ arr_t e;
+ struct {
+ int y;
+@@ -555,7 +560,7 @@ typedef arr1_t arr2_t;
+ typedef arr2_t arr3_t;
+ typedef arr3_t arr4_t;
+
+-typedef const char * const volatile fancy_char_ptr_t;
++typedef const char * const volatile fancy_char_ptr_t __bpf_aligned;
+
+ typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt;
+
+@@ -567,7 +572,7 @@ struct core_reloc_mods___typedefs {
+ arr4_t e;
+ fancy_char_ptr_t d;
+ fancy_char_ptr_t c;
+- int3_t b;
++ int3_t b __bpf_aligned;
+ int3_t a;
+ };
+
+@@ -739,19 +744,19 @@ struct core_reloc_bitfields___bit_sz_change {
+ int8_t sb4: 1; /* 4 -> 1 */
+ int32_t sb20: 30; /* 20 -> 30 */
+ /* non-bitfields */
+- uint16_t u32; /* 32 -> 16 */
+- int64_t s32; /* 32 -> 64 */
++ uint16_t u32; /* 32 -> 16 */
++ int64_t s32 __bpf_aligned; /* 32 -> 64 */
+ };
+
+ /* turn bitfield into non-bitfield and vice versa */
+ struct core_reloc_bitfields___bitfield_vs_int {
+ uint64_t ub1; /* 3 -> 64 non-bitfield */
+ uint8_t ub2; /* 20 -> 8 non-bitfield */
+- int64_t ub7; /* 7 -> 64 non-bitfield signed */
+- int64_t sb4; /* 4 -> 64 non-bitfield signed */
+- uint64_t sb20; /* 20 -> 16 non-bitfield unsigned */
+- int32_t u32: 20; /* 32 non-bitfield -> 20 bitfield */
+- uint64_t s32: 60; /* 32 non-bitfield -> 60 bitfield */
++ int64_t ub7 __bpf_aligned; /* 7 -> 64 non-bitfield signed */
++ int64_t sb4 __bpf_aligned; /* 4 -> 64 non-bitfield signed */
++ uint64_t sb20 __bpf_aligned; /* 20 -> 16 non-bitfield unsigned */
++ int32_t u32: 20; /* 32 non-bitfield -> 20 bitfield */
++ uint64_t s32: 60 __bpf_aligned; /* 32 non-bitfield -> 60 bitfield */
+ };
+
+ struct core_reloc_bitfields___just_big_enough {
+--
+2.25.1
+
--- /dev/null
+From 69139551b7d6e7d1ee178e0deb77d30c939c2f9b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 13:49:41 -0700
+Subject: selftests/bpf: Fix btf_dump test cases on 32-bit arches
+
+From: Andrii Nakryiko <andriin@fb.com>
+
+[ Upstream commit eed7818adf03e874994b966aa33bc00204dd275a ]
+
+Fix btf_dump test cases by hard-coding BPF's pointer size of 8 bytes for cases
+where it's impossible to deterimne the pointer size (no long type in BTF). In
+cases where it's known, validate libbpf correctly determines it as 8.
+
+Signed-off-by: Andrii Nakryiko <andriin@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20200813204945.1020225-6-andriin@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/bpf/prog_tests/btf_dump.c | 27 ++++++++++++++-----
+ 1 file changed, 20 insertions(+), 7 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/btf_dump.c b/tools/testing/selftests/bpf/prog_tests/btf_dump.c
+index cb33a7ee4e04f..39fb81d9daeb5 100644
+--- a/tools/testing/selftests/bpf/prog_tests/btf_dump.c
++++ b/tools/testing/selftests/bpf/prog_tests/btf_dump.c
+@@ -12,15 +12,16 @@ void btf_dump_printf(void *ctx, const char *fmt, va_list args)
+ static struct btf_dump_test_case {
+ const char *name;
+ const char *file;
++ bool known_ptr_sz;
+ struct btf_dump_opts opts;
+ } btf_dump_test_cases[] = {
+- {"btf_dump: syntax", "btf_dump_test_case_syntax", {}},
+- {"btf_dump: ordering", "btf_dump_test_case_ordering", {}},
+- {"btf_dump: padding", "btf_dump_test_case_padding", {}},
+- {"btf_dump: packing", "btf_dump_test_case_packing", {}},
+- {"btf_dump: bitfields", "btf_dump_test_case_bitfields", {}},
+- {"btf_dump: multidim", "btf_dump_test_case_multidim", {}},
+- {"btf_dump: namespacing", "btf_dump_test_case_namespacing", {}},
++ {"btf_dump: syntax", "btf_dump_test_case_syntax", true, {}},
++ {"btf_dump: ordering", "btf_dump_test_case_ordering", false, {}},
++ {"btf_dump: padding", "btf_dump_test_case_padding", true, {}},
++ {"btf_dump: packing", "btf_dump_test_case_packing", true, {}},
++ {"btf_dump: bitfields", "btf_dump_test_case_bitfields", true, {}},
++ {"btf_dump: multidim", "btf_dump_test_case_multidim", false, {}},
++ {"btf_dump: namespacing", "btf_dump_test_case_namespacing", false, {}},
+ };
+
+ static int btf_dump_all_types(const struct btf *btf,
+@@ -62,6 +63,18 @@ static int test_btf_dump_case(int n, struct btf_dump_test_case *t)
+ goto done;
+ }
+
++ /* tests with t->known_ptr_sz have no "long" or "unsigned long" type,
++ * so it's impossible to determine correct pointer size; but if they
++ * do, it should be 8 regardless of host architecture, becaues BPF
++ * target is always 64-bit
++ */
++ if (!t->known_ptr_sz) {
++ btf__set_pointer_size(btf, 8);
++ } else {
++ CHECK(btf__pointer_size(btf) != 8, "ptr_sz", "exp %d, got %zu\n",
++ 8, btf__pointer_size(btf));
++ }
++
+ snprintf(out_file, sizeof(out_file), "/tmp/%s.output.XXXXXX", t->file);
+ fd = mkstemp(out_file);
+ if (CHECK(fd < 0, "create_tmp", "failed to create file: %d\n", fd)) {
+--
+2.25.1
+
--- /dev/null
+From 9446a6d0140f127abfb26e98d3d9a74ac1bc336d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Aug 2020 23:39:40 +0800
+Subject: selftests/bpf: Fix segmentation fault in test_progs
+
+From: Jianlin Lv <Jianlin.Lv@arm.com>
+
+[ Upstream commit 0390c429dbed4068bd2cd8dded937d9a5ec24cd2 ]
+
+test_progs reports the segmentation fault as below:
+
+ $ sudo ./test_progs -t mmap --verbose
+ test_mmap:PASS:skel_open_and_load 0 nsec
+ [...]
+ test_mmap:PASS:adv_mmap1 0 nsec
+ test_mmap:PASS:adv_mmap2 0 nsec
+ test_mmap:PASS:adv_mmap3 0 nsec
+ test_mmap:PASS:adv_mmap4 0 nsec
+ Segmentation fault
+
+This issue was triggered because mmap() and munmap() used inconsistent
+length parameters; mmap() creates a new mapping of 3 * page_size, but the
+length parameter set in the subsequent re-map and munmap() functions is
+4 * page_size; this leads to the destruction of the process space.
+
+To fix this issue, first create 4 pages of anonymous mapping, then do all
+the mmap() with MAP_FIXED.
+
+Another issue is that when unmap the second page fails, the length
+parameter to delete tmp1 mappings should be 4 * page_size.
+
+Signed-off-by: Jianlin Lv <Jianlin.Lv@arm.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Andrii Nakryiko <andriin@fb.com>
+Link: https://lore.kernel.org/bpf/20200810153940.125508-1-Jianlin.Lv@arm.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/bpf/prog_tests/mmap.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+diff --git a/tools/testing/selftests/bpf/prog_tests/mmap.c b/tools/testing/selftests/bpf/prog_tests/mmap.c
+index 43d0b5578f461..9c3c5c0f068fb 100644
+--- a/tools/testing/selftests/bpf/prog_tests/mmap.c
++++ b/tools/testing/selftests/bpf/prog_tests/mmap.c
+@@ -21,7 +21,7 @@ void test_mmap(void)
+ const long page_size = sysconf(_SC_PAGE_SIZE);
+ int err, duration = 0, i, data_map_fd, data_map_id, tmp_fd, rdmap_fd;
+ struct bpf_map *data_map, *bss_map;
+- void *bss_mmaped = NULL, *map_mmaped = NULL, *tmp1, *tmp2;
++ void *bss_mmaped = NULL, *map_mmaped = NULL, *tmp0, *tmp1, *tmp2;
+ struct test_mmap__bss *bss_data;
+ struct bpf_map_info map_info;
+ __u32 map_info_sz = sizeof(map_info);
+@@ -183,16 +183,23 @@ void test_mmap(void)
+
+ /* check some more advanced mmap() manipulations */
+
++ tmp0 = mmap(NULL, 4 * page_size, PROT_READ, MAP_SHARED | MAP_ANONYMOUS,
++ -1, 0);
++ if (CHECK(tmp0 == MAP_FAILED, "adv_mmap0", "errno %d\n", errno))
++ goto cleanup;
++
+ /* map all but last page: pages 1-3 mapped */
+- tmp1 = mmap(NULL, 3 * page_size, PROT_READ, MAP_SHARED,
++ tmp1 = mmap(tmp0, 3 * page_size, PROT_READ, MAP_SHARED | MAP_FIXED,
+ data_map_fd, 0);
+- if (CHECK(tmp1 == MAP_FAILED, "adv_mmap1", "errno %d\n", errno))
++ if (CHECK(tmp0 != tmp1, "adv_mmap1", "tmp0: %p, tmp1: %p\n", tmp0, tmp1)) {
++ munmap(tmp0, 4 * page_size);
+ goto cleanup;
++ }
+
+ /* unmap second page: pages 1, 3 mapped */
+ err = munmap(tmp1 + page_size, page_size);
+ if (CHECK(err, "adv_mmap2", "errno %d\n", errno)) {
+- munmap(tmp1, map_sz);
++ munmap(tmp1, 4 * page_size);
+ goto cleanup;
+ }
+
+@@ -201,7 +208,7 @@ void test_mmap(void)
+ MAP_SHARED | MAP_FIXED, data_map_fd, 0);
+ if (CHECK(tmp2 == MAP_FAILED, "adv_mmap3", "errno %d\n", errno)) {
+ munmap(tmp1, page_size);
+- munmap(tmp1 + 2*page_size, page_size);
++ munmap(tmp1 + 2*page_size, 2 * page_size);
+ goto cleanup;
+ }
+ CHECK(tmp1 + page_size != tmp2, "adv_mmap4",
+@@ -211,7 +218,7 @@ void test_mmap(void)
+ tmp2 = mmap(tmp1, 4 * page_size, PROT_READ, MAP_SHARED | MAP_FIXED,
+ data_map_fd, 0);
+ if (CHECK(tmp2 == MAP_FAILED, "adv_mmap5", "errno %d\n", errno)) {
+- munmap(tmp1, 3 * page_size); /* unmap page 1 */
++ munmap(tmp1, 4 * page_size); /* unmap page 1 */
+ goto cleanup;
+ }
+ CHECK(tmp1 != tmp2, "adv_mmap6", "tmp1: %p, tmp2: %p\n", tmp1, tmp2);
+--
+2.25.1
+
--- /dev/null
+From d6c5a0c30bae337c51a88b4c6d55dc2c15c9a81a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 17 Aug 2020 09:43:33 -0600
+Subject: selftests: disable rp_filter for icmp_redirect.sh
+
+From: David Ahern <dsahern@kernel.org>
+
+[ Upstream commit bcf7ddb0186d366f761f86196b480ea6dd2dc18c ]
+
+h1 is initially configured to reach h2 via r1 rather than the
+more direct path through r2. If rp_filter is set and inherited
+for r2, forwarding fails since the source address of h1 is
+reachable from eth0 vs the packet coming to it via r1 and eth1.
+Since rp_filter setting affects the test, explicitly reset it.
+
+Signed-off-by: David Ahern <dsahern@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/net/icmp_redirect.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/tools/testing/selftests/net/icmp_redirect.sh b/tools/testing/selftests/net/icmp_redirect.sh
+index 18c5de53558af..bf361f30d6ef9 100755
+--- a/tools/testing/selftests/net/icmp_redirect.sh
++++ b/tools/testing/selftests/net/icmp_redirect.sh
+@@ -180,6 +180,8 @@ setup()
+ ;;
+ r[12]) ip netns exec $ns sysctl -q -w net.ipv4.ip_forward=1
+ ip netns exec $ns sysctl -q -w net.ipv4.conf.all.send_redirects=1
++ ip netns exec $ns sysctl -q -w net.ipv4.conf.default.rp_filter=0
++ ip netns exec $ns sysctl -q -w net.ipv4.conf.all.rp_filter=0
+
+ ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=1
+ ip netns exec $ns sysctl -q -w net.ipv6.route.mtu_expires=10
+--
+2.25.1
+
pm-devfreq-fix-the-wrong-end-with-semicolon.patch
cpufreq-intel_pstate-fix-epp-setting-via-sysfs-in-ac.patch
alsa-usb-audio-add-capture-support-for-saffire-6-usb.patch
+nfsd-fix-oops-on-mixed-nfsv4-nfsv3-client-access.patch
+block-respect-queue-limit-of-max-discard-segment.patch
+block-virtio_blk-fix-handling-single-range-discard-r.patch
+drm-msm-adreno-fix-updating-ring-fence.patch
+block-fix-page_is_mergeable-for-compound-pages.patch
+bfq-fix-blkio-cgroup-leakage-v4.patch
+hwmon-nct7904-correct-divide-by-0.patch
+blk-mq-insert-request-not-through-queue_rq-into-sw-s.patch
+blkcg-fix-memleak-for-iolatency.patch
+nvmet-fix-a-memory-leak.patch
+nvme-fc-fix-wrong-return-value-in-__nvme_fc_init_req.patch
+nvme-multipath-round-robin-fix-single-non-optimized-.patch
+null_blk-fix-passing-of-req_fua-flag-in-null_handle_.patch
+habanalabs-fix-memory-corruption-in-debugfs.patch
+drm-etnaviv-always-start-stop-scheduler-in-timeout-p.patch
+i2c-core-don-t-fail-prp0001-enumeration-when-no-id-t.patch
+i2c-rcar-in-slave-mode-clear-nack-earlier.patch
+vdpa-ifcvf-return-err-when-fail-to-request-config-ir.patch
+vdpa-ifcvf-free-config-irq-in-ifcvf_free_irq.patch
+usb-gadget-f_tcm-fix-some-resource-leaks-in-some-err.patch
+video-fbdev-controlfb-fix-build-for-compile_test-y-p.patch
+spi-stm32-clear-only-asserted-irq-flags-on-interrupt.patch
+jbd2-make-sure-jh-have-b_transaction-set-in-refile-u.patch
+ext4-don-t-bug-on-inconsistent-journal-feature.patch
+ext4-handle-read-only-external-journal-device.patch
+ext4-skip-non-loaded-groups-at-cr-0-1-when-scanning-.patch
+drm-virtio-fix-memory-leak-in-virtio_gpu_cleanup_obj.patch
+ext4-abort-the-filesystem-if-failed-to-async-write-m.patch
+jbd2-abort-journal-if-free-a-async-write-error-metad.patch
+ext4-handle-option-set-by-mount-flags-correctly.patch
+ext4-handle-error-of-ext4_setup_system_zone-on-remou.patch
+ext4-correctly-restore-system-zone-info-when-remount.patch
+fs-prevent-bug_on-in-submit_bh_wbc.patch
+spi-stm32h7-fix-race-condition-at-end-of-transfer.patch
+spi-stm32-fix-fifo-threshold-level-in-case-of-short-.patch
+spi-stm32-fix-stm32_spi_prepare_mbr-in-case-of-odd-c.patch
+spi-stm32-always-perform-registers-configuration-pri.patch
+drm-amd-powerplay-correct-vega20-cached-smu-feature-.patch
+drm-amd-powerplay-correct-uvd-vce-pg-state-on-custom.patch
+drm-amd-display-fix-lfc-multiplier-changing-erratica.patch
+drm-amd-display-switch-to-immediate-mode-for-updatin.patch
+selftests-bpf-fix-segmentation-fault-in-test_progs.patch
+libbpf-handle-gcc-built-in-types-for-arm-neon.patch
+netfilter-avoid-ipv6-nf_defrag_ipv6-module-dependenc.patch
+libbpf-prevent-overriding-errno-when-logging-errors.patch
+tools-bpftool-fix-compilation-warnings-in-32-bit-mod.patch
+selftest-bpf-fix-compilation-warnings-in-32-bit-mode.patch
+selftests-bpf-fix-btf_dump-test-cases-on-32-bit-arch.patch
+selftests-bpf-correct-various-core_reloc-64-bit-assu.patch
+can-j1939-transport-j1939_xtp_rx_dat_one-compare-own.patch
+dma-pool-fix-coherent-pool-allocations-for-iommu-map.patch
+dma-pool-only-allocate-from-cma-when-in-same-memory-.patch
+drivers-net-wan-hdlc_x25-added-needed_headroom-and-a.patch
+alsa-hda-realtek-add-model-alc298-samsung-headphone.patch
+s390-cio-add-cond_resched-in-the-slow_eval_known_fn-.patch
+asoc-wm8994-avoid-attempts-to-read-unreadable-regist.patch
+alsa-usb-audio-ignore-broken-processing-extension-un.patch
+selftests-disable-rp_filter-for-icmp_redirect.sh.patch
+scsi-fcoe-fix-i-o-path-allocation.patch
+scsi-ufs-fix-possible-infinite-loop-in-ufshcd_hold.patch
+scsi-ufs-improve-interrupt-handling-for-shared-inter.patch
+scsi-ufs-clean-up-completed-request-without-interrup.patch
+scsi-scsi_debug-fix-scp-is-null-errors.patch
+scsi-qla2xxx-flush-all-sessions-on-zone-disable.patch
+scsi-qla2xxx-flush-i-o-on-zone-disable.patch
+scsi-qla2xxx-indicate-correct-supported-speeds-for-m.patch
+scsi-qla2xxx-fix-login-timeout.patch
+scsi-qla2xxx-check-if-fw-supports-mq-before-enabling.patch
+scsi-qla2xxx-fix-null-pointer-access-during-disconne.patch
+revert-scsi-qla2xxx-fix-crash-on-qla2x00_mailbox_com.patch
+macvlan-validate-setting-of-multiple-remote-source-m.patch
+net-gianfar-add-of_node_put-before-goto-statement.patch
+drm-amdgpu-fix-null-pointer-access-issue-when-unload.patch
+drm-amdkfd-fix-the-wrong-sdma-instance-query-for-ren.patch
+bpf-fix-a-rcu_sched-stall-issue-with-bpf-task-task_f.patch
+bpf-avoid-visit-same-object-multiple-times.patch
+ext4-limit-the-length-of-per-inode-prealloc-list.patch
+powerpc-perf-fix-soft-lockups-due-to-missed-interrup.patch
+libbpf-fix-map-index-used-in-error-message.patch
+bpf-selftests-global_funcs-check-err_str-before-strs.patch
+arm64-move-handling-of-erratum-1418040-into-c-code.patch
+arm64-allow-booting-of-late-cpus-affected-by-erratum.patch
--- /dev/null
+From a8b321f59e182a7cef112f0fd4f10005930a3439 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Aug 2020 09:12:38 +0200
+Subject: spi: stm32: always perform registers configuration prior to transfer
+
+From: Alain Volmat <alain.volmat@st.com>
+
+[ Upstream commit 60ccb3515fc61a0124c70aa37317f75b67560024 ]
+
+SPI registers content may have been lost upon suspend/resume sequence.
+So, always compute and apply the necessary configuration in
+stm32_spi_transfer_one_setup routine.
+
+Signed-off-by: Alain Volmat <alain.volmat@st.com>
+Link: https://lore.kernel.org/r/1597043558-29668-6-git-send-email-alain.volmat@st.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-stm32.c | 42 +++++++++++++++++------------------------
+ 1 file changed, 17 insertions(+), 25 deletions(-)
+
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 9b90a22543fd7..d4b33b358a31e 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -1597,41 +1597,33 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
+ unsigned long flags;
+ unsigned int comm_type;
+ int nb_words, ret = 0;
++ int mbr;
+
+ spin_lock_irqsave(&spi->lock, flags);
+
+ spi->cur_xferlen = transfer->len;
+
+- if (spi->cur_bpw != transfer->bits_per_word) {
+- spi->cur_bpw = transfer->bits_per_word;
+- spi->cfg->set_bpw(spi);
+- }
+-
+- if (spi->cur_speed != transfer->speed_hz) {
+- int mbr;
+-
+- /* Update spi->cur_speed with real clock speed */
+- mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz,
+- spi->cfg->baud_rate_div_min,
+- spi->cfg->baud_rate_div_max);
+- if (mbr < 0) {
+- ret = mbr;
+- goto out;
+- }
++ spi->cur_bpw = transfer->bits_per_word;
++ spi->cfg->set_bpw(spi);
+
+- transfer->speed_hz = spi->cur_speed;
+- stm32_spi_set_mbr(spi, mbr);
++ /* Update spi->cur_speed with real clock speed */
++ mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz,
++ spi->cfg->baud_rate_div_min,
++ spi->cfg->baud_rate_div_max);
++ if (mbr < 0) {
++ ret = mbr;
++ goto out;
+ }
+
+- comm_type = stm32_spi_communication_type(spi_dev, transfer);
+- if (spi->cur_comm != comm_type) {
+- ret = spi->cfg->set_mode(spi, comm_type);
++ transfer->speed_hz = spi->cur_speed;
++ stm32_spi_set_mbr(spi, mbr);
+
+- if (ret < 0)
+- goto out;
++ comm_type = stm32_spi_communication_type(spi_dev, transfer);
++ ret = spi->cfg->set_mode(spi, comm_type);
++ if (ret < 0)
++ goto out;
+
+- spi->cur_comm = comm_type;
+- }
++ spi->cur_comm = comm_type;
+
+ if (spi->cfg->set_data_idleness)
+ spi->cfg->set_data_idleness(spi, transfer->len);
+--
+2.25.1
+
--- /dev/null
+From 806ff3f86f5fa59de9b8e4bfcda592aa17545341 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Aug 2020 21:51:36 +0200
+Subject: spi: stm32: clear only asserted irq flags on interrupt
+
+From: Tobias Schramm <t.schramm@manjaro.org>
+
+[ Upstream commit ae1ba50f1e706dfd7ce402ac52c1f1f10becad68 ]
+
+Previously the stm32h7 interrupt thread cleared all non-masked interrupts.
+If an interrupt was to occur during the handling of another interrupt its
+flag would be unset, resulting in a lost interrupt.
+This patches fixes the issue by clearing only the currently set interrupt
+flags.
+
+Signed-off-by: Tobias Schramm <t.schramm@manjaro.org>
+Link: https://lore.kernel.org/r/20200804195136.1485392-1-t.schramm@manjaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-stm32.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 9672cda2f8031..13f3d959759fb 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -967,7 +967,7 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
+ if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
+ stm32h7_spi_read_rxfifo(spi, false);
+
+- writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR);
++ writel_relaxed(sr & mask, spi->base + STM32H7_SPI_IFCR);
+
+ spin_unlock_irqrestore(&spi->lock, flags);
+
+--
+2.25.1
+
--- /dev/null
+From 3bfa391f680aa22db6d56b48bcc21bbef32edb6a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Aug 2020 09:12:35 +0200
+Subject: spi: stm32: fix fifo threshold level in case of short transfer
+
+From: Amelie Delaunay <amelie.delaunay@st.com>
+
+[ Upstream commit 3373e9004acc0603242622b4378c64bc01d21b5f ]
+
+When transfer is shorter than half of the fifo, set the data packet size
+up to transfer size instead of up to half of the fifo.
+Check also that threshold is set at least to 1 data frame.
+
+Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
+Signed-off-by: Alain Volmat <alain.volmat@st.com>
+Link: https://lore.kernel.org/r/1597043558-29668-3-git-send-email-alain.volmat@st.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-stm32.c | 26 ++++++++++++++++++--------
+ 1 file changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index fce679635829c..7f2113e7b3ddc 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -468,20 +468,27 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
+ /**
+ * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
+ * @spi: pointer to the spi controller data structure
++ * @xfer_len: length of the message to be transferred
+ */
+-static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
++static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len)
+ {
+- u32 fthlv, half_fifo;
++ u32 fthlv, half_fifo, packet;
+
+ /* data packet should not exceed 1/2 of fifo space */
+ half_fifo = (spi->fifo_size / 2);
+
++ /* data_packet should not exceed transfer length */
++ if (half_fifo > xfer_len)
++ packet = xfer_len;
++ else
++ packet = half_fifo;
++
+ if (spi->cur_bpw <= 8)
+- fthlv = half_fifo;
++ fthlv = packet;
+ else if (spi->cur_bpw <= 16)
+- fthlv = half_fifo / 2;
++ fthlv = packet / 2;
+ else
+- fthlv = half_fifo / 4;
++ fthlv = packet / 4;
+
+ /* align packet size with data registers access */
+ if (spi->cur_bpw > 8)
+@@ -489,6 +496,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
+ else
+ fthlv -= (fthlv % 4); /* multiple of 4 */
+
++ if (!fthlv)
++ fthlv = 1;
++
+ return fthlv;
+ }
+
+@@ -1394,7 +1404,7 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi)
+ cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
+ STM32H7_SPI_CFG1_DSIZE;
+
+- spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi);
++ spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi, spi->cur_xferlen);
+ fthlv = spi->cur_fthlv - 1;
+
+ cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
+@@ -1589,6 +1599,8 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
+
+ spin_lock_irqsave(&spi->lock, flags);
+
++ spi->cur_xferlen = transfer->len;
++
+ if (spi->cur_bpw != transfer->bits_per_word) {
+ spi->cur_bpw = transfer->bits_per_word;
+ spi->cfg->set_bpw(spi);
+@@ -1636,8 +1648,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
+ goto out;
+ }
+
+- spi->cur_xferlen = transfer->len;
+-
+ dev_dbg(spi->dev, "transfer communication mode set to %d\n",
+ spi->cur_comm);
+ dev_dbg(spi->dev,
+--
+2.25.1
+
--- /dev/null
+From 4fecc9ef85a49ade4d2239a0636d1d18149fe06b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Aug 2020 09:12:36 +0200
+Subject: spi: stm32: fix stm32_spi_prepare_mbr in case of odd clk_rate
+
+From: Amelie Delaunay <amelie.delaunay@st.com>
+
+[ Upstream commit 9cc61973bf9385b19ff5dda4a2a7e265fcba85e4 ]
+
+Fix spi->clk_rate when it is odd to the nearest lowest even value because
+minimum SPI divider is 2.
+
+Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
+Signed-off-by: Alain Volmat <alain.volmat@st.com>
+Link: https://lore.kernel.org/r/1597043558-29668-4-git-send-email-alain.volmat@st.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-stm32.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 7f2113e7b3ddc..9b90a22543fd7 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -442,7 +442,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
+ {
+ u32 div, mbrdiv;
+
+- div = DIV_ROUND_UP(spi->clk_rate, speed_hz);
++ /* Ensure spi->clk_rate is even */
++ div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz);
+
+ /*
+ * SPI framework set xfer->speed_hz to master->max_speed_hz if
+--
+2.25.1
+
--- /dev/null
+From a37930829df4f2f316f8425569ad7a46d093304b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Aug 2020 09:12:34 +0200
+Subject: spi: stm32h7: fix race condition at end of transfer
+
+From: Antonio Borneo <antonio.borneo@st.com>
+
+[ Upstream commit 135dd873d3c76d812ae64c668adef3f2c59ed27f ]
+
+The caller of stm32_spi_transfer_one(), spi_transfer_one_message(),
+is waiting for us to call spi_finalize_current_transfer() and will
+eventually schedule a new transfer, if available.
+We should guarantee that the spi controller is really available
+before calling spi_finalize_current_transfer().
+
+Move the call to spi_finalize_current_transfer() _after_ the call
+to stm32_spi_disable().
+
+Signed-off-by: Antonio Borneo <antonio.borneo@st.com>
+Signed-off-by: Alain Volmat <alain.volmat@st.com>
+Link: https://lore.kernel.org/r/1597043558-29668-2-git-send-email-alain.volmat@st.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-stm32.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
+index 13f3d959759fb..fce679635829c 100644
+--- a/drivers/spi/spi-stm32.c
++++ b/drivers/spi/spi-stm32.c
+@@ -972,8 +972,8 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
+ spin_unlock_irqrestore(&spi->lock, flags);
+
+ if (end) {
+- spi_finalize_current_transfer(master);
+ stm32h7_spi_disable(spi);
++ spi_finalize_current_transfer(master);
+ }
+
+ return IRQ_HANDLED;
+--
+2.25.1
+
--- /dev/null
+From 949b1e8ef2f2dcf98e2017a98282efbc3d748e3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 13 Aug 2020 13:49:37 -0700
+Subject: tools/bpftool: Fix compilation warnings in 32-bit mode
+
+From: Andrii Nakryiko <andriin@fb.com>
+
+[ Upstream commit 09f44b753a7d120becc80213c3459183c8acd26b ]
+
+Fix few compilation warnings in bpftool when compiling in 32-bit mode.
+Abstract away u64 to pointer conversion into a helper function.
+
+Signed-off-by: Andrii Nakryiko <andriin@fb.com>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Link: https://lore.kernel.org/bpf/20200813204945.1020225-2-andriin@fb.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/bpf/bpftool/btf_dumper.c | 2 +-
+ tools/bpf/bpftool/link.c | 4 ++--
+ tools/bpf/bpftool/main.h | 10 +++++++++-
+ tools/bpf/bpftool/prog.c | 16 ++++++++--------
+ 4 files changed, 20 insertions(+), 12 deletions(-)
+
+diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
+index ede162f83eea0..0e9310727281a 100644
+--- a/tools/bpf/bpftool/btf_dumper.c
++++ b/tools/bpf/bpftool/btf_dumper.c
+@@ -67,7 +67,7 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
+ if (!info->btf_id || !info->nr_func_info ||
+ btf__get_from_id(info->btf_id, &prog_btf))
+ goto print;
+- finfo = (struct bpf_func_info *)info->func_info;
++ finfo = u64_to_ptr(info->func_info);
+ func_type = btf__type_by_id(prog_btf, finfo->type_id);
+ if (!func_type || !btf_is_func(func_type))
+ goto print;
+diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c
+index fca57ee8fafe4..dea691c83afca 100644
+--- a/tools/bpf/bpftool/link.c
++++ b/tools/bpf/bpftool/link.c
+@@ -101,7 +101,7 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
+ switch (info->type) {
+ case BPF_LINK_TYPE_RAW_TRACEPOINT:
+ jsonw_string_field(json_wtr, "tp_name",
+- (const char *)info->raw_tracepoint.tp_name);
++ u64_to_ptr(info->raw_tracepoint.tp_name));
+ break;
+ case BPF_LINK_TYPE_TRACING:
+ err = get_prog_info(info->prog_id, &prog_info);
+@@ -177,7 +177,7 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
+ switch (info->type) {
+ case BPF_LINK_TYPE_RAW_TRACEPOINT:
+ printf("\n\ttp '%s' ",
+- (const char *)info->raw_tracepoint.tp_name);
++ (const char *)u64_to_ptr(info->raw_tracepoint.tp_name));
+ break;
+ case BPF_LINK_TYPE_TRACING:
+ err = get_prog_info(info->prog_id, &prog_info);
+diff --git a/tools/bpf/bpftool/main.h b/tools/bpf/bpftool/main.h
+index 5cdf0bc049bd9..5917484c2e027 100644
+--- a/tools/bpf/bpftool/main.h
++++ b/tools/bpf/bpftool/main.h
+@@ -21,7 +21,15 @@
+ /* Make sure we do not use kernel-only integer typedefs */
+ #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
+
+-#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr))
++static inline __u64 ptr_to_u64(const void *ptr)
++{
++ return (__u64)(unsigned long)ptr;
++}
++
++static inline void *u64_to_ptr(__u64 ptr)
++{
++ return (void *)(unsigned long)ptr;
++}
+
+ #define NEXT_ARG() ({ argc--; argv++; if (argc < 0) usage(); })
+ #define NEXT_ARGP() ({ (*argc)--; (*argv)++; if (*argc < 0) usage(); })
+diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
+index a5eff83496f2d..2c6f7e160b248 100644
+--- a/tools/bpf/bpftool/prog.c
++++ b/tools/bpf/bpftool/prog.c
+@@ -537,14 +537,14 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
+ p_info("no instructions returned");
+ return -1;
+ }
+- buf = (unsigned char *)(info->jited_prog_insns);
++ buf = u64_to_ptr(info->jited_prog_insns);
+ member_len = info->jited_prog_len;
+ } else { /* DUMP_XLATED */
+ if (info->xlated_prog_len == 0 || !info->xlated_prog_insns) {
+ p_err("error retrieving insn dump: kernel.kptr_restrict set?");
+ return -1;
+ }
+- buf = (unsigned char *)info->xlated_prog_insns;
++ buf = u64_to_ptr(info->xlated_prog_insns);
+ member_len = info->xlated_prog_len;
+ }
+
+@@ -553,7 +553,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
+ return -1;
+ }
+
+- func_info = (void *)info->func_info;
++ func_info = u64_to_ptr(info->func_info);
+
+ if (info->nr_line_info) {
+ prog_linfo = bpf_prog_linfo__new(info);
+@@ -571,7 +571,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
+
+ n = write(fd, buf, member_len);
+ close(fd);
+- if (n != member_len) {
++ if (n != (ssize_t)member_len) {
+ p_err("error writing output file: %s",
+ n < 0 ? strerror(errno) : "short write");
+ return -1;
+@@ -601,13 +601,13 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
+ __u32 i;
+ if (info->nr_jited_ksyms) {
+ kernel_syms_load(&dd);
+- ksyms = (__u64 *) info->jited_ksyms;
++ ksyms = u64_to_ptr(info->jited_ksyms);
+ }
+
+ if (json_output)
+ jsonw_start_array(json_wtr);
+
+- lens = (__u32 *) info->jited_func_lens;
++ lens = u64_to_ptr(info->jited_func_lens);
+ for (i = 0; i < info->nr_jited_func_lens; i++) {
+ if (ksyms) {
+ sym = kernel_syms_search(&dd, ksyms[i]);
+@@ -668,7 +668,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
+ } else {
+ kernel_syms_load(&dd);
+ dd.nr_jited_ksyms = info->nr_jited_ksyms;
+- dd.jited_ksyms = (__u64 *) info->jited_ksyms;
++ dd.jited_ksyms = u64_to_ptr(info->jited_ksyms);
+ dd.btf = btf;
+ dd.func_info = func_info;
+ dd.finfo_rec_size = info->func_info_rec_size;
+@@ -1790,7 +1790,7 @@ static char *profile_target_name(int tgt_fd)
+ goto out;
+ }
+
+- func_info = (struct bpf_func_info *)(info_linear->info.func_info);
++ func_info = u64_to_ptr(info_linear->info.func_info);
+ t = btf__type_by_id(btf, func_info[0].type_id);
+ if (!t) {
+ p_err("btf %d doesn't have type %d",
+--
+2.25.1
+
--- /dev/null
+From e52b31b3452089a46d44dd122db1a94d6e72b415 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 14 Aug 2020 07:55:01 +0200
+Subject: usb: gadget: f_tcm: Fix some resource leaks in some error paths
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 07c8434150f4eb0b65cae288721c8af1080fde17 ]
+
+If a memory allocation fails within a 'usb_ep_alloc_request()' call, the
+already allocated memory must be released.
+
+Fix a mix-up in the code and free the correct requests.
+
+Fixes: c52661d60f63 ("usb-gadget: Initial merge of target module for UASP + BOT")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Felipe Balbi <balbi@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_tcm.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
+index eaf556ceac32b..0a45b4ef66a67 100644
+--- a/drivers/usb/gadget/function/f_tcm.c
++++ b/drivers/usb/gadget/function/f_tcm.c
+@@ -753,12 +753,13 @@ static int uasp_alloc_stream_res(struct f_uas *fu, struct uas_stream *stream)
+ goto err_sts;
+
+ return 0;
++
+ err_sts:
+- usb_ep_free_request(fu->ep_status, stream->req_status);
+- stream->req_status = NULL;
+-err_out:
+ usb_ep_free_request(fu->ep_out, stream->req_out);
+ stream->req_out = NULL;
++err_out:
++ usb_ep_free_request(fu->ep_in, stream->req_in);
++ stream->req_in = NULL;
+ out:
+ return -ENOMEM;
+ }
+--
+2.25.1
+
--- /dev/null
+From 186f88dfc78aa59ea780f924c97f925f675831c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2020 17:12:54 +0800
+Subject: vdpa: ifcvf: free config irq in ifcvf_free_irq()
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 2b9f28d5e8efad34f472542315911c5ee9a65b6c ]
+
+We don't free config irq in ifcvf_free_irq() which will trigger a
+BUG() in pci core since we try to free the vectors that has an
+action. Fixing this by recording the config irq in ifcvf_hw structure
+and free it in ifcvf_free_irq().
+
+Fixes: e7991f376a4d ("ifcvf: implement config interrupt in IFCVF")
+Cc: Zhu Lingshan <lingshan.zhu@intel.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Link: https://lore.kernel.org/r/20200723091254.20617-2-jasowang@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Zhu Lingshan <lingshan.zhu@intel.com>
+Fixes: e7991f376a4d ("ifcvf: implement config interrupt in IFCVF")
+Cc: Zhu Lingshan <a class="moz-txt-link-rfc2396E" href="mailto:lingshan.zhu@intel.com"><lingshan.zhu@intel.com></a>
+Signed-off-by: Jason Wang <a class="moz-txt-link-rfc2396E" href="mailto:jasowang@redhat.com"><jasowang@redhat.com></a>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vdpa/ifcvf/ifcvf_base.h | 2 +-
+ drivers/vdpa/ifcvf/ifcvf_main.c | 5 +++--
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/vdpa/ifcvf/ifcvf_base.h b/drivers/vdpa/ifcvf/ifcvf_base.h
+index f4554412e607f..29efa75cdfce5 100644
+--- a/drivers/vdpa/ifcvf/ifcvf_base.h
++++ b/drivers/vdpa/ifcvf/ifcvf_base.h
+@@ -84,7 +84,7 @@ struct ifcvf_hw {
+ void __iomem * const *base;
+ char config_msix_name[256];
+ struct vdpa_callback config_cb;
+-
++ unsigned int config_irq;
+ };
+
+ struct ifcvf_adapter {
+diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
+index ae7110955a44d..7a6d899e541df 100644
+--- a/drivers/vdpa/ifcvf/ifcvf_main.c
++++ b/drivers/vdpa/ifcvf/ifcvf_main.c
+@@ -53,6 +53,7 @@ static void ifcvf_free_irq(struct ifcvf_adapter *adapter, int queues)
+ for (i = 0; i < queues; i++)
+ devm_free_irq(&pdev->dev, vf->vring[i].irq, &vf->vring[i]);
+
++ devm_free_irq(&pdev->dev, vf->config_irq, vf);
+ ifcvf_free_irq_vectors(pdev);
+ }
+
+@@ -72,8 +73,8 @@ static int ifcvf_request_irq(struct ifcvf_adapter *adapter)
+ snprintf(vf->config_msix_name, 256, "ifcvf[%s]-config\n",
+ pci_name(pdev));
+ vector = 0;
+- irq = pci_irq_vector(pdev, vector);
+- ret = devm_request_irq(&pdev->dev, irq,
++ vf->config_irq = pci_irq_vector(pdev, vector);
++ ret = devm_request_irq(&pdev->dev, vf->config_irq,
+ ifcvf_config_changed, 0,
+ vf->config_msix_name, vf);
+ if (ret) {
+--
+2.25.1
+
--- /dev/null
+From f6f69751ab79b5e5ab3d362998964979fdd22233 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Jul 2020 17:12:53 +0800
+Subject: vdpa: ifcvf: return err when fail to request config irq
+
+From: Jason Wang <jasowang@redhat.com>
+
+[ Upstream commit 9f4ce5d72b8e7a1f750598407c99f9e39dfb12fc ]
+
+We ignore the err of requesting config interrupt, fix this.
+
+Fixes: e7991f376a4d ("ifcvf: implement config interrupt in IFCVF")
+Cc: Zhu Lingshan <lingshan.zhu@intel.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Link: https://lore.kernel.org/r/20200723091254.20617-1-jasowang@redhat.com
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Zhu Lingshan <lingshan.zhu@intel.com>
+Fixes: e7991f376a4d ("ifcvf: implement config interrupt in IFCVF")
+Cc: Zhu Lingshan <a class="moz-txt-link-rfc2396E" href="mailto:lingshan.zhu@intel.com"><lingshan.zhu@intel.com></a>
+Signed-off-by: Jason Wang <a class="moz-txt-link-rfc2396E" href="mailto:jasowang@redhat.com"><jasowang@redhat.com></a>
+Tested-by: Maxime Coquelin <maxime.coquelin@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vdpa/ifcvf/ifcvf_main.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
+index f5a60c14b9799..ae7110955a44d 100644
+--- a/drivers/vdpa/ifcvf/ifcvf_main.c
++++ b/drivers/vdpa/ifcvf/ifcvf_main.c
+@@ -76,6 +76,10 @@ static int ifcvf_request_irq(struct ifcvf_adapter *adapter)
+ ret = devm_request_irq(&pdev->dev, irq,
+ ifcvf_config_changed, 0,
+ vf->config_msix_name, vf);
++ if (ret) {
++ IFCVF_ERR(pdev, "Failed to request config irq\n");
++ return ret;
++ }
+
+ for (i = 0; i < IFCVF_MAX_QUEUE_PAIRS * 2; i++) {
+ snprintf(vf->vring[i].msix_name, 256, "ifcvf[%s]-%d\n",
+--
+2.25.1
+
--- /dev/null
+From 3926a37877f179f9d703989839aa8b07a7eaef12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 21 Aug 2020 20:49:10 +1000
+Subject: video: fbdev: controlfb: Fix build for COMPILE_TEST=y && PPC_PMAC=n
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+[ Upstream commit 4d618b9f3fcab84e9ec28c180de46fb2c929d096 ]
+
+The build is currently broken, if COMPILE_TEST=y and PPC_PMAC=n:
+
+ linux/drivers/video/fbdev/controlfb.c: In function ‘control_set_hardware’:
+ linux/drivers/video/fbdev/controlfb.c:276:2: error: implicit declaration of function ‘btext_update_display’
+ 276 | btext_update_display(p->frame_buffer_phys + CTRLFB_OFF,
+ | ^~~~~~~~~~~~~~~~~~~~
+
+Fix it by including btext.h whenever CONFIG_BOOTX_TEXT is enabled.
+
+Fixes: a07a63b0e24d ("video: fbdev: controlfb: add COMPILE_TEST support")
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+Link: https://lore.kernel.org/r/20200821104910.3363818-1-mpe@ellerman.id.au
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/video/fbdev/controlfb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c
+index 9c4f1be856eca..547abeb39f87a 100644
+--- a/drivers/video/fbdev/controlfb.c
++++ b/drivers/video/fbdev/controlfb.c
+@@ -49,6 +49,8 @@
+ #include <linux/cuda.h>
+ #ifdef CONFIG_PPC_PMAC
+ #include <asm/prom.h>
++#endif
++#ifdef CONFIG_BOOTX_TEXT
+ #include <asm/btext.h>
+ #endif
+
+--
+2.25.1
+