The patch below does not apply to the 5.13-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
>From 3769e4c0af5b82c8ea21d037013cb9564dfaa51f Mon Sep 17 00:00:00 2001
From: Wayne Lin <Wayne.Lin(a)amd.com>
Date: Wed, 16 Jun 2021 11:55:01 +0800
Subject: [PATCH] drm/dp_mst: Avoid to mess up payload table by ports in stale
topology
[Why]
After unplug/hotplug hub from the system, userspace might start to
clear stale payloads gradually. If we call drm_dp_mst_deallocate_vcpi()
to release stale VCPI of those ports which are not relating to current
topology, we have chane to wrongly clear active payload table entry for
current topology.
E.g.
We have allocated VCPI 1 in current payload table and we call
drm_dp_mst_deallocate_vcpi() to clean VCPI 1 in stale topology. In
drm_dp_mst_deallocate_vcpi(), it will call drm_dp_mst_put_payload_id()
tp put VCPI 1 and which means ID 1 is available again. Thereafter, if we
want to allocate a new payload stream, it will find ID 1 is available by
drm_dp_mst_assign_payload_id(). However, ID 1 is being used
[How]
Check target sink is relating to current topology or not before doing
any payload table update.
Searching upward to find the target sink's relevant root branch device.
If the found root branch device is not the same root of current
topology, don't update payload table.
Changes since v1:
* Change debug macro to use drm_dbg_kms() instead
* Amend the commit message to add Cc tag.
Signed-off-by: Wayne Lin <Wayne.Lin(a)amd.com>
Cc: stable(a)vger.kernel.org
Signed-off-by: Lyude Paul <lyude(a)redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210616035501.3776-3-Wayne.L…
Reviewed-by: Lyude Paul <lyude(a)redhat.com>
diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
index b41b837db66d..9ac148efd9e4 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -94,6 +94,9 @@ static int drm_dp_mst_register_i2c_bus(struct drm_dp_mst_port *port);
static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_mst_port *port);
static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);
+static bool drm_dp_mst_port_downstream_of_branch(struct drm_dp_mst_port *port,
+ struct drm_dp_mst_branch *branch);
+
#define DBG_PREFIX "[dp_mst]"
#define DP_STR(x) [DP_ ## x] = #x
@@ -3366,6 +3369,7 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
struct drm_dp_mst_port *port;
int i, j;
int cur_slots = 1;
+ bool skip;
mutex_lock(&mgr->payload_lock);
for (i = 0; i < mgr->max_payloads; i++) {
@@ -3380,6 +3384,14 @@ int drm_dp_update_payload_part1(struct drm_dp_mst_topology_mgr *mgr)
port = container_of(vcpi, struct drm_dp_mst_port,
vcpi);
+ mutex_lock(&mgr->lock);
+ skip = !drm_dp_mst_port_downstream_of_branch(port, mgr->mst_primary);
+ mutex_unlock(&mgr->lock);
+
+ if (skip) {
+ drm_dbg_kms("Virtual channel %d is not in current topology\n", i);
+ continue;
+ }
/* Validated ports don't matter if we're releasing
* VCPI
*/
@@ -3479,6 +3491,7 @@ int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr)
struct drm_dp_mst_port *port;
int i;
int ret = 0;
+ bool skip;
mutex_lock(&mgr->payload_lock);
for (i = 0; i < mgr->max_payloads; i++) {
@@ -3488,6 +3501,13 @@ int drm_dp_update_payload_part2(struct drm_dp_mst_topology_mgr *mgr)
port = container_of(mgr->proposed_vcpis[i], struct drm_dp_mst_port, vcpi);
+ mutex_lock(&mgr->lock);
+ skip = !drm_dp_mst_port_downstream_of_branch(port, mgr->mst_primary);
+ mutex_unlock(&mgr->lock);
+
+ if (skip)
+ continue;
+
drm_dbg_kms(mgr->dev, "payload %d %d\n", i, mgr->payloads[i].payload_state);
if (mgr->payloads[i].payload_state == DP_PAYLOAD_LOCAL) {
ret = drm_dp_create_payload_step2(mgr, port, mgr->proposed_vcpis[i]->vcpi, &mgr->payloads[i]);
@@ -4574,9 +4594,18 @@ EXPORT_SYMBOL(drm_dp_mst_reset_vcpi_slots);
void drm_dp_mst_deallocate_vcpi(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_mst_port *port)
{
+ bool skip;
+
if (!port->vcpi.vcpi)
return;
+ mutex_lock(&mgr->lock);
+ skip = !drm_dp_mst_port_downstream_of_branch(port, mgr->mst_primary);
+ mutex_unlock(&mgr->lock);
+
+ if (skip)
+ return;
+
drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
port->vcpi.num_slots = 0;
port->vcpi.pbn = 0;
The patch titled
Subject: memblock: make for_each_mem_range() traverse MEMBLOCK_HOTPLUG regions
has been added to the -mm tree. Its filename is
memblock-make-for_each_mem_range-traverse-memblock_hotplug-regions.patch
This patch should soon appear at
https://ozlabs.org/~akpm/mmots/broken-out/memblock-make-for_each_mem_range-…
and later at
https://ozlabs.org/~akpm/mmotm/broken-out/memblock-make-for_each_mem_range-…
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***
The -mm tree is included into linux-next and is updated
there every 3-4 working days
------------------------------------------------------
From: Mike Rapoport <rppt(a)linux.ibm.com>
Subject: memblock: make for_each_mem_range() traverse MEMBLOCK_HOTPLUG regions
Commit b10d6bca8720 ("arch, drivers: replace for_each_membock() with
for_each_mem_range()") didn't take into account that when there is
movable_node parameter in the kernel command line, for_each_mem_range()
would skip ranges marked with MEMBLOCK_HOTPLUG.
The page table setup code in POWER uses for_each_mem_range() to create the
linear mapping of the physical memory and since the regions marked as
MEMORY_HOTPLUG are skipped, they never make it to the linear map.
A later access to the memory in those ranges will fail:
[ 2.271743] BUG: Unable to handle kernel data access on write at 0xc000000400000000
[ 2.271984] Faulting instruction address: 0xc00000000008a3c0
[ 2.272568] Oops: Kernel access of bad area, sig: 11 [#1]
[ 2.272683] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries
[ 2.273063] Modules linked in:
[ 2.273435] CPU: 0 PID: 53 Comm: kworker/u2:0 Not tainted 5.13.0 #7
[ 2.273832] NIP: c00000000008a3c0 LR: c0000000003c1ed8 CTR: 0000000000000040
[ 2.273918] REGS: c000000008a57770 TRAP: 0300 Not tainted (5.13.0)
[ 2.274036] MSR: 8000000002009033 <SF,VEC,EE,ME,IR,DR,RI,LE> CR: 84222202 XER: 20040000
[ 2.274454] CFAR: c0000000003c1ed4 DAR: c000000400000000 DSISR: 42000000 IRQMASK: 0
[ 2.274454] GPR00: c0000000003c1ed8 c000000008a57a10 c0000000019da700 c000000400000000
[ 2.274454] GPR04: 0000000000000280 0000000000000180 0000000000000400 0000000000000200
[ 2.274454] GPR08: 0000000000000100 0000000000000080 0000000000000040 0000000000000300
[ 2.274454] GPR12: 0000000000000380 c000000001bc0000 c0000000001660c8 c000000006337e00
[ 2.274454] GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[ 2.274454] GPR20: 0000000040000000 0000000020000000 c000000001a81990 c000000008c30000
[ 2.274454] GPR24: c000000008c20000 c000000001a81998 000fffffffff0000 c000000001a819a0
[ 2.274454] GPR28: c000000001a81908 c00c000001000000 c000000008c40000 c000000008a64680
[ 2.275520] NIP [c00000000008a3c0] clear_user_page+0x50/0x80
[ 2.276333] LR [c0000000003c1ed8] __handle_mm_fault+0xc88/0x1910
[ 2.276688] Call Trace:
[ 2.276839] [c000000008a57a10] [c0000000003c1e94] __handle_mm_fault+0xc44/0x1910 (unreliable)
[ 2.277142] [c000000008a57af0] [c0000000003c2c90] handle_mm_fault+0x130/0x2a0
[ 2.277331] [c000000008a57b40] [c0000000003b5f08] __get_user_pages+0x248/0x610
[ 2.277541] [c000000008a57c40] [c0000000003b848c] __get_user_pages_remote+0x12c/0x3e0
[ 2.277768] [c000000008a57cd0] [c000000000473f24] get_arg_page+0x54/0xf0
[ 2.277959] [c000000008a57d10] [c000000000474a7c] copy_string_kernel+0x11c/0x210
[ 2.278159] [c000000008a57d80] [c00000000047663c] kernel_execve+0x16c/0x220
[ 2.278361] [c000000008a57dd0] [c000000000166270] call_usermodehelper_exec_async+0x1b0/0x2f0
[ 2.278543] [c000000008a57e10] [c00000000000d5ec] ret_from_kernel_thread+0x5c/0x70
[ 2.278870] Instruction dump:
[ 2.279214] 79280fa4 79271764 79261f24 794ae8e2 7ca94214 7d683a14 7c893a14 7d893050
[ 2.279416] 7d4903a6 60000000 60000000 60000000 <7c001fec> 7c091fec 7c081fec 7c051fec
[ 2.280193] ---[ end trace 490b8c67e6075e09 ]---
Making for_each_mem_range() include MEMBLOCK_HOTPLUG regions in the
traversal fixes this issue.
Link: https://bugzilla.redhat.com/show_bug.cgi?id=1976100
Link: https://lkml.kernel.org/r/20210712071132.20902-1-rppt@kernel.org
Fixes: b10d6bca8720 ("arch, drivers: replace for_each_membock() with for_each_mem_range()")
Signed-off-by: Mike Rapoport <rppt(a)linux.ibm.com>
Tested-by: Greg Kurz <groug(a)kaod.org>
Reviewed-by: David Hildenbrand <david(a)redhat.com>
Cc: <stable(a)vger.kernel.org> [5.10+]
Signed-off-by: Andrew Morton <akpm(a)linux-foundation.org>
---
include/linux/memblock.h | 4 ++--
mm/memblock.c | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
--- a/include/linux/memblock.h~memblock-make-for_each_mem_range-traverse-memblock_hotplug-regions
+++ a/include/linux/memblock.h
@@ -209,7 +209,7 @@ static inline void __next_physmem_range(
*/
#define for_each_mem_range(i, p_start, p_end) \
__for_each_mem_range(i, &memblock.memory, NULL, NUMA_NO_NODE, \
- MEMBLOCK_NONE, p_start, p_end, NULL)
+ MEMBLOCK_HOTPLUG, p_start, p_end, NULL)
/**
* for_each_mem_range_rev - reverse iterate through memblock areas from
@@ -220,7 +220,7 @@ static inline void __next_physmem_range(
*/
#define for_each_mem_range_rev(i, p_start, p_end) \
__for_each_mem_range_rev(i, &memblock.memory, NULL, NUMA_NO_NODE, \
- MEMBLOCK_NONE, p_start, p_end, NULL)
+ MEMBLOCK_HOTPLUG, p_start, p_end, NULL)
/**
* for_each_reserved_mem_range - iterate over all reserved memblock areas
--- a/mm/memblock.c~memblock-make-for_each_mem_range-traverse-memblock_hotplug-regions
+++ a/mm/memblock.c
@@ -947,7 +947,8 @@ static bool should_skip_region(struct me
return true;
/* skip hotpluggable memory regions if needed */
- if (movable_node_is_enabled() && memblock_is_hotpluggable(m))
+ if (movable_node_is_enabled() && memblock_is_hotpluggable(m) &&
+ !(flags & MEMBLOCK_HOTPLUG))
return true;
/* if we want mirror memory skip non-mirror memory regions */
_
Patches currently in -mm which might be from rppt(a)linux.ibm.com are
memblock-make-for_each_mem_range-traverse-memblock_hotplug-regions.patch
mm-page_alloc-always-initialize-memory-map-for-the-holes.patch
microblaze-simplify-pte_alloc_one_kernel.patch
mm-introduce-memmap_alloc-to-unify-memory-map-allocation.patch
memblock-stop-poisoning-raw-allocations.patch
mm-remove-pfn_valid_within-and-config_holes_in_zone.patch
mm-memory_hotplug-cleanup-after-removal-of-pfn_valid_within.patch
Hi Greg,
thanks for applying/staging the commit for the stable release. For
kernel <= 5.11 the patch needs a small modification for the debug log.
See below. Should I send an adapted patch to stable(a)vger.kernel.org to
replace this one?
On Thu, 2021-07-15 at 16:43 +0200, gregkh(a)linuxfoundation.org wrote:
> This is a note to let you know that I've just added the patch titled
>
> media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K
>
> to the 5.10-stable tree which can be found at:
> http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=sum…
>
> The filename of the patch is:
> media-uvcvideo-fix-pixel-format-change-for-elgato-cam-link-4k.patch
> and it can be found in the queue-5.10 subdirectory.
>
> If you, or anyone else, feels it should not be added to the stable tree,
> please let <stable(a)vger.kernel.org> know about it.
>
>
> From 4c6e0976295add7f0ed94d276c04a3d6f1ea8f83 Mon Sep 17 00:00:00 2001
> From: Benjamin Drung <bdrung(a)posteo.de>
> Date: Sat, 5 Jun 2021 22:15:36 +0200
> Subject: media: uvcvideo: Fix pixel format change for Elgato Cam Link 4K
>
> From: Benjamin Drung <bdrung(a)posteo.de>
>
> commit 4c6e0976295add7f0ed94d276c04a3d6f1ea8f83 upstream.
>
> The Elgato Cam Link 4K HDMI video capture card reports to support three
> different pixel formats, where the first format depends on the connected
> HDMI device.
>
> ```
> $ v4l2-ctl -d /dev/video0 --list-formats-ext
> ioctl: VIDIOC_ENUM_FMT
> Type: Video Capture
>
> [0]: 'NV12' (Y/CbCr 4:2:0)
> Size: Discrete 3840x2160
> Interval: Discrete 0.033s (29.970 fps)
> [1]: 'NV12' (Y/CbCr 4:2:0)
> Size: Discrete 3840x2160
> Interval: Discrete 0.033s (29.970 fps)
> [2]: 'YU12' (Planar YUV 4:2:0)
> Size: Discrete 3840x2160
> Interval: Discrete 0.033s (29.970 fps)
> ```
>
> Changing the pixel format to anything besides the first pixel format
> does not work:
>
> ```
> $ v4l2-ctl -d /dev/video0 --try-fmt-video pixelformat=YU12
> Format Video Capture:
> Width/Height : 3840/2160
> Pixel Format : 'NV12' (Y/CbCr 4:2:0)
> Field : None
> Bytes per Line : 3840
> Size Image : 12441600
> Colorspace : sRGB
> Transfer Function : Rec. 709
> YCbCr/HSV Encoding: Rec. 709
> Quantization : Default (maps to Limited Range)
> Flags :
> ```
>
> User space applications like VLC might show an error message on the
> terminal in that case:
>
> ```
> libv4l2: error set_fmt gave us a different result than try_fmt!
> ```
>
> Depending on the error handling of the user space applications, they
> might display a distorted video, because they use the wrong pixel format
> for decoding the stream.
>
> The Elgato Cam Link 4K responds to the USB video probe
> VS_PROBE_CONTROL/VS_COMMIT_CONTROL with a malformed data structure: The
> second byte contains bFormatIndex (instead of being the second byte of
> bmHint). The first byte is always zero. The third byte is always 1.
>
> The firmware bug was reported to Elgato on 2020-12-01 and it was
> forwarded by the support team to the developers as feature request.
> There is no firmware update available since then. The latest firmware
> for Elgato Cam Link 4K as of 2021-03-23 has MCU 20.02.19 and FPGA 67.
>
> Therefore correct the malformed data structure for this device. The
> change was successfully tested with VLC, OBS, and Chromium using
> different pixel formats (YUYV, NV12, YU12), resolutions (3840x2160,
> 1920x1080), and frame rates (29.970 and 59.940 fps).
>
> Cc: stable(a)vger.kernel.org
> Signed-off-by: Benjamin Drung <bdrung(a)posteo.de>
> Signed-off-by: Laurent Pinchart <laurent.pinchart(a)ideasonboard.com>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei(a)kernel.org>
> Signed-off-by: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
> ---
> drivers/media/usb/uvc/uvc_video.c | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)
>
> --- a/drivers/media/usb/uvc/uvc_video.c
> +++ b/drivers/media/usb/uvc/uvc_video.c
> @@ -124,10 +124,37 @@ int uvc_query_ctrl(struct uvc_device *de
> static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
> struct uvc_streaming_control *ctrl)
> {
> + static const struct usb_device_id elgato_cam_link_4k = {
> + USB_DEVICE(0x0fd9, 0x0066)
> + };
> struct uvc_format *format = NULL;
> struct uvc_frame *frame = NULL;
> unsigned int i;
>
> + /*
> + * The response of the Elgato Cam Link 4K is incorrect: The second byte
> + * contains bFormatIndex (instead of being the second byte of bmHint).
> + * The first byte is always zero. The third byte is always 1.
> + *
> + * The UVC 1.5 class specification defines the first five bits in the
> + * bmHint bitfield. The remaining bits are reserved and should be zero.
> + * Therefore a valid bmHint will be less than 32.
> + *
> + * Latest Elgato Cam Link 4K firmware as of 2021-03-23 needs this fix.
> + * MCU: 20.02.19, FPGA: 67
> + */
> + if (usb_match_one_id(stream->dev->intf, &elgato_cam_link_4k) &&
> + ctrl->bmHint > 255) {
> + u8 corrected_format_index = ctrl->bmHint >> 8;
> +
> + /* uvc_dbg(stream->dev, VIDEO,
Instead of commenting out the debug log, this line needs to be replaced by:
uvc_trace(UVC_TRACE_VIDEO,
> + "Correct USB video probe response from {bmHint: 0x%04x, bFormatIndex: %u} to {bmHint: 0x%04x, bFormatIndex: %u}\n",
> + ctrl->bmHint, ctrl->bFormatIndex,
> + 1, corrected_format_index); */
> + ctrl->bmHint = 1;
> + ctrl->bFormatIndex = corrected_format_index;
> + }
> +
> for (i = 0; i < stream->nformats; ++i) {
> if (stream->format[i].index == ctrl->bFormatIndex) {
> format = &stream->format[i];
>
>
> Patches currently in stable-queue which might be from bdrung(a)posteo.de are
>
> queue-5.10/media-uvcvideo-fix-pixel-format-change-for-elgato-cam-link-4k.patch