From: Greg Kroah-Hartman Date: Mon, 24 May 2021 10:49:28 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.4.270~39 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=128633396582ecbf64e455d0f0b8df6e6f3ce727;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: dm-snapshot-fix-a-crash-when-an-origin-has-no-snapshots.patch dm-snapshot-fix-crash-with-transient-storage-and-zero-chunk-size.patch drm-amdgpu-disable-3dcgcg-on-picasso-raven1-to-avoid-compute-hang.patch drm-amdgpu-fix-gpu-tlb-update-error-when-page_size-amdgpu_page_size.patch drm-amdgpu-update-gc-golden-setting-for-navi12.patch drm-amdgpu-update-sdma-golden-setting-for-navi12.patch ipc-mqueue-msg-sem-avoid-relying-on-a-stack-reference-past-its-expiry.patch kcsan-fix-debugfs-initcall-return-type.patch mmc-sdhci-pci-gli-increase-1.8v-regulator-wait.patch powerpc-64s-syscall-fix-ptrace-syscall-info-with-scv-syscalls.patch powerpc-64s-syscall-use-pt_regs.trap-to-distinguish-syscall-abi-difference-between-sc-and-scv-syscalls.patch xen-pciback-reconfigure-also-from-backend-watch-handler.patch xen-pciback-redo-vf-placement-in-the-virtual-topology.patch --- diff --git a/queue-5.10/dm-snapshot-fix-a-crash-when-an-origin-has-no-snapshots.patch b/queue-5.10/dm-snapshot-fix-a-crash-when-an-origin-has-no-snapshots.patch new file mode 100644 index 00000000000..94a509615e2 --- /dev/null +++ b/queue-5.10/dm-snapshot-fix-a-crash-when-an-origin-has-no-snapshots.patch @@ -0,0 +1,43 @@ +From 7ee06ddc4038f936b0d4459d37a7d4d844fb03db Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Fri, 7 May 2021 11:38:10 -0400 +Subject: dm snapshot: fix a crash when an origin has no snapshots + +From: Mikulas Patocka + +commit 7ee06ddc4038f936b0d4459d37a7d4d844fb03db upstream. + +If an origin target has no snapshots, o->split_boundary is set to 0. +This causes BUG_ON(sectors <= 0) in block/bio.c:bio_split(). + +Fix this by initializing chunk_size, and in turn split_boundary, to +rounddown_pow_of_two(UINT_MAX) -- the largest power of two that fits +into "unsigned" type. + +Reported-by: Michael Tokarev +Tested-by: Michael Tokarev +Cc: stable@vger.kernel.org +Signed-off-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-snap.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -854,12 +854,11 @@ static int dm_add_exception(void *contex + static uint32_t __minimum_chunk_size(struct origin *o) + { + struct dm_snapshot *snap; +- unsigned chunk_size = 0; ++ unsigned chunk_size = rounddown_pow_of_two(UINT_MAX); + + if (o) + list_for_each_entry(snap, &o->snapshots, list) +- chunk_size = min_not_zero(chunk_size, +- snap->store->chunk_size); ++ chunk_size = min(chunk_size, snap->store->chunk_size); + + return (uint32_t) chunk_size; + } diff --git a/queue-5.10/dm-snapshot-fix-crash-with-transient-storage-and-zero-chunk-size.patch b/queue-5.10/dm-snapshot-fix-crash-with-transient-storage-and-zero-chunk-size.patch new file mode 100644 index 00000000000..f3d6a700546 --- /dev/null +++ b/queue-5.10/dm-snapshot-fix-crash-with-transient-storage-and-zero-chunk-size.patch @@ -0,0 +1,41 @@ +From c699a0db2d62e3bbb7f0bf35c87edbc8d23e3062 Mon Sep 17 00:00:00 2001 +From: Mikulas Patocka +Date: Mon, 10 May 2021 14:49:05 -0400 +Subject: dm snapshot: fix crash with transient storage and zero chunk size + +From: Mikulas Patocka + +commit c699a0db2d62e3bbb7f0bf35c87edbc8d23e3062 upstream. + +The following commands will crash the kernel: + +modprobe brd rd_size=1048576 +dmsetup create o --table "0 `blockdev --getsize /dev/ram0` snapshot-origin /dev/ram0" +dmsetup create s --table "0 `blockdev --getsize /dev/ram0` snapshot /dev/ram0 /dev/ram1 N 0" + +The reason is that when we test for zero chunk size, we jump to the label +bad_read_metadata without setting the "r" variable. The function +snapshot_ctr destroys all the structures and then exits with "r == 0". The +kernel then crashes because it falsely believes that snapshot_ctr +succeeded. + +In order to fix the bug, we set the variable "r" to -EINVAL. + +Signed-off-by: Mikulas Patocka +Cc: stable@vger.kernel.org +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-snap.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -1407,6 +1407,7 @@ static int snapshot_ctr(struct dm_target + + if (!s->store->chunk_size) { + ti->error = "Chunk size not set"; ++ r = -EINVAL; + goto bad_read_metadata; + } + diff --git a/queue-5.10/drm-amdgpu-disable-3dcgcg-on-picasso-raven1-to-avoid-compute-hang.patch b/queue-5.10/drm-amdgpu-disable-3dcgcg-on-picasso-raven1-to-avoid-compute-hang.patch new file mode 100644 index 00000000000..b3fc7bdf465 --- /dev/null +++ b/queue-5.10/drm-amdgpu-disable-3dcgcg-on-picasso-raven1-to-avoid-compute-hang.patch @@ -0,0 +1,68 @@ +From dbd1003d1252db5973dddf20b24bb0106ac52aa2 Mon Sep 17 00:00:00 2001 +From: Changfeng +Date: Fri, 14 May 2021 15:28:25 +0800 +Subject: drm/amdgpu: disable 3DCGCG on picasso/raven1 to avoid compute hang + +From: Changfeng + +commit dbd1003d1252db5973dddf20b24bb0106ac52aa2 upstream. + +There is problem with 3DCGCG firmware and it will cause compute test +hang on picasso/raven1. It needs to disable 3DCGCG in driver to avoid +compute hang. + +Signed-off-by: Changfeng +Reviewed-by: Alex Deucher +Reviewed-by: Huang Rui +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 10 +++++++--- + drivers/gpu/drm/amd/amdgpu/soc15.c | 2 -- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c +@@ -4859,7 +4859,7 @@ static void gfx_v9_0_update_3d_clock_gat + amdgpu_gfx_rlc_enter_safe_mode(adev); + + /* Enable 3D CGCG/CGLS */ +- if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGCG)) { ++ if (enable) { + /* write cmd to clear cgcg/cgls ov */ + def = data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE); + /* unset CGCG override */ +@@ -4871,8 +4871,12 @@ static void gfx_v9_0_update_3d_clock_gat + /* enable 3Dcgcg FSM(0x0000363f) */ + def = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D); + +- data = (0x36 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | +- RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK; ++ if (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGCG) ++ data = (0x36 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT) | ++ RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK; ++ else ++ data = 0x0 << RLC_CGCG_CGLS_CTRL_3D__CGCG_GFX_IDLE_THRESHOLD__SHIFT; ++ + if (adev->cg_flags & AMD_CG_SUPPORT_GFX_3D_CGLS) + data |= (0x000F << RLC_CGCG_CGLS_CTRL_3D__CGLS_REP_COMPANSAT_DELAY__SHIFT) | + RLC_CGCG_CGLS_CTRL_3D__CGLS_EN_MASK; +--- a/drivers/gpu/drm/amd/amdgpu/soc15.c ++++ b/drivers/gpu/drm/amd/amdgpu/soc15.c +@@ -1183,7 +1183,6 @@ static int soc15_common_early_init(void + adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG | + AMD_CG_SUPPORT_GFX_MGLS | + AMD_CG_SUPPORT_GFX_CP_LS | +- AMD_CG_SUPPORT_GFX_3D_CGCG | + AMD_CG_SUPPORT_GFX_3D_CGLS | + AMD_CG_SUPPORT_GFX_CGCG | + AMD_CG_SUPPORT_GFX_CGLS | +@@ -1203,7 +1202,6 @@ static int soc15_common_early_init(void + AMD_CG_SUPPORT_GFX_MGLS | + AMD_CG_SUPPORT_GFX_RLC_LS | + AMD_CG_SUPPORT_GFX_CP_LS | +- AMD_CG_SUPPORT_GFX_3D_CGCG | + AMD_CG_SUPPORT_GFX_3D_CGLS | + AMD_CG_SUPPORT_GFX_CGCG | + AMD_CG_SUPPORT_GFX_CGLS | diff --git a/queue-5.10/drm-amdgpu-fix-gpu-tlb-update-error-when-page_size-amdgpu_page_size.patch b/queue-5.10/drm-amdgpu-fix-gpu-tlb-update-error-when-page_size-amdgpu_page_size.patch new file mode 100644 index 00000000000..49cda8039f6 --- /dev/null +++ b/queue-5.10/drm-amdgpu-fix-gpu-tlb-update-error-when-page_size-amdgpu_page_size.patch @@ -0,0 +1,37 @@ +From d53751568359e5b3ffb859b13cbd79dc77a571f1 Mon Sep 17 00:00:00 2001 +From: Yi Li +Date: Fri, 14 May 2021 14:40:39 +0800 +Subject: drm/amdgpu: Fix GPU TLB update error when PAGE_SIZE > AMDGPU_PAGE_SIZE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yi Li + +commit d53751568359e5b3ffb859b13cbd79dc77a571f1 upstream. + +When PAGE_SIZE is larger than AMDGPU_PAGE_SIZE, the number of GPU TLB +entries which need to update in amdgpu_map_buffer() should be multiplied +by AMDGPU_GPU_PAGES_IN_CPU_PAGE (PAGE_SIZE / AMDGPU_PAGE_SIZE). + +Reviewed-by: Christian König +Signed-off-by: Yi Li +Signed-off-by: Huacai Chen +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +@@ -267,7 +267,7 @@ static int amdgpu_ttm_map_buffer(struct + *addr += offset & ~PAGE_MASK; + + num_dw = ALIGN(adev->mman.buffer_funcs->copy_num_dw, 8); +- num_bytes = num_pages * 8; ++ num_bytes = num_pages * 8 * AMDGPU_GPU_PAGES_IN_CPU_PAGE; + + r = amdgpu_job_alloc_with_ib(adev, num_dw * 4 + num_bytes, + AMDGPU_IB_POOL_DELAYED, &job); diff --git a/queue-5.10/drm-amdgpu-update-gc-golden-setting-for-navi12.patch b/queue-5.10/drm-amdgpu-update-gc-golden-setting-for-navi12.patch new file mode 100644 index 00000000000..60d4096c4d1 --- /dev/null +++ b/queue-5.10/drm-amdgpu-update-gc-golden-setting-for-navi12.patch @@ -0,0 +1,49 @@ +From 99c45ba5799d6b938bd9bd20edfeb6f3e3e039b9 Mon Sep 17 00:00:00 2001 +From: Guchun Chen +Date: Mon, 17 May 2021 16:35:40 +0800 +Subject: drm/amdgpu: update gc golden setting for Navi12 + +From: Guchun Chen + +commit 99c45ba5799d6b938bd9bd20edfeb6f3e3e039b9 upstream. + +Current golden setting is out of date. + +Signed-off-by: Guchun Chen +Reviewed-by: Kenneth Feng +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +@@ -1334,9 +1334,10 @@ static const struct soc15_reg_golden gol + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG, 0xffffffff, 0x20000000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG2, 0xffffffff, 0x00000420), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG3, 0xffffffff, 0x00000200), +- SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x04800000), ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DEBUG4, 0xffffffff, 0x04900000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_DFSM_TILES_IN_FLIGHT, 0x0000ffff, 0x0000003f), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmDB_LAST_OF_BURST_CONFIG, 0xffffffff, 0x03860204), ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmGB_ADDR_CONFIG, 0x0c1800ff, 0x00000044), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGCR_GENERAL_CNTL, 0x1ff0ffff, 0x00000500), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGE_PRIV_CONTROL, 0x00007fff, 0x000001fe), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmGL1_PIPE_STEER, 0xffffffff, 0xe4e4e4e4), +@@ -1354,12 +1355,13 @@ static const struct soc15_reg_golden gol + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_ENHANCE_2, 0x00000820, 0x00000820), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmPA_SC_LINE_STIPPLE_STATE, 0x0000ff0f, 0x00000000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmRMI_SPARE, 0xffffffff, 0xffff3101), ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSPI_CONFIG_CNTL_1, 0x001f0000, 0x00070104), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ALU_CLK_CTRL, 0xffffffff, 0xffffffff), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_ARB_CONFIG, 0x00000133, 0x00000130), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSQ_LDS_CLK_CTRL, 0xffffffff, 0xffffffff), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmTA_CNTL_AUX, 0xfff7ffff, 0x01030000), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmTCP_CNTL, 0xffdf80ff, 0x479c0010), +- SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00800000) ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmUTCL1_CTRL, 0xffffffff, 0x00c00000) + }; + + static void gfx_v10_rlcg_wreg(struct amdgpu_device *adev, u32 offset, u32 v) diff --git a/queue-5.10/drm-amdgpu-update-sdma-golden-setting-for-navi12.patch b/queue-5.10/drm-amdgpu-update-sdma-golden-setting-for-navi12.patch new file mode 100644 index 00000000000..4cede17032d --- /dev/null +++ b/queue-5.10/drm-amdgpu-update-sdma-golden-setting-for-navi12.patch @@ -0,0 +1,33 @@ +From 77194d8642dd4cb7ea8ced77bfaea55610574c38 Mon Sep 17 00:00:00 2001 +From: Guchun Chen +Date: Mon, 17 May 2021 16:38:00 +0800 +Subject: drm/amdgpu: update sdma golden setting for Navi12 + +From: Guchun Chen + +commit 77194d8642dd4cb7ea8ced77bfaea55610574c38 upstream. + +Current golden setting is out of date. + +Signed-off-by: Guchun Chen +Reviewed-by: Kenneth Feng +Signed-off-by: Alex Deucher +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +@@ -124,6 +124,10 @@ static const struct soc15_reg_golden gol + + static const struct soc15_reg_golden golden_settings_sdma_nv12[] = { + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_GB_ADDR_CONFIG, 0x001877ff, 0x00000044), ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA0_GB_ADDR_CONFIG_READ, 0x001877ff, 0x00000044), ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_GB_ADDR_CONFIG, 0x001877ff, 0x00000044), ++ SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_GB_ADDR_CONFIG_READ, 0x001877ff, 0x00000044), + SOC15_REG_GOLDEN_VALUE(GC, 0, mmSDMA1_RLC3_RB_WPTR_POLL_CNTL, 0xfffffff7, 0x00403000), + }; + diff --git a/queue-5.10/ipc-mqueue-msg-sem-avoid-relying-on-a-stack-reference-past-its-expiry.patch b/queue-5.10/ipc-mqueue-msg-sem-avoid-relying-on-a-stack-reference-past-its-expiry.patch new file mode 100644 index 00000000000..e612af4c584 --- /dev/null +++ b/queue-5.10/ipc-mqueue-msg-sem-avoid-relying-on-a-stack-reference-past-its-expiry.patch @@ -0,0 +1,141 @@ +From a11ddb37bf367e6b5239b95ca759e5389bb46048 Mon Sep 17 00:00:00 2001 +From: Varad Gautam +Date: Sat, 22 May 2021 17:41:49 -0700 +Subject: ipc/mqueue, msg, sem: avoid relying on a stack reference past its expiry + +From: Varad Gautam + +commit a11ddb37bf367e6b5239b95ca759e5389bb46048 upstream. + +do_mq_timedreceive calls wq_sleep with a stack local address. The +sender (do_mq_timedsend) uses this address to later call pipelined_send. + +This leads to a very hard to trigger race where a do_mq_timedreceive +call might return and leave do_mq_timedsend to rely on an invalid +address, causing the following crash: + + RIP: 0010:wake_q_add_safe+0x13/0x60 + Call Trace: + __x64_sys_mq_timedsend+0x2a9/0x490 + do_syscall_64+0x80/0x680 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + RIP: 0033:0x7f5928e40343 + +The race occurs as: + +1. do_mq_timedreceive calls wq_sleep with the address of `struct + ext_wait_queue` on function stack (aliased as `ewq_addr` here) - it + holds a valid `struct ext_wait_queue *` as long as the stack has not + been overwritten. + +2. `ewq_addr` gets added to info->e_wait_q[RECV].list in wq_add, and + do_mq_timedsend receives it via wq_get_first_waiter(info, RECV) to call + __pipelined_op. + +3. Sender calls __pipelined_op::smp_store_release(&this->state, + STATE_READY). Here is where the race window begins. (`this` is + `ewq_addr`.) + +4. If the receiver wakes up now in do_mq_timedreceive::wq_sleep, it + will see `state == STATE_READY` and break. + +5. do_mq_timedreceive returns, and `ewq_addr` is no longer guaranteed + to be a `struct ext_wait_queue *` since it was on do_mq_timedreceive's + stack. (Although the address may not get overwritten until another + function happens to touch it, which means it can persist around for an + indefinite time.) + +6. do_mq_timedsend::__pipelined_op() still believes `ewq_addr` is a + `struct ext_wait_queue *`, and uses it to find a task_struct to pass to + the wake_q_add_safe call. In the lucky case where nothing has + overwritten `ewq_addr` yet, `ewq_addr->task` is the right task_struct. + In the unlucky case, __pipelined_op::wake_q_add_safe gets handed a + bogus address as the receiver's task_struct causing the crash. + +do_mq_timedsend::__pipelined_op() should not dereference `this` after +setting STATE_READY, as the receiver counterpart is now free to return. +Change __pipelined_op to call wake_q_add_safe on the receiver's +task_struct returned by get_task_struct, instead of dereferencing `this` +which sits on the receiver's stack. + +As Manfred pointed out, the race potentially also exists in +ipc/msg.c::expunge_all and ipc/sem.c::wake_up_sem_queue_prepare. Fix +those in the same way. + +Link: https://lkml.kernel.org/r/20210510102950.12551-1-varad.gautam@suse.com +Fixes: c5b2cbdbdac563 ("ipc/mqueue.c: update/document memory barriers") +Fixes: 8116b54e7e23ef ("ipc/sem.c: document and update memory barriers") +Fixes: 0d97a82ba830d8 ("ipc/msg.c: update and document memory barriers") +Signed-off-by: Varad Gautam +Reported-by: Matthias von Faber +Acked-by: Davidlohr Bueso +Acked-by: Manfred Spraul +Cc: Christian Brauner +Cc: Oleg Nesterov +Cc: "Eric W. Biederman" +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + ipc/mqueue.c | 6 ++++-- + ipc/msg.c | 6 ++++-- + ipc/sem.c | 6 ++++-- + 3 files changed, 12 insertions(+), 6 deletions(-) + +--- a/ipc/mqueue.c ++++ b/ipc/mqueue.c +@@ -1003,12 +1003,14 @@ static inline void __pipelined_op(struct + struct mqueue_inode_info *info, + struct ext_wait_queue *this) + { ++ struct task_struct *task; ++ + list_del(&this->list); +- get_task_struct(this->task); ++ task = get_task_struct(this->task); + + /* see MQ_BARRIER for purpose/pairing */ + smp_store_release(&this->state, STATE_READY); +- wake_q_add_safe(wake_q, this->task); ++ wake_q_add_safe(wake_q, task); + } + + /* pipelined_send() - send a message directly to the task waiting in +--- a/ipc/msg.c ++++ b/ipc/msg.c +@@ -251,11 +251,13 @@ static void expunge_all(struct msg_queue + struct msg_receiver *msr, *t; + + list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) { +- get_task_struct(msr->r_tsk); ++ struct task_struct *r_tsk; ++ ++ r_tsk = get_task_struct(msr->r_tsk); + + /* see MSG_BARRIER for purpose/pairing */ + smp_store_release(&msr->r_msg, ERR_PTR(res)); +- wake_q_add_safe(wake_q, msr->r_tsk); ++ wake_q_add_safe(wake_q, r_tsk); + } + } + +--- a/ipc/sem.c ++++ b/ipc/sem.c +@@ -784,12 +784,14 @@ would_block: + static inline void wake_up_sem_queue_prepare(struct sem_queue *q, int error, + struct wake_q_head *wake_q) + { +- get_task_struct(q->sleeper); ++ struct task_struct *sleeper; ++ ++ sleeper = get_task_struct(q->sleeper); + + /* see SEM_BARRIER_2 for purpuse/pairing */ + smp_store_release(&q->status, error); + +- wake_q_add_safe(wake_q, q->sleeper); ++ wake_q_add_safe(wake_q, sleeper); + } + + static void unlink_queue(struct sem_array *sma, struct sem_queue *q) diff --git a/queue-5.10/kcsan-fix-debugfs-initcall-return-type.patch b/queue-5.10/kcsan-fix-debugfs-initcall-return-type.patch new file mode 100644 index 00000000000..af8149cd6ca --- /dev/null +++ b/queue-5.10/kcsan-fix-debugfs-initcall-return-type.patch @@ -0,0 +1,46 @@ +From 976aac5f882989e4f6c1b3a7224819bf0e801c6a Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 14 May 2021 16:00:08 +0200 +Subject: kcsan: Fix debugfs initcall return type + +From: Arnd Bergmann + +commit 976aac5f882989e4f6c1b3a7224819bf0e801c6a upstream. + +clang with CONFIG_LTO_CLANG points out that an initcall function should +return an 'int' due to the changes made to the initcall macros in commit +3578ad11f3fb ("init: lto: fix PREL32 relocations"): + +kernel/kcsan/debugfs.c:274:15: error: returning 'void' from a function with incompatible result type 'int' +late_initcall(kcsan_debugfs_init); +~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~ +include/linux/init.h:292:46: note: expanded from macro 'late_initcall' + #define late_initcall(fn) __define_initcall(fn, 7) + +Fixes: e36299efe7d7 ("kcsan, debugfs: Move debugfs file creation out of early init") +Cc: stable +Reviewed-by: Greg Kroah-Hartman +Reviewed-by: Marco Elver +Reviewed-by: Nathan Chancellor +Reviewed-by: Miguel Ojeda +Signed-off-by: Arnd Bergmann +Signed-off-by: Paul E. McKenney +Signed-off-by: Greg Kroah-Hartman +--- + kernel/kcsan/debugfs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/kcsan/debugfs.c ++++ b/kernel/kcsan/debugfs.c +@@ -261,9 +261,10 @@ static const struct file_operations debu + .release = single_release + }; + +-static void __init kcsan_debugfs_init(void) ++static int __init kcsan_debugfs_init(void) + { + debugfs_create_file("kcsan", 0644, NULL, NULL, &debugfs_ops); ++ return 0; + } + + late_initcall(kcsan_debugfs_init); diff --git a/queue-5.10/mmc-sdhci-pci-gli-increase-1.8v-regulator-wait.patch b/queue-5.10/mmc-sdhci-pci-gli-increase-1.8v-regulator-wait.patch new file mode 100644 index 00000000000..49c95287a08 --- /dev/null +++ b/queue-5.10/mmc-sdhci-pci-gli-increase-1.8v-regulator-wait.patch @@ -0,0 +1,53 @@ +From a1149a6c06ee094a6e62886b0c0e8e66967a728a Mon Sep 17 00:00:00 2001 +From: Daniel Beer +Date: Sat, 24 Apr 2021 20:16:52 +1200 +Subject: mmc: sdhci-pci-gli: increase 1.8V regulator wait + +From: Daniel Beer + +commit a1149a6c06ee094a6e62886b0c0e8e66967a728a upstream. + +Inserting an SD-card on an Intel NUC10i3FNK4 (which contains a GL9755) +results in the message: + + mmc0: 1.8V regulator output did not become stable + +Following this message, some cards work (sometimes), but most cards fail +with EILSEQ. This behaviour is observed on Debian 10 running kernel +4.19.188, but also with 5.8.18 and 5.11.15. + +The driver currently waits 5ms after switching on the 1.8V regulator for +it to become stable. Increasing this to 10ms gets rid of the warning +about stability, but most cards still fail. Increasing it to 20ms gets +some cards working (a 32GB Samsung micro SD works, a 128GB ADATA +doesn't). At 50ms, the ADATA works most of the time, and at 100ms both +cards work reliably. + +Signed-off-by: Daniel Beer +Acked-by: Ben Chuang +Fixes: e51df6ce668a ("mmc: host: sdhci-pci: Add Genesys Logic GL975x support") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210424081652.GA16047@nyquist.nev +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-pci-gli.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/mmc/host/sdhci-pci-gli.c ++++ b/drivers/mmc/host/sdhci-pci-gli.c +@@ -555,8 +555,13 @@ static void sdhci_gli_voltage_switch(str + * + * Wait 5ms after set 1.8V signal enable in Host Control 2 register + * to ensure 1.8V signal enable bit is set by GL9750/GL9755. ++ * ++ * ...however, the controller in the NUC10i3FNK4 (a 9755) requires ++ * slightly longer than 5ms before the control register reports that ++ * 1.8V is ready, and far longer still before the card will actually ++ * work reliably. + */ +- usleep_range(5000, 5500); ++ usleep_range(100000, 110000); + } + + static void sdhci_gl9750_reset(struct sdhci_host *host, u8 mask) diff --git a/queue-5.10/powerpc-64s-syscall-fix-ptrace-syscall-info-with-scv-syscalls.patch b/queue-5.10/powerpc-64s-syscall-fix-ptrace-syscall-info-with-scv-syscalls.patch new file mode 100644 index 00000000000..9e812a3bce3 --- /dev/null +++ b/queue-5.10/powerpc-64s-syscall-fix-ptrace-syscall-info-with-scv-syscalls.patch @@ -0,0 +1,157 @@ +From d72500f992849d31ebae8f821a023660ddd0dcc2 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Thu, 20 May 2021 21:19:31 +1000 +Subject: powerpc/64s/syscall: Fix ptrace syscall info with scv syscalls + +From: Nicholas Piggin + +commit d72500f992849d31ebae8f821a023660ddd0dcc2 upstream. + +The scv implementation missed updating syscall return value and error +value get/set functions to deal with the changed register ABI. This +broke ptrace PTRACE_GET_SYSCALL_INFO as well as some kernel auditing +and tracing functions. + +Fix. tools/testing/selftests/ptrace/get_syscall_info now passes when +scv is used. + +Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions") +Cc: stable@vger.kernel.org # v5.9+ +Reported-by: "Dmitry V. Levin" +Signed-off-by: Nicholas Piggin +Reviewed-by: Dmitry V. Levin +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20210520111931.2597127-2-npiggin@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/include/asm/ptrace.h | 45 +++++++++++++++++++++---------------- + arch/powerpc/include/asm/syscall.h | 42 +++++++++++++++++++++------------- + 2 files changed, 52 insertions(+), 35 deletions(-) + +--- a/arch/powerpc/include/asm/ptrace.h ++++ b/arch/powerpc/include/asm/ptrace.h +@@ -19,6 +19,7 @@ + #ifndef _ASM_POWERPC_PTRACE_H + #define _ASM_POWERPC_PTRACE_H + ++#include + #include + #include + +@@ -144,25 +145,6 @@ extern unsigned long profile_pc(struct p + long do_syscall_trace_enter(struct pt_regs *regs); + void do_syscall_trace_leave(struct pt_regs *regs); + +-#define kernel_stack_pointer(regs) ((regs)->gpr[1]) +-static inline int is_syscall_success(struct pt_regs *regs) +-{ +- return !(regs->ccr & 0x10000000); +-} +- +-static inline long regs_return_value(struct pt_regs *regs) +-{ +- if (is_syscall_success(regs)) +- return regs->gpr[3]; +- else +- return -regs->gpr[3]; +-} +- +-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) +-{ +- regs->gpr[3] = rc; +-} +- + #ifdef __powerpc64__ + #define user_mode(regs) ((((regs)->msr) >> MSR_PR_LG) & 0x1) + #else +@@ -245,6 +227,31 @@ static inline void set_trap_norestart(st + regs->trap |= 0x10; + } + ++#define kernel_stack_pointer(regs) ((regs)->gpr[1]) ++static inline int is_syscall_success(struct pt_regs *regs) ++{ ++ if (trap_is_scv(regs)) ++ return !IS_ERR_VALUE((unsigned long)regs->gpr[3]); ++ else ++ return !(regs->ccr & 0x10000000); ++} ++ ++static inline long regs_return_value(struct pt_regs *regs) ++{ ++ if (trap_is_scv(regs)) ++ return regs->gpr[3]; ++ ++ if (is_syscall_success(regs)) ++ return regs->gpr[3]; ++ else ++ return -regs->gpr[3]; ++} ++ ++static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc) ++{ ++ regs->gpr[3] = rc; ++} ++ + #define arch_has_single_step() (1) + #define arch_has_block_step() (true) + #define ARCH_HAS_USER_SINGLE_STEP_REPORT +--- a/arch/powerpc/include/asm/syscall.h ++++ b/arch/powerpc/include/asm/syscall.h +@@ -41,11 +41,17 @@ static inline void syscall_rollback(stru + static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) + { +- /* +- * If the system call failed, +- * regs->gpr[3] contains a positive ERRORCODE. +- */ +- return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0; ++ if (trap_is_scv(regs)) { ++ unsigned long error = regs->gpr[3]; ++ ++ return IS_ERR_VALUE(error) ? error : 0; ++ } else { ++ /* ++ * If the system call failed, ++ * regs->gpr[3] contains a positive ERRORCODE. ++ */ ++ return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0; ++ } + } + + static inline long syscall_get_return_value(struct task_struct *task, +@@ -58,18 +64,22 @@ static inline void syscall_set_return_va + struct pt_regs *regs, + int error, long val) + { +- /* +- * In the general case it's not obvious that we must deal with CCR +- * here, as the syscall exit path will also do that for us. However +- * there are some places, eg. the signal code, which check ccr to +- * decide if the value in r3 is actually an error. +- */ +- if (error) { +- regs->ccr |= 0x10000000L; +- regs->gpr[3] = error; ++ if (trap_is_scv(regs)) { ++ regs->gpr[3] = (long) error ?: val; + } else { +- regs->ccr &= ~0x10000000L; +- regs->gpr[3] = val; ++ /* ++ * In the general case it's not obvious that we must deal with ++ * CCR here, as the syscall exit path will also do that for us. ++ * However there are some places, eg. the signal code, which ++ * check ccr to decide if the value in r3 is actually an error. ++ */ ++ if (error) { ++ regs->ccr |= 0x10000000L; ++ regs->gpr[3] = error; ++ } else { ++ regs->ccr &= ~0x10000000L; ++ regs->gpr[3] = val; ++ } + } + } + diff --git a/queue-5.10/powerpc-64s-syscall-use-pt_regs.trap-to-distinguish-syscall-abi-difference-between-sc-and-scv-syscalls.patch b/queue-5.10/powerpc-64s-syscall-use-pt_regs.trap-to-distinguish-syscall-abi-difference-between-sc-and-scv-syscalls.patch new file mode 100644 index 00000000000..3b176b8c916 --- /dev/null +++ b/queue-5.10/powerpc-64s-syscall-use-pt_regs.trap-to-distinguish-syscall-abi-difference-between-sc-and-scv-syscalls.patch @@ -0,0 +1,85 @@ +From 5665bc35c1ed917ac8fd06cb651317bb47a65b10 Mon Sep 17 00:00:00 2001 +From: Nicholas Piggin +Date: Thu, 20 May 2021 21:19:30 +1000 +Subject: powerpc/64s/syscall: Use pt_regs.trap to distinguish syscall ABI difference between sc and scv syscalls + +From: Nicholas Piggin + +commit 5665bc35c1ed917ac8fd06cb651317bb47a65b10 upstream. + +The sc and scv 0 system calls have different ABI conventions, and +ptracers need to know which system call type is being used if they want +to look at the syscall registers. + +Document that pt_regs.trap can be used for this, and fix one in-tree user +to work with scv 0 syscalls. + +Fixes: 7fa95f9adaee ("powerpc/64s: system call support for scv/rfscv instructions") +Cc: stable@vger.kernel.org # v5.9+ +Reported-by: "Dmitry V. Levin" +Suggested-by: "Dmitry V. Levin" +Signed-off-by: Nicholas Piggin +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20210520111931.2597127-1-npiggin@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/powerpc/syscall64-abi.rst | 10 +++++++++ + tools/testing/selftests/seccomp/seccomp_bpf.c | 27 +++++++++++++++++--------- + 2 files changed, 28 insertions(+), 9 deletions(-) + +--- a/Documentation/powerpc/syscall64-abi.rst ++++ b/Documentation/powerpc/syscall64-abi.rst +@@ -96,6 +96,16 @@ auxiliary vector. + + scv 0 syscalls will always behave as PPC_FEATURE2_HTM_NOSC. + ++ptrace ++------ ++When ptracing system calls (PTRACE_SYSCALL), the pt_regs.trap value contains ++the system call type that can be used to distinguish between sc and scv 0 ++system calls, and the different register conventions can be accounted for. ++ ++If the value of (pt_regs.trap & 0xfff0) is 0xc00 then the system call was ++performed with the sc instruction, if it is 0x3000 then the system call was ++performed with the scv 0 instruction. ++ + vsyscall + ======== + +--- a/tools/testing/selftests/seccomp/seccomp_bpf.c ++++ b/tools/testing/selftests/seccomp/seccomp_bpf.c +@@ -1753,16 +1753,25 @@ TEST_F(TRACE_poke, getpid_runs_normally) + # define SYSCALL_RET_SET(_regs, _val) \ + do { \ + typeof(_val) _result = (_val); \ +- /* \ +- * A syscall error is signaled by CR0 SO bit \ +- * and the code is stored as a positive value. \ +- */ \ +- if (_result < 0) { \ +- SYSCALL_RET(_regs) = -_result; \ +- (_regs).ccr |= 0x10000000; \ +- } else { \ ++ if ((_regs.trap & 0xfff0) == 0x3000) { \ ++ /* \ ++ * scv 0 system call uses -ve result \ ++ * for error, so no need to adjust. \ ++ */ \ + SYSCALL_RET(_regs) = _result; \ +- (_regs).ccr &= ~0x10000000; \ ++ } else { \ ++ /* \ ++ * A syscall error is signaled by the \ ++ * CR0 SO bit and the code is stored as \ ++ * a positive value. \ ++ */ \ ++ if (_result < 0) { \ ++ SYSCALL_RET(_regs) = -_result; \ ++ (_regs).ccr |= 0x10000000; \ ++ } else { \ ++ SYSCALL_RET(_regs) = _result; \ ++ (_regs).ccr &= ~0x10000000; \ ++ } \ + } \ + } while (0) + # define SYSCALL_RET_SET_ON_PTRACE_EXIT diff --git a/queue-5.10/series b/queue-5.10/series index 8029ddd1481..d3d3d2ffb16 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -57,3 +57,16 @@ x86-sev-es-invalidate-the-ghcb-after-completing-vmgexit.patch x86-sev-es-don-t-return-null-from-sev_es_get_ghcb.patch x86-sev-es-use-__put_user-__get_user-for-data-accesses.patch x86-sev-es-forward-page-faults-which-happen-during-emulation.patch +drm-amdgpu-fix-gpu-tlb-update-error-when-page_size-amdgpu_page_size.patch +drm-amdgpu-disable-3dcgcg-on-picasso-raven1-to-avoid-compute-hang.patch +drm-amdgpu-update-gc-golden-setting-for-navi12.patch +drm-amdgpu-update-sdma-golden-setting-for-navi12.patch +powerpc-64s-syscall-use-pt_regs.trap-to-distinguish-syscall-abi-difference-between-sc-and-scv-syscalls.patch +powerpc-64s-syscall-fix-ptrace-syscall-info-with-scv-syscalls.patch +mmc-sdhci-pci-gli-increase-1.8v-regulator-wait.patch +xen-pciback-redo-vf-placement-in-the-virtual-topology.patch +xen-pciback-reconfigure-also-from-backend-watch-handler.patch +ipc-mqueue-msg-sem-avoid-relying-on-a-stack-reference-past-its-expiry.patch +dm-snapshot-fix-a-crash-when-an-origin-has-no-snapshots.patch +dm-snapshot-fix-crash-with-transient-storage-and-zero-chunk-size.patch +kcsan-fix-debugfs-initcall-return-type.patch diff --git a/queue-5.10/xen-pciback-reconfigure-also-from-backend-watch-handler.patch b/queue-5.10/xen-pciback-reconfigure-also-from-backend-watch-handler.patch new file mode 100644 index 00000000000..bf41b75bfd8 --- /dev/null +++ b/queue-5.10/xen-pciback-reconfigure-also-from-backend-watch-handler.patch @@ -0,0 +1,85 @@ +From c81d3d24602540f65256f98831d0a25599ea6b87 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 18 May 2021 18:14:07 +0200 +Subject: xen-pciback: reconfigure also from backend watch handler + +From: Jan Beulich + +commit c81d3d24602540f65256f98831d0a25599ea6b87 upstream. + +When multiple PCI devices get assigned to a guest right at boot, libxl +incrementally populates the backend tree. The writes for the first of +the devices trigger the backend watch. In turn xen_pcibk_setup_backend() +will set the XenBus state to Initialised, at which point no further +reconfigures would happen unless a device got hotplugged. Arrange for +reconfigure to also get triggered from the backend watch handler. + +Signed-off-by: Jan Beulich +Cc: stable@vger.kernel.org +Reviewed-by: Boris Ostrovsky +Link: https://lore.kernel.org/r/2337cbd6-94b9-4187-9862-c03ea12e0c61@suse.com +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + drivers/xen/xen-pciback/xenbus.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +--- a/drivers/xen/xen-pciback/xenbus.c ++++ b/drivers/xen/xen-pciback/xenbus.c +@@ -359,7 +359,8 @@ out: + return err; + } + +-static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev) ++static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev, ++ enum xenbus_state state) + { + int err = 0; + int num_devs; +@@ -373,9 +374,7 @@ static int xen_pcibk_reconfigure(struct + dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n"); + + mutex_lock(&pdev->dev_lock); +- /* Make sure we only reconfigure once */ +- if (xenbus_read_driver_state(pdev->xdev->nodename) != +- XenbusStateReconfiguring) ++ if (xenbus_read_driver_state(pdev->xdev->nodename) != state) + goto out; + + err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d", +@@ -500,6 +499,10 @@ static int xen_pcibk_reconfigure(struct + } + } + ++ if (state != XenbusStateReconfiguring) ++ /* Make sure we only reconfigure once. */ ++ goto out; ++ + err = xenbus_switch_state(pdev->xdev, XenbusStateReconfigured); + if (err) { + xenbus_dev_fatal(pdev->xdev, err, +@@ -525,7 +528,7 @@ static void xen_pcibk_frontend_changed(s + break; + + case XenbusStateReconfiguring: +- xen_pcibk_reconfigure(pdev); ++ xen_pcibk_reconfigure(pdev, XenbusStateReconfiguring); + break; + + case XenbusStateConnected: +@@ -664,6 +667,15 @@ static void xen_pcibk_be_watch(struct xe + xen_pcibk_setup_backend(pdev); + break; + ++ case XenbusStateInitialised: ++ /* ++ * We typically move to Initialised when the first device was ++ * added. Hence subsequent devices getting added may need ++ * reconfiguring. ++ */ ++ xen_pcibk_reconfigure(pdev, XenbusStateInitialised); ++ break; ++ + default: + break; + } diff --git a/queue-5.10/xen-pciback-redo-vf-placement-in-the-virtual-topology.patch b/queue-5.10/xen-pciback-redo-vf-placement-in-the-virtual-topology.patch new file mode 100644 index 00000000000..1d112e9e7e4 --- /dev/null +++ b/queue-5.10/xen-pciback-redo-vf-placement-in-the-virtual-topology.patch @@ -0,0 +1,81 @@ +From 4ba50e7c423c29639878c00573288869aa627068 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 18 May 2021 18:13:42 +0200 +Subject: xen-pciback: redo VF placement in the virtual topology + +From: Jan Beulich + +commit 4ba50e7c423c29639878c00573288869aa627068 upstream. + +The commit referenced below was incomplete: It merely affected what +would get written to the vdev- xenstore node. The guest would still +find the function at the original function number as long as +__xen_pcibk_get_pci_dev() wouldn't be in sync. The same goes for AER wrt +__xen_pcibk_get_pcifront_dev(). + +Undo overriding the function to zero and instead make sure that VFs at +function zero remain alone in their slot. This has the added benefit of +improving overall capacity, considering that there's only a total of 32 +slots available right now (PCI segment and bus can both only ever be +zero at present). + +Fixes: 8a5248fe10b1 ("xen PV passthru: assign SR-IOV virtual functions to separate virtual slots") +Signed-off-by: Jan Beulich +Cc: stable@vger.kernel.org +Reviewed-by: Boris Ostrovsky +Link: https://lore.kernel.org/r/8def783b-404c-3452-196d-3f3fd4d72c9e@suse.com +Signed-off-by: Juergen Gross +Signed-off-by: Greg Kroah-Hartman +--- + drivers/xen/xen-pciback/vpci.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/xen/xen-pciback/vpci.c ++++ b/drivers/xen/xen-pciback/vpci.c +@@ -70,7 +70,7 @@ static int __xen_pcibk_add_pci_dev(struc + struct pci_dev *dev, int devid, + publish_pci_dev_cb publish_cb) + { +- int err = 0, slot, func = -1; ++ int err = 0, slot, func = PCI_FUNC(dev->devfn); + struct pci_dev_entry *t, *dev_entry; + struct vpci_dev_data *vpci_dev = pdev->pci_dev_data; + +@@ -95,22 +95,25 @@ static int __xen_pcibk_add_pci_dev(struc + + /* + * Keep multi-function devices together on the virtual PCI bus, except +- * virtual functions. ++ * that we want to keep virtual functions at func 0 on their own. They ++ * aren't multi-function devices and hence their presence at func 0 ++ * may cause guests to not scan the other functions. + */ +- if (!dev->is_virtfn) { ++ if (!dev->is_virtfn || func) { + for (slot = 0; slot < PCI_SLOT_MAX; slot++) { + if (list_empty(&vpci_dev->dev_list[slot])) + continue; + + t = list_entry(list_first(&vpci_dev->dev_list[slot]), + struct pci_dev_entry, list); ++ if (t->dev->is_virtfn && !PCI_FUNC(t->dev->devfn)) ++ continue; + + if (match_slot(dev, t->dev)) { + dev_info(&dev->dev, "vpci: assign to virtual slot %d func %d\n", +- slot, PCI_FUNC(dev->devfn)); ++ slot, func); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); +- func = PCI_FUNC(dev->devfn); + goto unlock; + } + } +@@ -123,7 +126,6 @@ static int __xen_pcibk_add_pci_dev(struc + slot); + list_add_tail(&dev_entry->list, + &vpci_dev->dev_list[slot]); +- func = dev->is_virtfn ? 0 : PCI_FUNC(dev->devfn); + goto unlock; + } + }