From: Greg Kroah-Hartman Date: Fri, 19 Mar 2021 09:52:34 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.19.182~15 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ee0786bbcfb9279dc7427ca0a7352ca8620a886b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: btrfs-scrub-don-t-check-free-space-before-marking-a-block-group-ro.patch drm-i915-gvt-fix-mmio-handler-break-on-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 drm-i915-gvt-fix-virtual-display-setup-for-bxt-apl.patch drm-i915-gvt-set-snoop-for-pat3-on-bxt-apl-to-workaround-gpu-bb-hang.patch fuse-fix-live-lock-in-fuse_iget.patch --- diff --git a/queue-5.4/btrfs-scrub-don-t-check-free-space-before-marking-a-block-group-ro.patch b/queue-5.4/btrfs-scrub-don-t-check-free-space-before-marking-a-block-group-ro.patch new file mode 100644 index 00000000000..4ef256b8264 --- /dev/null +++ b/queue-5.4/btrfs-scrub-don-t-check-free-space-before-marking-a-block-group-ro.patch @@ -0,0 +1,231 @@ +From b12de52896c0e8213f70e3a168fde9e6eee95909 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +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 + +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 +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Greg Kroah-Hartman + +--- + 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 diff --git a/queue-5.4/drm-i915-gvt-fix-mmio-handler-break-on-bxt-apl.patch b/queue-5.4/drm-i915-gvt-fix-mmio-handler-break-on-bxt-apl.patch new file mode 100644 index 00000000000..b8981e16f67 --- /dev/null +++ b/queue-5.4/drm-i915-gvt-fix-mmio-handler-break-on-bxt-apl.patch @@ -0,0 +1,60 @@ +From foo@baz Fri Mar 19 10:39:38 AM CET 2021 +From: Colin Xu +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 + +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 +Signed-off-by: Colin Xu +Signed-off-by: Zhenyu Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20201016052913.209248-1-colin.xu@intel.com +(cherry picked from commit 92010a97098c4c9fd777408cc98064d26b32695b) +Signed-off-by: Colin Xu +Cc: # 5.4.y +Signed-off-by: Greg Kroah-Hartman +--- + 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); + diff --git a/queue-5.4/drm-i915-gvt-fix-port-number-for-bdw-on-edid-region-setup.patch b/queue-5.4/drm-i915-gvt-fix-port-number-for-bdw-on-edid-region-setup.patch new file mode 100644 index 00000000000..355942fc3d9 --- /dev/null +++ b/queue-5.4/drm-i915-gvt-fix-port-number-for-bdw-on-edid-region-setup.patch @@ -0,0 +1,48 @@ +From foo@baz Fri Mar 19 10:39:38 AM CET 2021 +From: Colin Xu +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: + +From: Colin Xu + +From: Zhenyu Wang + +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 +Cc: Alejandro Sior +Fixes: 0178f4ce3c3b ("drm/i915/gvt: Enable vfio edid for all GVT supported platform") +Reviewed-by: Hang Yuan +Signed-off-by: Zhenyu Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20200914030302.2775505-1-zhenyuw@linux.intel.com +(cherry picked from commit 28284943ac94014767ecc2f7b3c5747c4a5617a0) +Signed-off-by: Colin Xu +Cc: # 5.4.y +Signed-off-by: Greg Kroah-Hartman +--- + 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; diff --git a/queue-5.4/drm-i915-gvt-fix-vfio_edid-issue-for-bxt-apl.patch b/queue-5.4/drm-i915-gvt-fix-vfio_edid-issue-for-bxt-apl.patch new file mode 100644 index 00000000000..0701c101f4e --- /dev/null +++ b/queue-5.4/drm-i915-gvt-fix-vfio_edid-issue-for-bxt-apl.patch @@ -0,0 +1,176 @@ +From foo@baz Fri Mar 19 10:39:38 AM CET 2021 +From: Colin Xu +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 + +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 +Signed-off-by: Zhenyu Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20201201060329.142375-1-colin.xu@intel.com +Reviewed-by: Zhenyu Wang +(cherry picked from commit 4ceb06e7c336f4a8d3f3b6ac9a4fea2e9c97dc07) +Signed-off-by: Colin Xu +Cc: # 5.4.y +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-5.4/drm-i915-gvt-fix-virtual-display-setup-for-bxt-apl.patch b/queue-5.4/drm-i915-gvt-fix-virtual-display-setup-for-bxt-apl.patch new file mode 100644 index 00000000000..1486579b73e --- /dev/null +++ b/queue-5.4/drm-i915-gvt-fix-virtual-display-setup-for-bxt-apl.patch @@ -0,0 +1,269 @@ +From foo@baz Fri Mar 19 10:39:38 AM CET 2021 +From: Colin Xu +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 + +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 +Signed-off-by: Colin Xu +Signed-off-by: Zhenyu Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20201109073922.757759-1-colin.xu@intel.com +(cherry picked from commit a5a8ef937cfa79167f4b2a5602092b8d14fd6b9a) +Signed-off-by: Colin Xu +Cc: # 5.4.y +Signed-off-by: Greg Kroah-Hartman +--- + 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) diff --git a/queue-5.4/drm-i915-gvt-set-snoop-for-pat3-on-bxt-apl-to-workaround-gpu-bb-hang.patch b/queue-5.4/drm-i915-gvt-set-snoop-for-pat3-on-bxt-apl-to-workaround-gpu-bb-hang.patch new file mode 100644 index 00000000000..89719d8e455 --- /dev/null +++ b/queue-5.4/drm-i915-gvt-set-snoop-for-pat3-on-bxt-apl-to-workaround-gpu-bb-hang.patch @@ -0,0 +1,89 @@ +From foo@baz Fri Mar 19 10:39:38 AM CET 2021 +From: Colin Xu +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: + +From: Colin Xu + +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 +Signed-off-by: Colin Xu +Signed-off-by: Zhenyu Wang +Link: http://patchwork.freedesktop.org/patch/msgid/20201012045231.226748-1-colin.xu@intel.com +(cherry picked from commit 8fe105679765700378eb328495fcfe1566cdbbd0) +Signed-off-by: Colin Xu +Cc: # 5.4.y +Signed-off-by: Greg Kroah-Hartman +--- + 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; + } + diff --git a/queue-5.4/fuse-fix-live-lock-in-fuse_iget.patch b/queue-5.4/fuse-fix-live-lock-in-fuse_iget.patch new file mode 100644 index 00000000000..6c22f9a6a83 --- /dev/null +++ b/queue-5.4/fuse-fix-live-lock-in-fuse_iget.patch @@ -0,0 +1,52 @@ +From 775c5033a0d164622d9d10dd0f0a5531639ed3ed Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Thu, 4 Mar 2021 11:09:12 +0200 +Subject: fuse: fix live lock in fuse_iget() + +From: Amir Goldstein + +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 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman +--- + 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); + } + diff --git a/queue-5.4/series b/queue-5.4/series index b51dd4f09ca..af350dad394 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -4,3 +4,10 @@ bpf-fix-off-by-one-for-area-size-in-creating-mask-to-left.patch 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