--- /dev/null
+From b12de52896c0e8213f70e3a168fde9e6eee95909 Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Fri, 15 Nov 2019 10:09:00 +0800
+Subject: btrfs: scrub: Don't check free space before marking a block group RO
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit b12de52896c0e8213f70e3a168fde9e6eee95909 upstream.
+
+[BUG]
+When running btrfs/072 with only one online CPU, it has a pretty high
+chance to fail:
+
+# btrfs/072 12s ... _check_dmesg: something found in dmesg (see xfstests-dev/results//btrfs/072.dmesg)
+# - output mismatch (see xfstests-dev/results//btrfs/072.out.bad)
+# --- tests/btrfs/072.out 2019-10-22 15:18:14.008965340 +0800
+# +++ /xfstests-dev/results//btrfs/072.out.bad 2019-11-14 15:56:45.877152240 +0800
+# @@ -1,2 +1,3 @@
+# QA output created by 072
+# Silence is golden
+# +Scrub find errors in "-m dup -d single" test
+# ...
+
+And with the following call trace:
+
+ BTRFS info (device dm-5): scrub: started on devid 1
+ ------------[ cut here ]------------
+ BTRFS: Transaction aborted (error -27)
+ WARNING: CPU: 0 PID: 55087 at fs/btrfs/block-group.c:1890 btrfs_create_pending_block_groups+0x3e6/0x470 [btrfs]
+ CPU: 0 PID: 55087 Comm: btrfs Tainted: G W O 5.4.0-rc1-custom+ #13
+ Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
+ RIP: 0010:btrfs_create_pending_block_groups+0x3e6/0x470 [btrfs]
+ Call Trace:
+ __btrfs_end_transaction+0xdb/0x310 [btrfs]
+ btrfs_end_transaction+0x10/0x20 [btrfs]
+ btrfs_inc_block_group_ro+0x1c9/0x210 [btrfs]
+ scrub_enumerate_chunks+0x264/0x940 [btrfs]
+ btrfs_scrub_dev+0x45c/0x8f0 [btrfs]
+ btrfs_ioctl+0x31a1/0x3fb0 [btrfs]
+ do_vfs_ioctl+0x636/0xaa0
+ ksys_ioctl+0x67/0x90
+ __x64_sys_ioctl+0x43/0x50
+ do_syscall_64+0x79/0xe0
+ entry_SYSCALL_64_after_hwframe+0x49/0xbe
+ ---[ end trace 166c865cec7688e7 ]---
+
+[CAUSE]
+The error number -27 is -EFBIG, returned from the following call chain:
+btrfs_end_transaction()
+|- __btrfs_end_transaction()
+ |- btrfs_create_pending_block_groups()
+ |- btrfs_finish_chunk_alloc()
+ |- btrfs_add_system_chunk()
+
+This happens because we have used up all space of
+btrfs_super_block::sys_chunk_array.
+
+The root cause is, we have the following bad loop of creating tons of
+system chunks:
+
+1. The only SYSTEM chunk is being scrubbed
+ It's very common to have only one SYSTEM chunk.
+2. New SYSTEM bg will be allocated
+ As btrfs_inc_block_group_ro() will check if we have enough space
+ after marking current bg RO. If not, then allocate a new chunk.
+3. New SYSTEM bg is still empty, will be reclaimed
+ During the reclaim, we will mark it RO again.
+4. That newly allocated empty SYSTEM bg get scrubbed
+ We go back to step 2, as the bg is already mark RO but still not
+ cleaned up yet.
+
+If the cleaner kthread doesn't get executed fast enough (e.g. only one
+CPU), then we will get more and more empty SYSTEM chunks, using up all
+the space of btrfs_super_block::sys_chunk_array.
+
+[FIX]
+Since scrub/dev-replace doesn't always need to allocate new extent,
+especially chunk tree extent, so we don't really need to do chunk
+pre-allocation.
+
+To break above spiral, here we introduce a new parameter to
+btrfs_inc_block_group(), @do_chunk_alloc, which indicates whether we
+need extra chunk pre-allocation.
+
+For relocation, we pass @do_chunk_alloc=true, while for scrub, we pass
+@do_chunk_alloc=false.
+This should keep unnecessary empty chunks from popping up for scrub.
+
+Also, since there are two parameters for btrfs_inc_block_group_ro(),
+add more comment for it.
+
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/block-group.c | 48 +++++++++++++++++++++++++++++++-----------------
+ fs/btrfs/block-group.h | 3 ++-
+ fs/btrfs/relocation.c | 2 +-
+ fs/btrfs/scrub.c | 21 ++++++++++++++++++++-
+ 4 files changed, 54 insertions(+), 20 deletions(-)
+
+--- a/fs/btrfs/block-group.c
++++ b/fs/btrfs/block-group.c
+@@ -2048,8 +2048,17 @@ static u64 update_block_group_flags(stru
+ return flags;
+ }
+
+-int btrfs_inc_block_group_ro(struct btrfs_block_group_cache *cache)
+-
++/*
++ * Mark one block group RO, can be called several times for the same block
++ * group.
++ *
++ * @cache: the destination block group
++ * @do_chunk_alloc: whether need to do chunk pre-allocation, this is to
++ * ensure we still have some free space after marking this
++ * block group RO.
++ */
++int btrfs_inc_block_group_ro(struct btrfs_block_group_cache *cache,
++ bool do_chunk_alloc)
+ {
+ struct btrfs_fs_info *fs_info = cache->fs_info;
+ struct btrfs_trans_handle *trans;
+@@ -2079,25 +2088,29 @@ again:
+ goto again;
+ }
+
+- /*
+- * if we are changing raid levels, try to allocate a corresponding
+- * block group with the new raid level.
+- */
+- alloc_flags = update_block_group_flags(fs_info, cache->flags);
+- if (alloc_flags != cache->flags) {
+- ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE);
++ if (do_chunk_alloc) {
+ /*
+- * ENOSPC is allowed here, we may have enough space
+- * already allocated at the new raid level to
+- * carry on
++ * If we are changing raid levels, try to allocate a
++ * corresponding block group with the new raid level.
+ */
+- if (ret == -ENOSPC)
+- ret = 0;
+- if (ret < 0)
+- goto out;
++ alloc_flags = update_block_group_flags(fs_info, cache->flags);
++ if (alloc_flags != cache->flags) {
++ ret = btrfs_chunk_alloc(trans, alloc_flags,
++ CHUNK_ALLOC_FORCE);
++ /*
++ * ENOSPC is allowed here, we may have enough space
++ * already allocated at the new raid level to carry on
++ */
++ if (ret == -ENOSPC)
++ ret = 0;
++ if (ret < 0)
++ goto out;
++ }
+ }
+
+- ret = inc_block_group_ro(cache, 0);
++ ret = inc_block_group_ro(cache, !do_chunk_alloc);
++ if (!do_chunk_alloc)
++ goto unlock_out;
+ if (!ret)
+ goto out;
+ alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags);
+@@ -2112,6 +2125,7 @@ out:
+ check_system_chunk(trans, alloc_flags);
+ mutex_unlock(&fs_info->chunk_mutex);
+ }
++unlock_out:
+ mutex_unlock(&fs_info->ro_block_group_mutex);
+
+ btrfs_end_transaction(trans);
+--- a/fs/btrfs/block-group.h
++++ b/fs/btrfs/block-group.h
+@@ -205,7 +205,8 @@ int btrfs_read_block_groups(struct btrfs
+ int btrfs_make_block_group(struct btrfs_trans_handle *trans, u64 bytes_used,
+ u64 type, u64 chunk_offset, u64 size);
+ void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans);
+-int btrfs_inc_block_group_ro(struct btrfs_block_group_cache *cache);
++int btrfs_inc_block_group_ro(struct btrfs_block_group_cache *cache,
++ bool do_chunk_alloc);
+ void btrfs_dec_block_group_ro(struct btrfs_block_group_cache *cache);
+ int btrfs_start_dirty_block_groups(struct btrfs_trans_handle *trans);
+ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans);
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -4428,7 +4428,7 @@ int btrfs_relocate_block_group(struct bt
+ rc->extent_root = extent_root;
+ rc->block_group = bg;
+
+- ret = btrfs_inc_block_group_ro(rc->block_group);
++ ret = btrfs_inc_block_group_ro(rc->block_group, true);
+ if (ret) {
+ err = ret;
+ goto out;
+--- a/fs/btrfs/scrub.c
++++ b/fs/btrfs/scrub.c
+@@ -3560,7 +3560,26 @@ int scrub_enumerate_chunks(struct scrub_
+ * -> btrfs_scrub_pause()
+ */
+ scrub_pause_on(fs_info);
+- ret = btrfs_inc_block_group_ro(cache);
++
++ /*
++ * Don't do chunk preallocation for scrub.
++ *
++ * This is especially important for SYSTEM bgs, or we can hit
++ * -EFBIG from btrfs_finish_chunk_alloc() like:
++ * 1. The only SYSTEM bg is marked RO.
++ * Since SYSTEM bg is small, that's pretty common.
++ * 2. New SYSTEM bg will be allocated
++ * Due to regular version will allocate new chunk.
++ * 3. New SYSTEM bg is empty and will get cleaned up
++ * Before cleanup really happens, it's marked RO again.
++ * 4. Empty SYSTEM bg get scrubbed
++ * We go back to 2.
++ *
++ * This can easily boost the amount of SYSTEM chunks if cleaner
++ * thread can't be triggered fast enough, and use up all space
++ * of btrfs_super_block::sys_chunk_array
++ */
++ ret = btrfs_inc_block_group_ro(cache, false);
+ if (!ret && sctx->is_dev_replace) {
+ /*
+ * If we are doing a device replace wait for any tasks
--- /dev/null
+From foo@baz Fri Mar 19 10:39:38 AM CET 2021
+From: Colin Xu <colin.xu@intel.com>
+Date: Wed, 17 Mar 2021 10:55:01 +0800
+Subject: drm/i915/gvt: Fix mmio handler break on BXT/APL.
+To: stable@vger.kernel.org
+Cc: intel-gvt-dev@lists.freedesktop.org, zhenyuw@linux.intel.com, colin.xu@intel.com
+Message-ID: <71b10da4af9e8be3b38b99382e164dd4e83fdf27.1615946755.git.colin.xu@intel.com>
+
+From: Colin Xu <colin.xu@intel.com>
+
+commit 92010a97098c4c9fd777408cc98064d26b32695b upstream
+
+- Remove dup mmio handler for BXT/APL. Otherwise mmio handler will fail
+ to init.
+- Add engine GPR with F_CMD_ACCESS since BXT/APL will load them via
+ LRI. Otherwise, guest will enter failsafe mode.
+
+V2:
+Use RCS/BCS GPR macros instead of offset.
+Revise commit message.
+
+V3:
+Use GEN8_RING_CS_GPR macros on ring base.
+
+Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20201016052913.209248-1-colin.xu@intel.com
+(cherry picked from commit 92010a97098c4c9fd777408cc98064d26b32695b)
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Cc: <stable@vger.kernel.org> # 5.4.y
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gvt/handlers.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/gvt/handlers.c
++++ b/drivers/gpu/drm/i915/gvt/handlers.c
+@@ -3132,7 +3132,7 @@ static int init_skl_mmio_info(struct int
+ NULL, NULL);
+
+ MMIO_D(GAMT_CHKN_BIT_REG, D_KBL | D_CFL);
+- MMIO_D(GEN9_CTX_PREEMPT_REG, D_SKL_PLUS);
++ MMIO_D(GEN9_CTX_PREEMPT_REG, D_SKL_PLUS & ~D_BXT);
+
+ return 0;
+ }
+@@ -3306,6 +3306,12 @@ static int init_bxt_mmio_info(struct int
+ MMIO_D(GEN8_PUSHBUS_SHIFT, D_BXT);
+ MMIO_D(GEN6_GFXPAUSE, D_BXT);
+ MMIO_DFH(GEN8_L3SQCREG1, D_BXT, F_CMD_ACCESS, NULL, NULL);
++ MMIO_DFH(GEN8_L3CNTLREG, D_BXT, F_CMD_ACCESS, NULL, NULL);
++ MMIO_DFH(_MMIO(0x20D8), D_BXT, F_CMD_ACCESS, NULL, NULL);
++ MMIO_F(HSW_CS_GPR(0), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL);
++ MMIO_F(_MMIO(0x12600), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL);
++ MMIO_F(BCS_GPR(0), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL);
++ MMIO_F(_MMIO(0x1a600), 0x40, F_CMD_ACCESS, 0, 0, D_BXT, NULL, NULL);
+
+ MMIO_DFH(GEN9_CTX_PREEMPT_REG, D_BXT, F_CMD_ACCESS, NULL, NULL);
+
--- /dev/null
+From foo@baz Fri Mar 19 10:39:38 AM CET 2021
+From: Colin Xu <colin.xu@intel.com>
+Date: Wed, 17 Mar 2021 10:55:03 +0800
+Subject: drm/i915/gvt: Fix port number for BDW on EDID region setup
+To: stable@vger.kernel.org
+Cc: intel-gvt-dev@lists.freedesktop.org, zhenyuw@linux.intel.com, colin.xu@intel.com
+Message-ID: <ef9ce56bfd3bee8b68063503d12b1d5d3535536e.1615946755.git.colin.xu@intel.com>
+
+From: Colin Xu <colin.xu@intel.com>
+
+From: Zhenyu Wang <zhenyuw@linux.intel.com>
+
+commit 28284943ac94014767ecc2f7b3c5747c4a5617a0 upstream
+
+Current BDW virtual display port is initialized as PORT_B, so need
+to use same port for VFIO EDID region, otherwise invalid EDID blob
+pointer is assigned which caused kernel null pointer reference. We
+might evaluate actual display hotplug for BDW to make this function
+work as expected, anyway this is always required to be fixed first.
+
+Reported-by: Alejandro Sior <aho@sior.be>
+Cc: Alejandro Sior <aho@sior.be>
+Fixes: 0178f4ce3c3b ("drm/i915/gvt: Enable vfio edid for all GVT supported platform")
+Reviewed-by: Hang Yuan <hang.yuan@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20200914030302.2775505-1-zhenyuw@linux.intel.com
+(cherry picked from commit 28284943ac94014767ecc2f7b3c5747c4a5617a0)
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Cc: <stable@vger.kernel.org> # 5.4.y
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gvt/vgpu.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/gpu/drm/i915/gvt/vgpu.c
++++ b/drivers/gpu/drm/i915/gvt/vgpu.c
+@@ -432,8 +432,9 @@ static struct intel_vgpu *__intel_gvt_cr
+ if (ret)
+ goto out_clean_sched_policy;
+
+- /*TODO: add more platforms support */
+- if (IS_SKYLAKE(gvt->dev_priv) || IS_KABYLAKE(gvt->dev_priv))
++ if (IS_BROADWELL(gvt->dev_priv))
++ ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B);
++ else
+ ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D);
+ if (ret)
+ goto out_clean_sched_policy;
--- /dev/null
+From foo@baz Fri Mar 19 10:39:38 AM CET 2021
+From: Colin Xu <colin.xu@intel.com>
+Date: Wed, 17 Mar 2021 10:55:04 +0800
+Subject: drm/i915/gvt: Fix vfio_edid issue for BXT/APL
+To: stable@vger.kernel.org
+Cc: intel-gvt-dev@lists.freedesktop.org, zhenyuw@linux.intel.com, colin.xu@intel.com
+Message-ID: <982acc6579f652db9ed67f042453c302055b0692.1615946755.git.colin.xu@intel.com>
+
+From: Colin Xu <colin.xu@intel.com>
+
+commit 4ceb06e7c336f4a8d3f3b6ac9a4fea2e9c97dc07 upstream
+
+BXT/APL has different isr/irr/hpd regs compared with other GEN9. If not
+setting these regs bits correctly according to the emulated monitor
+(currently a DP on PORT_B), although gvt still triggers a virtual HPD
+event, the guest driver won't detect a valid HPD pulse thus no full
+display detection will be executed to read the updated EDID.
+
+With this patch, the vfio_edid is enabled again on BXT/APL, which is
+previously disabled.
+
+Fixes: 642403e3599e ("drm/i915/gvt: Temporarily disable vfio_edid for BXT/APL")
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20201201060329.142375-1-colin.xu@intel.com
+Reviewed-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+(cherry picked from commit 4ceb06e7c336f4a8d3f3b6ac9a4fea2e9c97dc07)
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Cc: <stable@vger.kernel.org> # 5.4.y
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gvt/display.c | 83 +++++++++++++++++++++++++++----------
+ drivers/gpu/drm/i915/gvt/vgpu.c | 2
+ 2 files changed, 62 insertions(+), 23 deletions(-)
+
+--- a/drivers/gpu/drm/i915/gvt/display.c
++++ b/drivers/gpu/drm/i915/gvt/display.c
+@@ -215,6 +215,15 @@ static void emulate_monitor_status_chang
+ DDI_BUF_CTL_ENABLE);
+ vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE;
+ }
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~(PORTA_HOTPLUG_ENABLE | PORTA_HOTPLUG_STATUS_MASK);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~(PORTB_HOTPLUG_ENABLE | PORTB_HOTPLUG_STATUS_MASK);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~(PORTC_HOTPLUG_ENABLE | PORTC_HOTPLUG_STATUS_MASK);
++ /* No hpd_invert set in vgpu vbt, need to clear invert mask */
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &= ~BXT_DDI_HPD_INVERT_MASK;
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HOTPLUG_MASK;
+
+ vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1));
+ vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
+@@ -271,6 +280,8 @@ static void emulate_monitor_status_chang
+ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |=
+ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
+ TRANS_DDI_FUNC_ENABLE);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTA_HOTPLUG_ENABLE;
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIA;
+ }
+@@ -299,6 +310,8 @@ static void emulate_monitor_status_chang
+ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
+ (PORT_B << TRANS_DDI_PORT_SHIFT) |
+ TRANS_DDI_FUNC_ENABLE);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTB_HOTPLUG_ENABLE;
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIB;
+ }
+@@ -327,6 +340,8 @@ static void emulate_monitor_status_chang
+ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
+ (PORT_B << TRANS_DDI_PORT_SHIFT) |
+ TRANS_DDI_FUNC_ENABLE);
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTC_HOTPLUG_ENABLE;
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIC;
+ }
+@@ -652,38 +667,62 @@ void intel_vgpu_emulate_hotplug(struct i
+ PORTD_HOTPLUG_STATUS_MASK;
+ intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG);
+ } else if (IS_BROXTON(dev_priv)) {
+- if (connected) {
+- if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
+- vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIA;
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
++ if (connected) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
++ BXT_DE_PORT_HP_DDIA;
++ } else {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
++ ~BXT_DE_PORT_HP_DDIA;
+ }
+- if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
++ BXT_DE_PORT_HP_DDIA;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~PORTA_HOTPLUG_STATUS_MASK;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTA_HOTPLUG_LONG_DETECT;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_A_HOTPLUG);
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
++ if (connected) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
++ BXT_DE_PORT_HP_DDIB;
+ vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
+ SFUSE_STRAP_DDIB_DETECTED;
+- vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIB;
+- }
+- if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
+- vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
+- SFUSE_STRAP_DDIC_DETECTED;
+- vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIC;
+- }
+- } else {
+- if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
+- vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HP_DDIA;
+- }
+- if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
++ } else {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
++ ~BXT_DE_PORT_HP_DDIB;
+ vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
+ ~SFUSE_STRAP_DDIB_DETECTED;
+- vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HP_DDIB;
+ }
+- if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
++ BXT_DE_PORT_HP_DDIB;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~PORTB_HOTPLUG_STATUS_MASK;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTB_HOTPLUG_LONG_DETECT;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
++ if (connected) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
++ BXT_DE_PORT_HP_DDIC;
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
++ SFUSE_STRAP_DDIC_DETECTED;
++ } else {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &=
++ ~BXT_DE_PORT_HP_DDIC;
+ vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
+ ~SFUSE_STRAP_DDIC_DETECTED;
+- vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HP_DDIC;
+ }
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_IIR) |=
++ BXT_DE_PORT_HP_DDIC;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) &=
++ ~PORTC_HOTPLUG_STATUS_MASK;
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTC_HOTPLUG_LONG_DETECT;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_C_HOTPLUG);
+ }
+- vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
+- PORTB_HOTPLUG_STATUS_MASK;
+- intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
+ }
+ }
+
+--- a/drivers/gpu/drm/i915/gvt/vgpu.c
++++ b/drivers/gpu/drm/i915/gvt/vgpu.c
+@@ -432,7 +432,7 @@ static struct intel_vgpu *__intel_gvt_cr
+ if (ret)
+ goto out_clean_sched_policy;
+
+- if (IS_BROADWELL(gvt->dev_priv))
++ if (IS_BROADWELL(gvt->dev_priv) || IS_BROXTON(gvt->dev_priv))
+ ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_B);
+ else
+ ret = intel_gvt_hypervisor_set_edid(vgpu, PORT_D);
--- /dev/null
+From foo@baz Fri Mar 19 10:39:38 AM CET 2021
+From: Colin Xu <colin.xu@intel.com>
+Date: Wed, 17 Mar 2021 10:55:02 +0800
+Subject: drm/i915/gvt: Fix virtual display setup for BXT/APL
+To: stable@vger.kernel.org
+Cc: intel-gvt-dev@lists.freedesktop.org, zhenyuw@linux.intel.com, colin.xu@intel.com
+Message-ID: <280168619124c762cb29add7e68952222a0e4801.1615946755.git.colin.xu@intel.com>
+
+From: Colin Xu <colin.xu@intel.com>
+
+commit a5a8ef937cfa79167f4b2a5602092b8d14fd6b9a upstream
+
+Program display related vregs to proper value at initialization, setup
+virtual monitor and hotplug.
+
+vGPU virtual display vregs inherit the value from pregs. The virtual DP
+monitor is always setup on PORT_B for BXT/APL. However the host may
+connect monitor on other PORT or without any monitor connected. Without
+properly setup PIPE/DDI/PLL related vregs, guest driver may not setup
+the virutal display as expected, and the guest desktop may not be
+created.
+Since only one virtual display is supported, enable PIPE_A only. And
+enable transcoder/DDI/PLL based on which port is setup for BXT/APL.
+
+V2:
+Revise commit message.
+
+V3:
+set_edid should on PORT_B for BXT.
+Inject hpd event for BXT.
+
+V4:
+Temporarily disable vfio edid on BXT/APL until issue fixed.
+
+V5:
+Rebase to use new HPD define GEN8_DE_PORT_HOTPLUG for BXT.
+Put vfio edid disabling on BXT/APL to a separate patch.
+
+Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20201109073922.757759-1-colin.xu@intel.com
+(cherry picked from commit a5a8ef937cfa79167f4b2a5602092b8d14fd6b9a)
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Cc: <stable@vger.kernel.org> # 5.4.y
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gvt/display.c | 173 +++++++++++++++++++++++++++++++++++++
+ drivers/gpu/drm/i915/gvt/mmio.c | 5 +
+ 2 files changed, 178 insertions(+)
+
+--- a/drivers/gpu/drm/i915/gvt/display.c
++++ b/drivers/gpu/drm/i915/gvt/display.c
+@@ -172,21 +172,161 @@ static void emulate_monitor_status_chang
+ int pipe;
+
+ if (IS_BROXTON(dev_priv)) {
++ enum transcoder trans;
++ enum port port;
++
++ /* Clear PIPE, DDI, PHY, HPD before setting new */
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~(BXT_DE_PORT_HP_DDIA |
+ BXT_DE_PORT_HP_DDIB |
+ BXT_DE_PORT_HP_DDIC);
+
++ for_each_pipe(dev_priv, pipe) {
++ vgpu_vreg_t(vgpu, PIPECONF(pipe)) &=
++ ~(PIPECONF_ENABLE | I965_PIPECONF_ACTIVE);
++ vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
++ vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
++ vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~MCURSOR_MODE;
++ vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= MCURSOR_MODE_DISABLE;
++ }
++
++ for (trans = TRANSCODER_A; trans <= TRANSCODER_EDP; trans++) {
++ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(trans)) &=
++ ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
++ TRANS_DDI_PORT_MASK | TRANS_DDI_FUNC_ENABLE);
++ }
++ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) &=
++ ~(TRANS_DDI_BPC_MASK | TRANS_DDI_MODE_SELECT_MASK |
++ TRANS_DDI_PORT_MASK);
++
++ for (port = PORT_A; port <= PORT_C; port++) {
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) &=
++ ~BXT_PHY_LANE_ENABLED;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(port)) |=
++ (BXT_PHY_CMNLANE_POWERDOWN_ACK |
++ BXT_PHY_LANE_POWERDOWN_ACK);
++
++ vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(port)) &=
++ ~(PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
++ PORT_PLL_REF_SEL | PORT_PLL_LOCK |
++ PORT_PLL_ENABLE);
++
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) &=
++ ~(DDI_INIT_DISPLAY_DETECTED |
++ DDI_BUF_CTL_ENABLE);
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(port)) |= DDI_BUF_IS_IDLE;
++ }
++
++ vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) &= ~(BIT(0) | BIT(1));
++ vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) &=
++ ~PHY_POWER_GOOD;
++ vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) &=
++ ~PHY_POWER_GOOD;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) &= ~BIT(30);
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) &= ~BIT(30);
++
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIB_DETECTED;
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) &= ~SFUSE_STRAP_DDIC_DETECTED;
++
++ /*
++ * Only 1 PIPE enabled in current vGPU display and PIPE_A is
++ * tied to TRANSCODER_A in HW, so it's safe to assume PIPE_A,
++ * TRANSCODER_A can be enabled. PORT_x depends on the input of
++ * setup_virtual_dp_monitor.
++ */
++ vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
++ vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= I965_PIPECONF_ACTIVE;
++
++ /*
++ * Golden M/N are calculated based on:
++ * 24 bpp, 4 lanes, 154000 pixel clk (from virtual EDID),
++ * DP link clk 1620 MHz and non-constant_n.
++ * TODO: calculate DP link symbol clk and stream clk m/n.
++ */
++ vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) = 63 << TU_SIZE_SHIFT;
++ vgpu_vreg_t(vgpu, PIPE_DATA_M1(TRANSCODER_A)) |= 0x5b425e;
++ vgpu_vreg_t(vgpu, PIPE_DATA_N1(TRANSCODER_A)) = 0x800000;
++ vgpu_vreg_t(vgpu, PIPE_LINK_M1(TRANSCODER_A)) = 0x3cd6e;
++ vgpu_vreg_t(vgpu, PIPE_LINK_N1(TRANSCODER_A)) = 0x80000;
++
++ /* Enable per-DDI/PORT vreg */
+ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
++ vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(1);
++ vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY1)) |=
++ PHY_POWER_GOOD;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY1)) |=
++ BIT(30);
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) |=
++ BXT_PHY_LANE_ENABLED;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_A)) &=
++ ~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
++ BXT_PHY_LANE_POWERDOWN_ACK);
++ vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_A)) |=
++ (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
++ PORT_PLL_REF_SEL | PORT_PLL_LOCK |
++ PORT_PLL_ENABLE);
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) |=
++ (DDI_BUF_CTL_ENABLE | DDI_INIT_DISPLAY_DETECTED);
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_A)) &=
++ ~DDI_BUF_IS_IDLE;
++ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)) |=
++ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
++ TRANS_DDI_FUNC_ENABLE);
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIA;
+ }
+
+ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
++ vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
++ vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
++ PHY_POWER_GOOD;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
++ BIT(30);
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) |=
++ BXT_PHY_LANE_ENABLED;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_B)) &=
++ ~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
++ BXT_PHY_LANE_POWERDOWN_ACK);
++ vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_B)) |=
++ (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
++ PORT_PLL_REF_SEL | PORT_PLL_LOCK |
++ PORT_PLL_ENABLE);
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) |=
++ DDI_BUF_CTL_ENABLE;
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_B)) &=
++ ~DDI_BUF_IS_IDLE;
++ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
++ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
++ (PORT_B << TRANS_DDI_PORT_SHIFT) |
++ TRANS_DDI_FUNC_ENABLE);
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIB;
+ }
+
+ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
++ vgpu_vreg_t(vgpu, BXT_P_CR_GT_DISP_PWRON) |= BIT(0);
++ vgpu_vreg_t(vgpu, BXT_PORT_CL1CM_DW0(DPIO_PHY0)) |=
++ PHY_POWER_GOOD;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL_FAMILY(DPIO_PHY0)) |=
++ BIT(30);
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
++ BXT_PHY_LANE_ENABLED;
++ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) &=
++ ~(BXT_PHY_CMNLANE_POWERDOWN_ACK |
++ BXT_PHY_LANE_POWERDOWN_ACK);
++ vgpu_vreg_t(vgpu, BXT_PORT_PLL_ENABLE(PORT_C)) |=
++ (PORT_PLL_POWER_STATE | PORT_PLL_POWER_ENABLE |
++ PORT_PLL_REF_SEL | PORT_PLL_LOCK |
++ PORT_PLL_ENABLE);
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) |=
++ DDI_BUF_CTL_ENABLE;
++ vgpu_vreg_t(vgpu, DDI_BUF_CTL(PORT_C)) &=
++ ~DDI_BUF_IS_IDLE;
++ vgpu_vreg_t(vgpu, TRANS_DDI_FUNC_CTL(TRANSCODER_A)) |=
++ (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
++ (PORT_B << TRANS_DDI_PORT_SHIFT) |
++ TRANS_DDI_FUNC_ENABLE);
+ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |=
+ BXT_DE_PORT_HP_DDIC;
+ }
+@@ -511,6 +651,39 @@ void intel_vgpu_emulate_hotplug(struct i
+ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
+ PORTD_HOTPLUG_STATUS_MASK;
+ intel_vgpu_trigger_virtual_event(vgpu, DP_D_HOTPLUG);
++ } else if (IS_BROXTON(dev_priv)) {
++ if (connected) {
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIA;
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
++ SFUSE_STRAP_DDIB_DETECTED;
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIB;
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) |=
++ SFUSE_STRAP_DDIC_DETECTED;
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) |= BXT_DE_PORT_HP_DDIC;
++ }
++ } else {
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_A)) {
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HP_DDIA;
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
++ ~SFUSE_STRAP_DDIB_DETECTED;
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HP_DDIB;
++ }
++ if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
++ vgpu_vreg_t(vgpu, SFUSE_STRAP) &=
++ ~SFUSE_STRAP_DDIC_DETECTED;
++ vgpu_vreg_t(vgpu, GEN8_DE_PORT_ISR) &= ~BXT_DE_PORT_HP_DDIC;
++ }
++ }
++ vgpu_vreg_t(vgpu, PCH_PORT_HOTPLUG) |=
++ PORTB_HOTPLUG_STATUS_MASK;
++ intel_vgpu_trigger_virtual_event(vgpu, DP_B_HOTPLUG);
+ }
+ }
+
+--- a/drivers/gpu/drm/i915/gvt/mmio.c
++++ b/drivers/gpu/drm/i915/gvt/mmio.c
+@@ -271,6 +271,11 @@ void intel_vgpu_reset_mmio(struct intel_
+ vgpu_vreg_t(vgpu, BXT_PHY_CTL(PORT_C)) |=
+ BXT_PHY_CMNLANE_POWERDOWN_ACK |
+ BXT_PHY_LANE_POWERDOWN_ACK;
++ vgpu_vreg_t(vgpu, SKL_FUSE_STATUS) |=
++ SKL_FUSE_DOWNLOAD_STATUS |
++ SKL_FUSE_PG_DIST_STATUS(SKL_PG0) |
++ SKL_FUSE_PG_DIST_STATUS(SKL_PG1) |
++ SKL_FUSE_PG_DIST_STATUS(SKL_PG2);
+ }
+ } else {
+ #define GVT_GEN8_MMIO_RESET_OFFSET (0x44200)
--- /dev/null
+From foo@baz Fri Mar 19 10:39:38 AM CET 2021
+From: Colin Xu <colin.xu@intel.com>
+Date: Wed, 17 Mar 2021 10:55:00 +0800
+Subject: drm/i915/gvt: Set SNOOP for PAT3 on BXT/APL to workaround GPU BB hang
+To: stable@vger.kernel.org
+Cc: intel-gvt-dev@lists.freedesktop.org, zhenyuw@linux.intel.com, colin.xu@intel.com
+Message-ID: <cfc85d94d1d2005fba3e5813b0c4c2df080b8aed.1615946755.git.colin.xu@intel.com>
+
+From: Colin Xu <colin.xu@intel.com>
+
+commit 8fe105679765700378eb328495fcfe1566cdbbd0 upstream
+
+If guest fills non-priv bb on ApolloLake/Broxton as Mesa i965 does in:
+717e7539124d (i965: Use a WC map and memcpy for the batch instead of pw-)
+Due to the missing flush of bb filled by VM vCPU, host GPU hangs on
+executing these MI_BATCH_BUFFER.
+
+Temporarily workaround this by setting SNOOP bit for PAT3 used by PPGTT
+PML4 PTE: PAT(0) PCD(1) PWT(1).
+
+The performance is still expected to be low, will need further improvement.
+
+Acked-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
+Link: http://patchwork.freedesktop.org/patch/msgid/20201012045231.226748-1-colin.xu@intel.com
+(cherry picked from commit 8fe105679765700378eb328495fcfe1566cdbbd0)
+Signed-off-by: Colin Xu <colin.xu@intel.com>
+Cc: <stable@vger.kernel.org> # 5.4.y
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i915/gvt/handlers.c | 32 +++++++++++++++++++++++++++++++-
+ 1 file changed, 31 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i915/gvt/handlers.c
++++ b/drivers/gpu/drm/i915/gvt/handlers.c
+@@ -1632,6 +1632,34 @@ static int edp_psr_imr_iir_write(struct
+ return 0;
+ }
+
++/**
++ * FixMe:
++ * If guest fills non-priv batch buffer on ApolloLake/Broxton as Mesa i965 did:
++ * 717e7539124d (i965: Use a WC map and memcpy for the batch instead of pwrite.)
++ * Due to the missing flush of bb filled by VM vCPU, host GPU hangs on executing
++ * these MI_BATCH_BUFFER.
++ * Temporarily workaround this by setting SNOOP bit for PAT3 used by PPGTT
++ * PML4 PTE: PAT(0) PCD(1) PWT(1).
++ * The performance is still expected to be low, will need further improvement.
++ */
++static int bxt_ppat_low_write(struct intel_vgpu *vgpu, unsigned int offset,
++ void *p_data, unsigned int bytes)
++{
++ u64 pat =
++ GEN8_PPAT(0, CHV_PPAT_SNOOP) |
++ GEN8_PPAT(1, 0) |
++ GEN8_PPAT(2, 0) |
++ GEN8_PPAT(3, CHV_PPAT_SNOOP) |
++ GEN8_PPAT(4, CHV_PPAT_SNOOP) |
++ GEN8_PPAT(5, CHV_PPAT_SNOOP) |
++ GEN8_PPAT(6, CHV_PPAT_SNOOP) |
++ GEN8_PPAT(7, CHV_PPAT_SNOOP);
++
++ vgpu_vreg(vgpu, offset) = lower_32_bits(pat);
++
++ return 0;
++}
++
+ static int mmio_read_from_hw(struct intel_vgpu *vgpu,
+ unsigned int offset, void *p_data, unsigned int bytes)
+ {
+@@ -2778,7 +2806,7 @@ static int init_broadwell_mmio_info(stru
+
+ MMIO_DH(GEN6_PCODE_MAILBOX, D_BDW_PLUS, NULL, mailbox_write);
+
+- MMIO_D(GEN8_PRIVATE_PAT_LO, D_BDW_PLUS);
++ MMIO_D(GEN8_PRIVATE_PAT_LO, D_BDW_PLUS & ~D_BXT);
+ MMIO_D(GEN8_PRIVATE_PAT_HI, D_BDW_PLUS);
+
+ MMIO_D(GAMTARBMODE, D_BDW_PLUS);
+@@ -3281,6 +3309,8 @@ static int init_bxt_mmio_info(struct int
+
+ MMIO_DFH(GEN9_CTX_PREEMPT_REG, D_BXT, F_CMD_ACCESS, NULL, NULL);
+
++ MMIO_DH(GEN8_PRIVATE_PAT_LO, D_BXT, NULL, bxt_ppat_low_write);
++
+ return 0;
+ }
+
--- /dev/null
+From 775c5033a0d164622d9d10dd0f0a5531639ed3ed Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Thu, 4 Mar 2021 11:09:12 +0200
+Subject: fuse: fix live lock in fuse_iget()
+
+From: Amir Goldstein <amir73il@gmail.com>
+
+commit 775c5033a0d164622d9d10dd0f0a5531639ed3ed upstream.
+
+Commit 5d069dbe8aaf ("fuse: fix bad inode") replaced make_bad_inode()
+in fuse_iget() with a private implementation fuse_make_bad().
+
+The private implementation fails to remove the bad inode from inode
+cache, so the retry loop with iget5_locked() finds the same bad inode
+and marks it bad forever.
+
+kmsg snip:
+
+[ ] rcu: INFO: rcu_sched self-detected stall on CPU
+...
+[ ] ? bit_wait_io+0x50/0x50
+[ ] ? fuse_init_file_inode+0x70/0x70
+[ ] ? find_inode.isra.32+0x60/0xb0
+[ ] ? fuse_init_file_inode+0x70/0x70
+[ ] ilookup5_nowait+0x65/0x90
+[ ] ? fuse_init_file_inode+0x70/0x70
+[ ] ilookup5.part.36+0x2e/0x80
+[ ] ? fuse_init_file_inode+0x70/0x70
+[ ] ? fuse_inode_eq+0x20/0x20
+[ ] iget5_locked+0x21/0x80
+[ ] ? fuse_inode_eq+0x20/0x20
+[ ] fuse_iget+0x96/0x1b0
+
+Fixes: 5d069dbe8aaf ("fuse: fix bad inode")
+Cc: stable@vger.kernel.org # 5.10+
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/fuse_i.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -791,6 +791,7 @@ static inline u64 fuse_get_attr_version(
+
+ static inline void fuse_make_bad(struct inode *inode)
+ {
++ remove_inode_hash(inode);
+ set_bit(FUSE_I_BAD, &get_fuse_inode(inode)->state);
+ }
+
bpf-simplify-alu_limit-masking-for-pointer-arithmetic.patch
bpf-add-sanity-check-for-upper-ptr_limit.patch
bpf-selftests-fix-up-some-test_verifier-cases-for-unprivileged.patch
+btrfs-scrub-don-t-check-free-space-before-marking-a-block-group-ro.patch
+drm-i915-gvt-set-snoop-for-pat3-on-bxt-apl-to-workaround-gpu-bb-hang.patch
+drm-i915-gvt-fix-mmio-handler-break-on-bxt-apl.patch
+drm-i915-gvt-fix-virtual-display-setup-for-bxt-apl.patch
+drm-i915-gvt-fix-port-number-for-bdw-on-edid-region-setup.patch
+drm-i915-gvt-fix-vfio_edid-issue-for-bxt-apl.patch
+fuse-fix-live-lock-in-fuse_iget.patch