* Re: [PATCH v2 3/3] arm64: dts: exynos850: Add ap2apm mailbox
From: Alexey Klimov @ 2026-04-02 13:30 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
linux-kernel
In-Reply-To: <20260402-free-foamy-gibbon-acad72@quoll>
On Thu Apr 2, 2026 at 9:01 AM BST, Krzysztof Kozlowski wrote:
> On Thu, Apr 02, 2026 at 03:20:16AM +0100, Alexey Klimov wrote:
>> Add mailbox node that describes AP-to-APM mailbox, that can be
>> used for communicating with APM co-processor on Exynos850 SoCs.
>>
>> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
>> ---
>> arch/arm64/boot/dts/exynos/exynos850.dtsi | 9 +++++++++
>
> What DTS is doing in the middle of the patchset? If there is going to be
> resend, then fix the order. If the order is intended, then most likely
> NAK but I need somewhere explanation (but I really do not see the need
> for it).
>
> Please read submitting patches (both documents).
The dts change goes last in this series, the commit 3 out of 3.
There is no DTS changes in the middle of the patchset as far as I can
trust my eyes.
If the order in this series is NACK, please explain why.
I suspect that potential confusion is because 2 clock patches from
prev series were accepted/merged, so dts change shifted from its 5th
place to 3-rd place.
BR,
Alexey.
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: exynos850: Add ap2apm mailbox
From: Krzysztof Kozlowski @ 2026-04-02 13:32 UTC (permalink / raw)
To: Alexey Klimov
Cc: Sylwester Nawrocki, Chanwoo Choi, Alim Akhtar, Sam Protsenko,
Michael Turquette, Stephen Boyd, Rob Herring, Conor Dooley,
Tudor Ambarus, Jassi Brar, Krzysztof Kozlowski, Peter Griffin,
linux-samsung-soc, linux-arm-kernel, linux-clk, devicetree,
linux-kernel
In-Reply-To: <DHIPEQ4XDUI6.297HDXTP84FFP@linaro.org>
On 02/04/2026 15:30, Alexey Klimov wrote:
> On Thu Apr 2, 2026 at 9:01 AM BST, Krzysztof Kozlowski wrote:
>> On Thu, Apr 02, 2026 at 03:20:16AM +0100, Alexey Klimov wrote:
>>> Add mailbox node that describes AP-to-APM mailbox, that can be
>>> used for communicating with APM co-processor on Exynos850 SoCs.
>>>
>>> Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
>>> ---
>>> arch/arm64/boot/dts/exynos/exynos850.dtsi | 9 +++++++++
>>
>> What DTS is doing in the middle of the patchset? If there is going to be
>> resend, then fix the order. If the order is intended, then most likely
>> NAK but I need somewhere explanation (but I really do not see the need
>> for it).
>>
>> Please read submitting patches (both documents).
>
> The dts change goes last in this series, the commit 3 out of 3.
> There is no DTS changes in the middle of the patchset as far as I can
> trust my eyes.
>
> If the order in this series is NACK, please explain why.
> I suspect that potential confusion is because 2 clock patches from
> prev series were accepted/merged, so dts change shifted from its 5th
> place to 3-rd place.
Oops, It is at the end! mutt does not order them by default when loaded
via b4, so it appeared in the middle and I did not pay attention enough.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v3] KVM: arm64: Prevent the host from using an smc with imm16 != 0
From: Marc Zyngier @ 2026-04-02 13:35 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, linux-kernel, android-kvm,
Sebastian Ene
Cc: catalin.marinas, joey.gouly, mark.rutland, oupton, suzuki.poulose,
tabba, vdonnefort, will, yuzenghui
In-Reply-To: <20260330105441.3226904-1-sebastianene@google.com>
On Mon, 30 Mar 2026 10:54:41 +0000, Sebastian Ene wrote:
> The ARM Service Calling Convention (SMCCC) specifies that the function
> identifier and parameters should be passed in registers, leaving the
> 16-bit immediate field un-handled in pKVM when an SMC instruction is
> trapped.
> Since the HVC is a private interface between EL2 and the host,
> enforce the host kernel running under pKVM to use an immediate value
> of 0 only when using SMCs to make it clear for non-compliant software
> talking to Trustzone that we only use SMCCC.
>
> [...]
Applied to next, thanks!
[1/1] KVM: arm64: Prevent the host from using an smc with imm16 != 0
commit: cf6348af645bd8e38758114e6afcc406c5bb515f
Cheers,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH 0/2] KVM: arm64: Tentative fixes for page-table lifetime issues
From: Marc Zyngier @ 2026-04-02 13:36 UTC (permalink / raw)
To: kvmarm, Will Deacon
Cc: linux-arm-kernel, Oliver Upton, Joey Gouly, Suzuki K Poulose,
Zenghui Yu
In-Reply-To: <20260327192758.21739-1-will@kernel.org>
On Fri, 27 Mar 2026 19:27:55 +0000, Will Deacon wrote:
> Sashiko highlighted a couple of potential page-table lifetime issues
> in the upstream code while it was reviewing the pKVM protected memory
> series. They make sense to me so I've had a crack at fixing them and
> writing a better description of the problem in the commit message.
>
> For the second issue, I've tested it by forcing the notifier
> registration to fail and then watching the SecPageTables line in
> /proc/meminfo after attempting to create VMs.
>
> [...]
Applied to next, thanks!
[1/2] KVM: arm64: Don't leave mmu->pgt dangling on kvm_init_stage2_mmu() error
commit: 2fc0f3e2b9a9f397554ffe86e8f6eb0e2507ec6e
[2/2] KVM: arm64: Destroy stage-2 page-table in kvm_arch_destroy_vm()
commit: a3ca3bfd01b7ee9f54ed85718a6d553cdd87050e
Cheers,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH] KVM: arm64: selftests: Avoid testing the IMPDEF behavior
From: Marc Zyngier @ 2026-04-02 13:37 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, Zenghui Yu; +Cc: oupton, joey.gouly, suzuki.poulose
In-Reply-To: <20260317131558.52751-1-zenghui.yu@linux.dev>
On Tue, 17 Mar 2026 21:15:58 +0800, Zenghui Yu wrote:
> It turned out that we can't really force KVM to use the "slow" path when
> emulating AT instructions [1]. We should therefore avoid testing the IMPDEF
> behavior (i.e., TEST_ACCESS_FLAG - address translation instructions are
> permitted to update AF but not required).
>
> Remove it and improve the comment a bit.
>
> [...]
Applied to next, thanks!
[1/1] KVM: arm64: selftests: Avoid testing the IMPDEF behavior
commit: 03db5f05d4c76d76b32a9d26001e2ec6252f74f8
Cheers,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH] KVM: arm64: vgic-v5: Fold PPI state for all exposed PPIs
From: Marc Zyngier @ 2026-04-02 13:37 UTC (permalink / raw)
To: linux-arm-kernel, kvmarm, kvm, Sascha Bischoff
Cc: nd, Joey Gouly, Suzuki Poulose, yuzenghui, broonie, Oliver Upton
In-Reply-To: <20260401162152.932243-1-sascha.bischoff@arm.com>
On Wed, 01 Apr 2026 16:21:57 +0000, Sascha Bischoff wrote:
> GICv5 supports up to 128 PPIs, which would introduce a large amount of
> overhead if all of them were actively tracked. Rather than keeping
> track of all 128 potential PPIs, we instead only consider the set of
> architected PPIs (the first 64). Moreover, we further reduce that set
> by only exposing a subset of the PPIs to a guest. In practice, this
> means that only 4 PPIs are typically exposed to a guest - the SW_PPI,
> PMUIRQ, and the timers.
>
> [...]
Applied to next, thanks!
[1/1] KVM: arm64: vgic-v5: Fold PPI state for all exposed PPIs
commit: 9c1ac77ddfc90b6292ef63a4fa5ab6f9e4b29981
Cheers,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH] KVM: arm64: Advertise ID_AA64PFR2_EL1.GCIE
From: Marc Zyngier @ 2026-04-02 13:37 UTC (permalink / raw)
To: kvmarm, linux-arm-kernel, Marc Zyngier
Cc: Joey Gouly, Suzuki K Poulose, Oliver Upton, Zenghui Yu,
Sascha Bischoff, Will Deacon, Catalin Marinas
In-Reply-To: <20260401170017.369529-1-maz@kernel.org>
On Wed, 01 Apr 2026 18:00:17 +0100, Marc Zyngier wrote:
> As we are missing ID_AA64PFR2_EL1.GCIE from the kernel feature set,
> userspace cannot write ID_AA64PFR2_EL1 with GCIE set, even if we are
> on a GICv5 host.
>
> Add the required field description.
>
>
> [...]
Applied to next, thanks!
[1/1] KVM: arm64: Advertise ID_AA64PFR2_EL1.GCIE
commit: 899ff451fcee1289f3f37d061da66c3e38748a69
Cheers,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply
* Re: [PATCH] arm64: dts: imx{91,93}-phyboard-segin: Add peb-av-18 overlay
From: Frank Li @ 2026-04-02 13:50 UTC (permalink / raw)
To: Florijan Plohl
Cc: Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, imx, linux-arm-kernel,
devicetree, linux-kernel, upstream
In-Reply-To: <20260402070826.970012-1-florijan.plohl@norik.com>
On Thu, Apr 02, 2026 at 09:08:26AM +0200, Florijan Plohl wrote:
> Add overlay for the PEB-AV-18 adapter on phyBOARD-Segin-i.MX91/93.
what's means PEB-AV-18? Is it random board name?
> The supported LCD is Powertip PH800480T032-ZHC19 panel (AC220).
>
> Signed-off-by: Florijan Plohl <florijan.plohl@norik.com>
> ---
> arch/arm64/boot/dts/freescale/Makefile | 4 +
> .../imx91-phyboard-segin-peb-av-18.dtso | 142 ++++++++++++++++++
> .../imx93-phyboard-segin-peb-av-18.dtso | 142 ++++++++++++++++++
Any difference between 91 and 93, can use one overlay file?
Frank
> --
> 2.43.0
>
^ permalink raw reply
* Re: [PATCH v2 6/7] MAINTAINERS: add exynos850-pmu.c to Exynos850 entry
From: Alexey Klimov @ 2026-04-02 13:57 UTC (permalink / raw)
To: Sam Protsenko, Krzysztof Kozlowski
Cc: linux-samsung-soc, Peter Griffin, André Draszik,
Conor Dooley, Alim Akhtar, Tudor Ambarus, Rob Herring,
Krzysztof Kozlowski, linux-arm-kernel, devicetree, linux-kernel
In-Reply-To: <CAPLW+4=H_UkjwY2RJFPD9ekJh05MyuhKrymeuUYC4dX1WzF0wg@mail.gmail.com>
On Wed Apr 1, 2026 at 5:16 PM BST, Sam Protsenko wrote:
> Hi Krzysztof,
>
> On Wed, Apr 1, 2026 at 9:28 AM Krzysztof Kozlowski <krzk@kernel.org> wrote:
>>
>> On 01/04/2026 06:51, Alexey Klimov wrote:
>> > Update Exynos850 entry to include new file
>> > drivers/soc/samsung/exynos850-pmu.c. Add myself as M
>> > there.
>> >
>> > Signed-off-by: Alexey Klimov <alexey.klimov@linaro.org>
>> > ---
>> > MAINTAINERS | 2 ++
>> > 1 file changed, 2 insertions(+)
>> >
>> > diff --git a/MAINTAINERS b/MAINTAINERS
>> > index e14e6f874e05..4b28e92b4d9b 100644
>> > --- a/MAINTAINERS
>> > +++ b/MAINTAINERS
>> > @@ -23601,6 +23601,7 @@ F: include/dt-bindings/clock/samsung,exynos2200-cmu.h
>> >
>> > SAMSUNG EXYNOS850 SoC SUPPORT
>> > M: Sam Protsenko <semen.protsenko@linaro.org>
>> > +M: Alexey Klimov <alexey.klimov@linaro.org>
>>
>> I am surprised to see this because I did not find many reviews from your
>> side before.
>>
>
> It was me who advised Alexey to add himself on the list, as he's doing
> a lot of Exynos850 related work nowadays, and we expect him to
> continue doing that. If you think it's too early, let's get back to
> this once there are more patches submitted under his name.
>
> Thanks!
>
>> Please first engage in reviewing of this platform, before assigning
>> yourself as a maintainer.
Okay, so it was done after Sam's advice. I can do one of these options:
- drop this patch;
- move it into separate entry in maintainers file;
- something else, please suggest.
I don't fancy having loose files (first option).
Best regards,
Alexey.
^ permalink raw reply
* [PATCH 6.1.y v2 1/6] Revert "nvme: fix admin request_queue lifetime"
From: Heyne, Maximilian @ 2026-04-02 13:57 UTC (permalink / raw)
To: stable@vger.kernel.org
Cc: Heyne, Maximilian, Jens Axboe, Hector Martin, Sven Peter,
Alyssa Rosenzweig, Keith Busch, Christoph Hellwig, Sagi Grimberg,
James E.J. Bottomley, Martin K. Petersen, Alim Akhtar,
Avri Altman, Bart Van Assche, Sasha Levin, Peter Wang,
Greg Kroah-Hartman, Seunghwan Baek, Thomas Yen, Adrian Hunter,
Wonkon Kim, Brian Kao, Seunghui Lee, Sanjeev Yadav,
Hannes Reinecke, Ming Lei, Chaitanya Kulkarni,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org
In-Reply-To: <20260402-moral-jockey-f072379b@mheyne-amazon>
This reverts commit ff037b5f47eeccc1636c03f84cd47db094eb73c9.
The backport of upstream commit 03b3bcd319b3 ("nvme: fix admin
request_queue lifetime") to 6.1 is broken in 2 ways. First of all it
doesn't actually fix the issue because blk_put_queue will still be
called as part of blk_mq_destroy_queue in nvme_remove_admin_tag_set
leading to the UAF.
Second, the backport leads to a refcount underflow when unbinding a pci
nvme device:
refcount_t: underflow; use-after-free.
WARNING: CPU: 2 PID: 1486 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110
Modules linked in: bochs drm_vram_helper simpledrm skx_edac_common drm_shmem_helper drm_kms_helper kvm_intel cfbfillrect syscopyarea cfbimgblt sysfillrect sysimgblt fb_sys_fops cfbcopyarea drm_ttm_helper fb ttm kvm fbdev drm mousedev nls_ascii psmouse irqbypass nls_cp437 atkbd crc32_pclmul crc32c_intel libps2 vfat fat sunrpc virtio_net ata_piix vivaldi_fmap drm_panel_orientation_quirks libata backlight i2c_piix4 net_failover i8042 ghash_clmulni_intel failover serio i2c_core button sch_fq_codel
CPU: 2 PID: 1486 Comm: bash Not tainted 6.1.167 #2
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS edk2-20240813-306.amzn2 08/13/2024
RIP: 0010:refcount_warn_saturate+0xba/0x110
Code: 01 01 e8 89 79 ad ff 0f 0b e9 82 f4 7e 00 80 3d 73 03 cc 01 00 75 85 48 c7 c7 e0 5d 3b 8e c6 05 63 03 cc 01 01 e8 66 79 ad ff <0f> 0b c3 cc cc cc cc 80 3d 4e 03 cc 01 00 0f 85 5e ff ff ff 48 c7
RSP: 0018:ffffd0cc011bfd18 EFLAGS: 00010286
RAX: 0000000000000000 RBX: ffff8ada07b33210 RCX: 0000000000000027
RDX: ffff8adb37d1f728 RSI: 0000000000000001 RDI: ffff8adb37d1f720
RBP: ffff8ada07b33000 R08: 0000000000000000 R09: 00000000fffeffff
R10: ffffd0cc011bfba8 R11: ffffffff8f1781a8 R12: ffffd0cc011bfd38
R13: ffff8ada03080800 R14: ffff8ada07b33210 R15: ffff8ada07b33b10
FS: 00007f50f6964740(0000) GS:ffff8adb37d00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 000055cdb54e6ae0 CR3: 000000010224e001 CR4: 0000000000770ee0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
<TASK>
nvme_pci_free_ctrl+0x45/0x80
nvme_free_ctrl+0x1aa/0x2b0
device_release+0x34/0x90
kobject_cleanup+0x3a/0x130
pci_device_remove+0x3e/0xb0
device_release_driver_internal+0x1aa/0x230
unbind_store+0x11f/0x130
kernfs_fop_write_iter+0x13a/0x1d0
vfs_write+0x2a6/0x3b0
ksys_write+0x5f/0xe0
do_syscall_64+0x35/0x80
entry_SYSCALL_64_after_hwframe+0x6e/0xd8
RIP: 0033:0x7f50f66ff897
Code: 0f 00 f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b7 0f 1f 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 51 c3 48 83 ec 28 48 89 54 24 18 48 89 74 24
RSP: 002b:00007fffaef903d8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007f50f67fd780 RCX: 00007f50f66ff897
RDX: 000000000000000d RSI: 0000557f72ef6b90 RDI: 0000000000000001
RBP: 000000000000000d R08: 0000000000000000 R09: 00007f50f67b2d20
R10: 00007f50f67b2c20 R11: 0000000000000246 R12: 000000000000000d
R13: 0000557f72ef6b90 R14: 000000000000000d R15: 00007f50f67f89c0
</TASK>
The reason for this is that nvme_free_ctrl calls ->free_ctrl which
resolves to nvme_pci_free_ctrl in aforementioned case which also has a
blk_put_queue, so the admin queue is put twice. This is because on 6.1
we're missing the commit 96ef1be53663 ("nvme-pci: put the admin queue in
nvme_dev_remove_admin").
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
---
drivers/nvme/host/core.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 9df33b293ee3e..938af571dc13e 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -5180,8 +5180,6 @@ static void nvme_free_ctrl(struct device *dev)
container_of(dev, struct nvme_ctrl, ctrl_device);
struct nvme_subsystem *subsys = ctrl->subsys;
- if (ctrl->admin_q)
- blk_put_queue(ctrl->admin_q);
if (!subsys || ctrl->instance != subsys->instance)
ida_free(&nvme_instance_ida, ctrl->instance);
--
2.50.1
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related
* [PATCH 6.1.y v2 0/6] nvme: correctly fix admin request_queue lifetime
From: Heyne, Maximilian @ 2026-04-02 13:57 UTC (permalink / raw)
To: stable@vger.kernel.org
Cc: Heyne, Maximilian, Jens Axboe, Hector Martin, Sven Peter,
Alyssa Rosenzweig, Keith Busch, Christoph Hellwig, Sagi Grimberg,
James E.J. Bottomley, Martin K. Petersen, Alim Akhtar,
Avri Altman, Bart Van Assche, Sasha Levin, Peter Wang,
Greg Kroah-Hartman, Adrian Hunter, Seunghwan Baek, Seunghui Lee,
Thomas Yen, Brian Kao, Sanjeev Yadav, Wonkon Kim,
Chaitanya Kulkarni, Hannes Reinecke, Ming Lei,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org
The initial attempt to backport upstream commit 03b3bcd319b3 ("nvme: fix
admin request_queue lifetime") was not correct leading to refcount
underflows and not even fixing the problem.
I've tested the reproduction steps from [1] (adding a delay to
nvme_submit_user_cmd and 'echo 1 | sudo tee
/sys/class/nvme/nvme0/delete_controller') on the nvme-tcp driver which
printed the KASAN UAF blurb.
Fixing the issue in the 6.1 series requires a few dependent patches.
This is mainly the upstream commit 2b3f056f72e5 ("blk-mq: move the call
to blk_put_queue out of blk_mq_destroy_queue") which allows to move the
blk_put_queue to a different location.
The backport of commit 03b3bcd319b3 ("nvme: fix admin
request_queue lifetime") needed a tweak to the nvme pci driver.
Furthermore, in this patch series I've also included a follow-up fixup
from upstream commit b84bb7bd913d ("nvme: fix admin queue leak on
controller reset"), again with an adaption to the nvme pci driver. This
issue could easily be reproduced by resetting the controller (no need to
run full blktests):
echo 1 > /sys/class/nvme/nvme0/reset_controller
[1] https://lore.kernel.org/all/20251029210853.20768-1-cachen@purestorage.com/
---
Changes in v2:
- dropped 2 patches from the series that are unnecessary (scsi and
apple). The apple-nvme patch was even wrong (Thanks Fedor for
pointing that out)
Christoph Hellwig (3):
blk-mq: move the call to blk_put_queue out of blk_mq_destroy_queue
nvme-pci: remove an extra queue reference
nvme-pci: put the admin queue in nvme_dev_remove_admin
Keith Busch (1):
nvme: fix admin request_queue lifetime
Maximilian Heyne (1):
Revert "nvme: fix admin request_queue lifetime"
Ming Lei (1):
nvme: fix admin queue leak on controller reset
block/blk-mq.c | 4 +---
block/bsg-lib.c | 2 ++
drivers/nvme/host/apple.c | 1 +
drivers/nvme/host/core.c | 16 ++++++++++++++--
drivers/nvme/host/pci.c | 14 +++++++-------
drivers/scsi/scsi_sysfs.c | 1 +
drivers/ufs/core/ufshcd.c | 2 ++
7 files changed, 28 insertions(+), 12 deletions(-)
--
2.50.1
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply
* [PATCH 6.1.y v2 2/6] blk-mq: move the call to blk_put_queue out of blk_mq_destroy_queue
From: Heyne, Maximilian @ 2026-04-02 13:57 UTC (permalink / raw)
To: stable@vger.kernel.org
Cc: Heyne, Maximilian, Christoph Hellwig, Sagi Grimberg,
Chaitanya Kulkarni, Keith Busch, Jens Axboe, Hector Martin,
Sven Peter, Alyssa Rosenzweig, James E.J. Bottomley,
Martin K. Petersen, Alim Akhtar, Avri Altman, Bart Van Assche,
Sasha Levin, Peter Wang, Greg Kroah-Hartman, Adrian Hunter,
Thomas Yen, Brian Kao, Seunghui Lee, Sanjeev Yadav, Wonkon Kim,
Ming Lei, Hannes Reinecke, linux-block@vger.kernel.org,
linux-kernel@vger.kernel.org, asahi@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org
In-Reply-To: <20260402-moral-jockey-f072379b@mheyne-amazon>
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit 2b3f056f72e56fa07df69b4705e0b46a6c08e77c ]
The fact that blk_mq_destroy_queue also drops a queue reference leads
to various places having to grab an extra reference. Move the call to
blk_put_queue into the callers to allow removing the extra references.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Link: https://lore.kernel.org/r/20221018135720.670094-2-hch@lst.de
[axboe: fix fabrics_q vs admin_q conflict in nvme core.c]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Stable-dep-of: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime")
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
---
block/blk-mq.c | 4 +---
block/bsg-lib.c | 2 ++
drivers/nvme/host/apple.c | 1 +
drivers/nvme/host/core.c | 10 ++++++++--
drivers/nvme/host/pci.c | 1 +
drivers/scsi/scsi_sysfs.c | 1 +
drivers/ufs/core/ufshcd.c | 2 ++
7 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index a9697541d67f9..8b9e5ca398242 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -4194,9 +4194,6 @@ void blk_mq_destroy_queue(struct request_queue *q)
blk_sync_queue(q);
blk_mq_cancel_work_sync(q);
blk_mq_exit_queue(q);
-
- /* @q is and will stay empty, shutdown and put */
- blk_put_queue(q);
}
EXPORT_SYMBOL(blk_mq_destroy_queue);
@@ -4213,6 +4210,7 @@ struct gendisk *__blk_mq_alloc_disk(struct blk_mq_tag_set *set, void *queuedata,
disk = __alloc_disk_node(q, set->numa_node, lkclass);
if (!disk) {
blk_mq_destroy_queue(q);
+ blk_put_queue(q);
return ERR_PTR(-ENOMEM);
}
set_bit(GD_OWNS_QUEUE, &disk->state);
diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index d6f5dcdce748c..435c32373cd68 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -325,6 +325,7 @@ void bsg_remove_queue(struct request_queue *q)
bsg_unregister_queue(bset->bd);
blk_mq_destroy_queue(q);
+ blk_put_queue(q);
blk_mq_free_tag_set(&bset->tag_set);
kfree(bset);
}
@@ -400,6 +401,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name,
return q;
out_cleanup_queue:
blk_mq_destroy_queue(q);
+ blk_put_queue(q);
out_queue:
blk_mq_free_tag_set(set);
out_tag_set:
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c
index 262d2b60ac6dd..c5fc293c22123 100644
--- a/drivers/nvme/host/apple.c
+++ b/drivers/nvme/host/apple.c
@@ -1510,6 +1510,7 @@ static int apple_nvme_probe(struct platform_device *pdev)
if (!blk_get_queue(anv->ctrl.admin_q)) {
nvme_start_admin_queue(&anv->ctrl);
blk_mq_destroy_queue(anv->ctrl.admin_q);
+ blk_put_queue(anv->ctrl.admin_q);
anv->ctrl.admin_q = NULL;
ret = -ENODEV;
goto put_dev;
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 938af571dc13e..044e1a9c099b3 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -5031,6 +5031,7 @@ int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set,
out_cleanup_admin_q:
blk_mq_destroy_queue(ctrl->admin_q);
+ blk_put_queue(ctrl->admin_q);
out_free_tagset:
blk_mq_free_tag_set(set);
ctrl->admin_q = NULL;
@@ -5042,8 +5043,11 @@ EXPORT_SYMBOL_GPL(nvme_alloc_admin_tag_set);
void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl)
{
blk_mq_destroy_queue(ctrl->admin_q);
- if (ctrl->ops->flags & NVME_F_FABRICS)
+ blk_put_queue(ctrl->admin_q);
+ if (ctrl->ops->flags & NVME_F_FABRICS) {
blk_mq_destroy_queue(ctrl->fabrics_q);
+ blk_put_queue(ctrl->fabrics_q);
+ }
blk_mq_free_tag_set(ctrl->admin_tagset);
}
EXPORT_SYMBOL_GPL(nvme_remove_admin_tag_set);
@@ -5099,8 +5103,10 @@ EXPORT_SYMBOL_GPL(nvme_alloc_io_tag_set);
void nvme_remove_io_tag_set(struct nvme_ctrl *ctrl)
{
- if (ctrl->ops->flags & NVME_F_FABRICS)
+ if (ctrl->ops->flags & NVME_F_FABRICS) {
blk_mq_destroy_queue(ctrl->connect_q);
+ blk_put_queue(ctrl->connect_q);
+ }
blk_mq_free_tag_set(ctrl->tagset);
}
EXPORT_SYMBOL_GPL(nvme_remove_io_tag_set);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 518f8c5012bdf..727585f580362 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1782,6 +1782,7 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev)
*/
nvme_start_admin_queue(&dev->ctrl);
blk_mq_destroy_queue(dev->ctrl.admin_q);
+ blk_put_queue(dev->ctrl.admin_q);
blk_mq_free_tag_set(&dev->admin_tagset);
}
}
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 456b92c3a7811..af81b2ba0c9b3 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1486,6 +1486,7 @@ void __scsi_remove_device(struct scsi_device *sdev)
mutex_unlock(&sdev->state_mutex);
blk_mq_destroy_queue(sdev->request_queue);
+ blk_put_queue(sdev->request_queue);
kref_put(&sdev->host->tagset_refcnt, scsi_mq_free_tags);
cancel_work_sync(&sdev->requeue_work);
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index f72ba0b206437..a39ffc62d88a1 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -9651,6 +9651,7 @@ void ufshcd_remove(struct ufs_hba *hba)
ufshpb_remove(hba);
ufs_sysfs_remove_nodes(hba->dev);
blk_mq_destroy_queue(hba->tmf_queue);
+ blk_put_queue(hba->tmf_queue);
blk_mq_free_tag_set(&hba->tmf_tag_set);
scsi_remove_host(hba->host);
/* disable interrupts */
@@ -9953,6 +9954,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
free_tmf_queue:
blk_mq_destroy_queue(hba->tmf_queue);
+ blk_put_queue(hba->tmf_queue);
free_tmf_tag_set:
blk_mq_free_tag_set(&hba->tmf_tag_set);
out_remove_scsi_host:
--
2.50.1
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related
* [PATCH 6.1.y v2 3/6] nvme-pci: remove an extra queue reference
From: Heyne, Maximilian @ 2026-04-02 13:57 UTC (permalink / raw)
To: stable@vger.kernel.org
Cc: Heyne, Maximilian, Christoph Hellwig, Sagi Grimberg,
Chaitanya Kulkarni, Keith Busch, Jens Axboe, Hector Martin,
Sven Peter, Alyssa Rosenzweig, James E.J. Bottomley,
Martin K. Petersen, Alim Akhtar, Avri Altman, Bart Van Assche,
Sasha Levin, Peter Wang, Greg Kroah-Hartman, Sanjeev Yadav,
Adrian Hunter, Seunghwan Baek, Brian Kao, Seunghui Lee,
Wonkon Kim, Hannes Reinecke, Ming Lei,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org
In-Reply-To: <20260402-moral-jockey-f072379b@mheyne-amazon>
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit 7dcebef90d35de13a326f765dd787538880566f9 ]
Now that blk_mq_destroy_queue does not release the queue reference, there
is no need for a second admin queue reference to be held by the nvme_dev.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Link: https://lore.kernel.org/r/20221018135720.670094-4-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Stable-dep-of: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime")
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
---
drivers/nvme/host/pci.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 727585f580362..13c0098939ec0 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1782,7 +1782,6 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev)
*/
nvme_start_admin_queue(&dev->ctrl);
blk_mq_destroy_queue(dev->ctrl.admin_q);
- blk_put_queue(dev->ctrl.admin_q);
blk_mq_free_tag_set(&dev->admin_tagset);
}
}
@@ -1811,11 +1810,6 @@ static int nvme_pci_alloc_admin_tag_set(struct nvme_dev *dev)
dev->ctrl.admin_q = NULL;
return -ENOMEM;
}
- if (!blk_get_queue(dev->ctrl.admin_q)) {
- nvme_dev_remove_admin(dev);
- dev->ctrl.admin_q = NULL;
- return -ENODEV;
- }
return 0;
}
--
2.50.1
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related
* [PATCH 6.1.y v2 4/6] nvme-pci: put the admin queue in nvme_dev_remove_admin
From: Heyne, Maximilian @ 2026-04-02 13:57 UTC (permalink / raw)
To: stable@vger.kernel.org
Cc: Heyne, Maximilian, Christoph Hellwig, Keith Busch, Sagi Grimberg,
Chaitanya Kulkarni, Jens Axboe, Hector Martin, Sven Peter,
Alyssa Rosenzweig, James E.J. Bottomley, Martin K. Petersen,
Alim Akhtar, Avri Altman, Bart Van Assche, Sasha Levin,
Peter Wang, Greg Kroah-Hartman, Thomas Yen, Brian Kao,
Sanjeev Yadav, Wonkon Kim, Seunghui Lee, Ming Lei,
Hannes Reinecke, linux-block@vger.kernel.org,
linux-kernel@vger.kernel.org, asahi@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org
In-Reply-To: <20260402-moral-jockey-f072379b@mheyne-amazon>
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit 96ef1be53663a9343dffcf106e2f1b59da4b8799 ]
Once the controller is shutdown no one can access the admin queue. Tear
it down in nvme_dev_remove_admin, which matches the flow in the other
drivers.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Tested-by Gerd Bayer <gbayer@linxu.ibm.com>
Stable-dep-of: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime")
[ Context change due to missing commit 94cc781f69f4 ("nvme: move OPAL
setup from PCIe to core")]
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
---
drivers/nvme/host/pci.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 13c0098939ec0..38732c0c28bbb 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1782,6 +1782,7 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev)
*/
nvme_start_admin_queue(&dev->ctrl);
blk_mq_destroy_queue(dev->ctrl.admin_q);
+ blk_put_queue(dev->ctrl.admin_q);
blk_mq_free_tag_set(&dev->admin_tagset);
}
}
@@ -2831,8 +2832,6 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
nvme_dbbuf_dma_free(dev);
nvme_free_tagset(dev);
- if (dev->ctrl.admin_q)
- blk_put_queue(dev->ctrl.admin_q);
free_opal_dev(dev->ctrl.opal_dev);
mempool_destroy(dev->iod_mempool);
put_device(dev->dev);
--
2.50.1
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related
* [PATCH 6.1.y v2 6/6] nvme: fix admin queue leak on controller reset
From: Heyne, Maximilian @ 2026-04-02 13:57 UTC (permalink / raw)
To: stable@vger.kernel.org
Cc: Heyne, Maximilian, Ming Lei, Keith Busch, Yi Zhang, Jens Axboe,
Hector Martin, Sven Peter, Alyssa Rosenzweig, Christoph Hellwig,
Sagi Grimberg, James E.J. Bottomley, Martin K. Petersen,
Alim Akhtar, Avri Altman, Bart Van Assche, Sasha Levin,
Peter Wang, Greg Kroah-Hartman, Seunghwan Baek, Seunghui Lee,
Adrian Hunter, Brian Kao, Sanjeev Yadav, Wonkon Kim,
Chaitanya Kulkarni, Hannes Reinecke, linux-block@vger.kernel.org,
linux-kernel@vger.kernel.org, asahi@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org
In-Reply-To: <20260402-moral-jockey-f072379b@mheyne-amazon>
From: Ming Lei <ming.lei@redhat.com>
[ Upstream commit b84bb7bd913d8ca2f976ee6faf4a174f91c02b8d ]
When nvme_alloc_admin_tag_set() is called during a controller reset,
a previous admin queue may still exist. Release it properly before
allocating a new one to avoid orphaning the old queue.
This fixes a regression introduced by commit 03b3bcd319b3 ("nvme: fix
admin request_queue lifetime").
Cc: Keith Busch <kbusch@kernel.org>
Fixes: 03b3bcd319b3 ("nvme: fix admin request_queue lifetime").
Reported-and-tested-by: Yi Zhang <yi.zhang@redhat.com>
Closes: https://lore.kernel.org/linux-block/CAHj4cs9wv3SdPo+N01Fw2SHBYDs9tj2M_e1-GdQOkRy=DsBB1w@mail.gmail.com/
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
[ Have to do analogous work in nvme_pci_alloc_admin_tag_set in pci.c due
to missing upstream commit 0da7feaa5913 ("nvme-pci: use the tagset
alloc/free helpers") ]
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
---
drivers/nvme/host/core.c | 7 +++++++
drivers/nvme/host/pci.c | 7 +++++++
2 files changed, 14 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f17318f6c82b0..09439fa7d083a 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -5012,6 +5012,13 @@ int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set,
if (ret)
return ret;
+ /*
+ * If a previous admin queue exists (e.g., from before a reset),
+ * put it now before allocating a new one to avoid orphaning it.
+ */
+ if (ctrl->admin_q)
+ blk_put_queue(ctrl->admin_q);
+
ctrl->admin_q = blk_mq_init_queue(set);
if (IS_ERR(ctrl->admin_q)) {
ret = PTR_ERR(ctrl->admin_q);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index e8b7b0004086c..07ca1e1d920b8 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1804,6 +1804,13 @@ static int nvme_pci_alloc_admin_tag_set(struct nvme_dev *dev)
return -ENOMEM;
dev->ctrl.admin_tagset = set;
+ /*
+ * If a previous admin queue exists (e.g., from before a reset),
+ * put it now before allocating a new one to avoid orphaning it.
+ */
+ if (dev->ctrl.admin_q)
+ blk_put_queue(dev->ctrl.admin_q);
+
dev->ctrl.admin_q = blk_mq_init_queue(set);
if (IS_ERR(dev->ctrl.admin_q)) {
blk_mq_free_tag_set(set);
--
2.50.1
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related
* [PATCH 6.1.y v2 5/6] nvme: fix admin request_queue lifetime
From: Heyne, Maximilian @ 2026-04-02 13:57 UTC (permalink / raw)
To: stable@vger.kernel.org
Cc: Heyne, Maximilian, Keith Busch, Casey Chen, Christoph Hellwig,
Hannes Reinecke, Ming Lei, Chaitanya Kulkarni, Jens Axboe,
Hector Martin, Sven Peter, Alyssa Rosenzweig, Sagi Grimberg,
James E.J. Bottomley, Martin K. Petersen, Alim Akhtar,
Avri Altman, Bart Van Assche, Sasha Levin, Peter Wang,
Greg Kroah-Hartman, Thomas Yen, Bean Huo, Seunghwan Baek,
Brian Kao, Seunghui Lee, Sanjeev Yadav, Wonkon Kim,
linux-block@vger.kernel.org, linux-kernel@vger.kernel.org,
asahi@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-nvme@lists.infradead.org, linux-scsi@vger.kernel.org
In-Reply-To: <20260402-moral-jockey-f072379b@mheyne-amazon>
From: Keith Busch <kbusch@kernel.org>
[ Upstream commit 03b3bcd319b3ab5182bc9aaa0421351572c78ac0]
The namespaces can access the controller's admin request_queue, and
stale references on the namespaces may exist after tearing down the
controller. Ensure the admin request_queue is active by moving the
controller's 'put' to after all controller references have been released
to ensure no one is can access the request_queue. This fixes a reported
use-after-free bug:
BUG: KASAN: slab-use-after-free in blk_queue_enter+0x41c/0x4a0
Read of size 8 at addr ffff88c0a53819f8 by task nvme/3287
CPU: 67 UID: 0 PID: 3287 Comm: nvme Tainted: G E 6.13.2-ga1582f1a031e #15
Tainted: [E]=UNSIGNED_MODULE
Hardware name: Jabil /EGS 2S MB1, BIOS 1.00 06/18/2025
Call Trace:
<TASK>
dump_stack_lvl+0x4f/0x60
print_report+0xc4/0x620
? _raw_spin_lock_irqsave+0x70/0xb0
? _raw_read_unlock_irqrestore+0x30/0x30
? blk_queue_enter+0x41c/0x4a0
kasan_report+0xab/0xe0
? blk_queue_enter+0x41c/0x4a0
blk_queue_enter+0x41c/0x4a0
? __irq_work_queue_local+0x75/0x1d0
? blk_queue_start_drain+0x70/0x70
? irq_work_queue+0x18/0x20
? vprintk_emit.part.0+0x1cc/0x350
? wake_up_klogd_work_func+0x60/0x60
blk_mq_alloc_request+0x2b7/0x6b0
? __blk_mq_alloc_requests+0x1060/0x1060
? __switch_to+0x5b7/0x1060
nvme_submit_user_cmd+0xa9/0x330
nvme_user_cmd.isra.0+0x240/0x3f0
? force_sigsegv+0xe0/0xe0
? nvme_user_cmd64+0x400/0x400
? vfs_fileattr_set+0x9b0/0x9b0
? cgroup_update_frozen_flag+0x24/0x1c0
? cgroup_leave_frozen+0x204/0x330
? nvme_ioctl+0x7c/0x2c0
blkdev_ioctl+0x1a8/0x4d0
? blkdev_common_ioctl+0x1930/0x1930
? fdget+0x54/0x380
__x64_sys_ioctl+0x129/0x190
do_syscall_64+0x5b/0x160
entry_SYSCALL_64_after_hwframe+0x4b/0x53
RIP: 0033:0x7f765f703b0b
Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d dd 52 0f 00 f7 d8 64 89 01 48
RSP: 002b:00007ffe2cefe808 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007ffe2cefe860 RCX: 00007f765f703b0b
RDX: 00007ffe2cefe860 RSI: 00000000c0484e41 RDI: 0000000000000003
RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000
R10: 00007f765f611d50 R11: 0000000000000202 R12: 0000000000000003
R13: 00000000c0484e41 R14: 0000000000000001 R15: 00007ffe2cefea60
</TASK>
Reported-by: Casey Chen <cachen@purestorage.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
[ Because we're missing commit 0da7feaa5913 ("nvme-pci: use the tagset
alloc/free helpers") we need to additionally remove the blk_put_queue
from nvme_dev_remove_admin in pci.c to properly fix the UAF ]
Signed-off-by: Maximilian Heyne <mheyne@amazon.de>
---
drivers/nvme/host/core.c | 3 ++-
drivers/nvme/host/pci.c | 1 -
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 044e1a9c099b3..f17318f6c82b0 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -5043,7 +5043,6 @@ EXPORT_SYMBOL_GPL(nvme_alloc_admin_tag_set);
void nvme_remove_admin_tag_set(struct nvme_ctrl *ctrl)
{
blk_mq_destroy_queue(ctrl->admin_q);
- blk_put_queue(ctrl->admin_q);
if (ctrl->ops->flags & NVME_F_FABRICS) {
blk_mq_destroy_queue(ctrl->fabrics_q);
blk_put_queue(ctrl->fabrics_q);
@@ -5186,6 +5185,8 @@ static void nvme_free_ctrl(struct device *dev)
container_of(dev, struct nvme_ctrl, ctrl_device);
struct nvme_subsystem *subsys = ctrl->subsys;
+ if (ctrl->admin_q)
+ blk_put_queue(ctrl->admin_q);
if (!subsys || ctrl->instance != subsys->instance)
ida_free(&nvme_instance_ida, ctrl->instance);
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 38732c0c28bbb..e8b7b0004086c 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1782,7 +1782,6 @@ static void nvme_dev_remove_admin(struct nvme_dev *dev)
*/
nvme_start_admin_queue(&dev->ctrl);
blk_mq_destroy_queue(dev->ctrl.admin_q);
- blk_put_queue(dev->ctrl.admin_q);
blk_mq_free_tag_set(&dev->admin_tagset);
}
}
--
2.50.1
Amazon Web Services Development Center Germany GmbH
Tamara-Danz-Str. 13
10243 Berlin
Geschaeftsfuehrung: Christof Hellmis, Andreas Stieger
Eingetragen am Amtsgericht Charlottenburg unter HRB 257764 B
Sitz: Berlin
Ust-ID: DE 365 538 597
^ permalink raw reply related
* [PATCH v3 2/4] media: rkvdec: Use the global bitwriter instead of local one
From: Detlev Casanova @ 2026-04-02 14:06 UTC (permalink / raw)
To: Ezequiel Garcia, Mauro Carvalho Chehab, Heiko Stuebner,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Jonas Karlman, Nicolas Dufresne
Cc: linux-kernel, linux-media, linux-rockchip, linux-arm-kernel, llvm,
kernel, Detlev Casanova
In-Reply-To: <20260402-rkvdec-use-bitwriter-v3-0-2072474ceaf4@collabora.com>
Both rkvdec-h264.c and rkvdec-hevc.c use their own bitwriter
function and macros.
Move to using the global one introduced before.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
.../media/platform/rockchip/rkvdec/rkvdec-h264.c | 109 ++++++-------
.../media/platform/rockchip/rkvdec/rkvdec-hevc.c | 171 +++++++++------------
2 files changed, 119 insertions(+), 161 deletions(-)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
index d3202cecb988..ffa606038192 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c
@@ -16,6 +16,7 @@
#include "rkvdec-regs.h"
#include "rkvdec-cabac.h"
#include "rkvdec-h264-common.h"
+#include "rkvdec-bitwriter.h"
/* Size with u32 units. */
#define RKV_CABAC_INIT_BUFFER_SIZE (3680 + 128)
@@ -25,56 +26,48 @@ struct rkvdec_sps_pps_packet {
u32 info[8];
};
-struct rkvdec_ps_field {
- u16 offset;
- u8 len;
-};
-
-#define PS_FIELD(_offset, _len) \
- ((struct rkvdec_ps_field){ _offset, _len })
-
-#define SEQ_PARAMETER_SET_ID PS_FIELD(0, 4)
-#define PROFILE_IDC PS_FIELD(4, 8)
-#define CONSTRAINT_SET3_FLAG PS_FIELD(12, 1)
-#define CHROMA_FORMAT_IDC PS_FIELD(13, 2)
-#define BIT_DEPTH_LUMA PS_FIELD(15, 3)
-#define BIT_DEPTH_CHROMA PS_FIELD(18, 3)
-#define QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG PS_FIELD(21, 1)
-#define LOG2_MAX_FRAME_NUM_MINUS4 PS_FIELD(22, 4)
-#define MAX_NUM_REF_FRAMES PS_FIELD(26, 5)
-#define PIC_ORDER_CNT_TYPE PS_FIELD(31, 2)
-#define LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 PS_FIELD(33, 4)
-#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG PS_FIELD(37, 1)
-#define PIC_WIDTH_IN_MBS PS_FIELD(38, 9)
-#define PIC_HEIGHT_IN_MBS PS_FIELD(47, 9)
-#define FRAME_MBS_ONLY_FLAG PS_FIELD(56, 1)
-#define MB_ADAPTIVE_FRAME_FIELD_FLAG PS_FIELD(57, 1)
-#define DIRECT_8X8_INFERENCE_FLAG PS_FIELD(58, 1)
-#define MVC_EXTENSION_ENABLE PS_FIELD(59, 1)
-#define NUM_VIEWS PS_FIELD(60, 2)
-#define VIEW_ID(i) PS_FIELD(62 + ((i) * 10), 10)
-#define NUM_ANCHOR_REFS_L(i) PS_FIELD(82 + ((i) * 11), 1)
-#define ANCHOR_REF_L(i) PS_FIELD(83 + ((i) * 11), 10)
-#define NUM_NON_ANCHOR_REFS_L(i) PS_FIELD(104 + ((i) * 11), 1)
-#define NON_ANCHOR_REFS_L(i) PS_FIELD(105 + ((i) * 11), 10)
-#define PIC_PARAMETER_SET_ID PS_FIELD(128, 8)
-#define PPS_SEQ_PARAMETER_SET_ID PS_FIELD(136, 5)
-#define ENTROPY_CODING_MODE_FLAG PS_FIELD(141, 1)
-#define BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG PS_FIELD(142, 1)
-#define NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(i) PS_FIELD(143 + ((i) * 5), 5)
-#define WEIGHTED_PRED_FLAG PS_FIELD(153, 1)
-#define WEIGHTED_BIPRED_IDC PS_FIELD(154, 2)
-#define PIC_INIT_QP_MINUS26 PS_FIELD(156, 7)
-#define PIC_INIT_QS_MINUS26 PS_FIELD(163, 6)
-#define CHROMA_QP_INDEX_OFFSET PS_FIELD(169, 5)
-#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG PS_FIELD(174, 1)
-#define CONSTRAINED_INTRA_PRED_FLAG PS_FIELD(175, 1)
-#define REDUNDANT_PIC_CNT_PRESENT PS_FIELD(176, 1)
-#define TRANSFORM_8X8_MODE_FLAG PS_FIELD(177, 1)
-#define SECOND_CHROMA_QP_INDEX_OFFSET PS_FIELD(178, 5)
-#define SCALING_LIST_ENABLE_FLAG PS_FIELD(183, 1)
-#define SCALING_LIST_ADDRESS PS_FIELD(184, 32)
-#define IS_LONG_TERM(i) PS_FIELD(216 + (i), 1)
+#define SEQ_PARAMETER_SET_ID BW_FIELD(0, 4)
+#define PROFILE_IDC BW_FIELD(4, 8)
+#define CONSTRAINT_SET3_FLAG BW_FIELD(12, 1)
+#define CHROMA_FORMAT_IDC BW_FIELD(13, 2)
+#define BIT_DEPTH_LUMA BW_FIELD(15, 3)
+#define BIT_DEPTH_CHROMA BW_FIELD(18, 3)
+#define QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG BW_FIELD(21, 1)
+#define LOG2_MAX_FRAME_NUM_MINUS4 BW_FIELD(22, 4)
+#define MAX_NUM_REF_FRAMES BW_FIELD(26, 5)
+#define PIC_ORDER_CNT_TYPE BW_FIELD(31, 2)
+#define LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 BW_FIELD(33, 4)
+#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG BW_FIELD(37, 1)
+#define PIC_WIDTH_IN_MBS BW_FIELD(38, 9)
+#define PIC_HEIGHT_IN_MBS BW_FIELD(47, 9)
+#define FRAME_MBS_ONLY_FLAG BW_FIELD(56, 1)
+#define MB_ADAPTIVE_FRAME_FIELD_FLAG BW_FIELD(57, 1)
+#define DIRECT_8X8_INFERENCE_FLAG BW_FIELD(58, 1)
+#define MVC_EXTENSION_ENABLE BW_FIELD(59, 1)
+#define NUM_VIEWS BW_FIELD(60, 2)
+#define VIEW_ID(i) BW_FIELD(62 + ((i) * 10), 10)
+#define NUM_ANCHOR_REFS_L(i) BW_FIELD(82 + ((i) * 11), 1)
+#define ANCHOR_REF_L(i) BW_FIELD(83 + ((i) * 11), 10)
+#define NUM_NON_ANCHOR_REFS_L(i) BW_FIELD(104 + ((i) * 11), 1)
+#define NON_ANCHOR_REFS_L(i) BW_FIELD(105 + ((i) * 11), 10)
+#define PIC_PARAMETER_SET_ID BW_FIELD(128, 8)
+#define PPS_SEQ_PARAMETER_SET_ID BW_FIELD(136, 5)
+#define ENTROPY_CODING_MODE_FLAG BW_FIELD(141, 1)
+#define BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG BW_FIELD(142, 1)
+#define NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(i) BW_FIELD(143 + ((i) * 5), 5)
+#define WEIGHTED_PRED_FLAG BW_FIELD(153, 1)
+#define WEIGHTED_BIPRED_IDC BW_FIELD(154, 2)
+#define PIC_INIT_QP_MINUS26 BW_FIELD(156, 7)
+#define PIC_INIT_QS_MINUS26 BW_FIELD(163, 6)
+#define CHROMA_QP_INDEX_OFFSET BW_FIELD(169, 5)
+#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG BW_FIELD(174, 1)
+#define CONSTRAINED_INTRA_PRED_FLAG BW_FIELD(175, 1)
+#define REDUNDANT_PIC_CNT_PRESENT BW_FIELD(176, 1)
+#define TRANSFORM_8X8_MODE_FLAG BW_FIELD(177, 1)
+#define SECOND_CHROMA_QP_INDEX_OFFSET BW_FIELD(178, 5)
+#define SCALING_LIST_ENABLE_FLAG BW_FIELD(183, 1)
+#define SCALING_LIST_ADDRESS BW_FIELD(184, 32)
+#define IS_LONG_TERM(i) BW_FIELD(216 + (i), 1)
/* Data structure describing auxiliary buffer format. */
struct rkvdec_h264_priv_tbl {
@@ -91,20 +84,6 @@ struct rkvdec_h264_ctx {
struct rkvdec_regs regs;
};
-static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value)
-{
- u8 bit = field.offset % 32, word = field.offset / 32;
- u64 mask = GENMASK_ULL(bit + field.len - 1, bit);
- u64 val = ((u64)value << bit) & mask;
-
- buf[word] &= ~mask;
- buf[word] |= val;
- if (bit + field.len > 32) {
- buf[word + 1] &= ~(mask >> 32);
- buf[word + 1] |= val >> 32;
- }
-}
-
static void assemble_hw_pps(struct rkvdec_ctx *ctx,
struct rkvdec_h264_run *run)
{
@@ -128,7 +107,7 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
memset(hw_ps, 0, sizeof(*hw_ps));
-#define WRITE_PPS(value, field) set_ps_field(hw_ps->info, field, value)
+#define WRITE_PPS(value, field) rkvdec_set_bw_field(hw_ps->info, field, value)
/* write sps */
WRITE_PPS(sps->seq_parameter_set_id, SEQ_PARAMETER_SET_ID);
WRITE_PPS(sps->profile_idc, PROFILE_IDC);
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
index ac8b825d080a..87abf93dfd5e 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
@@ -18,6 +18,7 @@
#include "rkvdec-regs.h"
#include "rkvdec-cabac.h"
#include "rkvdec-hevc-common.h"
+#include "rkvdec-bitwriter.h"
/* Size in u8/u32 units. */
#define RKV_SCALING_LIST_SIZE 1360
@@ -34,80 +35,72 @@ struct rkvdec_rps_packet {
u32 info[RKV_RPS_SIZE];
};
-struct rkvdec_ps_field {
- u16 offset;
- u8 len;
-};
-
-#define PS_FIELD(_offset, _len) \
- ((struct rkvdec_ps_field){ _offset, _len })
-
/* SPS */
-#define VIDEO_PARAMETER_SET_ID PS_FIELD(0, 4)
-#define SEQ_PARAMETER_SET_ID PS_FIELD(4, 4)
-#define CHROMA_FORMAT_IDC PS_FIELD(8, 2)
-#define PIC_WIDTH_IN_LUMA_SAMPLES PS_FIELD(10, 13)
-#define PIC_HEIGHT_IN_LUMA_SAMPLES PS_FIELD(23, 13)
-#define BIT_DEPTH_LUMA PS_FIELD(36, 4)
-#define BIT_DEPTH_CHROMA PS_FIELD(40, 4)
-#define LOG2_MAX_PIC_ORDER_CNT_LSB PS_FIELD(44, 5)
-#define LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE PS_FIELD(49, 2)
-#define LOG2_MIN_LUMA_CODING_BLOCK_SIZE PS_FIELD(51, 3)
-#define LOG2_MIN_TRANSFORM_BLOCK_SIZE PS_FIELD(54, 3)
-#define LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE PS_FIELD(57, 2)
-#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTER PS_FIELD(59, 3)
-#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA PS_FIELD(62, 3)
-#define SCALING_LIST_ENABLED_FLAG PS_FIELD(65, 1)
-#define AMP_ENABLED_FLAG PS_FIELD(66, 1)
-#define SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG PS_FIELD(67, 1)
-#define PCM_ENABLED_FLAG PS_FIELD(68, 1)
-#define PCM_SAMPLE_BIT_DEPTH_LUMA PS_FIELD(69, 4)
-#define PCM_SAMPLE_BIT_DEPTH_CHROMA PS_FIELD(73, 4)
-#define PCM_LOOP_FILTER_DISABLED_FLAG PS_FIELD(77, 1)
-#define LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE PS_FIELD(78, 3)
-#define LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE PS_FIELD(81, 3)
-#define NUM_SHORT_TERM_REF_PIC_SETS PS_FIELD(84, 7)
-#define LONG_TERM_REF_PICS_PRESENT_FLAG PS_FIELD(91, 1)
-#define NUM_LONG_TERM_REF_PICS_SPS PS_FIELD(92, 6)
-#define SPS_TEMPORAL_MVP_ENABLED_FLAG PS_FIELD(98, 1)
-#define STRONG_INTRA_SMOOTHING_ENABLED_FLAG PS_FIELD(99, 1)
+#define VIDEO_PARAMETER_SET_ID BW_FIELD(0, 4)
+#define SEQ_PARAMETER_SET_ID BW_FIELD(4, 4)
+#define CHROMA_FORMAT_IDC BW_FIELD(8, 2)
+#define PIC_WIDTH_IN_LUMA_SAMPLES BW_FIELD(10, 13)
+#define PIC_HEIGHT_IN_LUMA_SAMPLES BW_FIELD(23, 13)
+#define BIT_DEPTH_LUMA BW_FIELD(36, 4)
+#define BIT_DEPTH_CHROMA BW_FIELD(40, 4)
+#define LOG2_MAX_PIC_ORDER_CNT_LSB BW_FIELD(44, 5)
+#define LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE BW_FIELD(49, 2)
+#define LOG2_MIN_LUMA_CODING_BLOCK_SIZE BW_FIELD(51, 3)
+#define LOG2_MIN_TRANSFORM_BLOCK_SIZE BW_FIELD(54, 3)
+#define LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE BW_FIELD(57, 2)
+#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTER BW_FIELD(59, 3)
+#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA BW_FIELD(62, 3)
+#define SCALING_LIST_ENABLED_FLAG BW_FIELD(65, 1)
+#define AMP_ENABLED_FLAG BW_FIELD(66, 1)
+#define SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG BW_FIELD(67, 1)
+#define PCM_ENABLED_FLAG BW_FIELD(68, 1)
+#define PCM_SAMPLE_BIT_DEPTH_LUMA BW_FIELD(69, 4)
+#define PCM_SAMPLE_BIT_DEPTH_CHROMA BW_FIELD(73, 4)
+#define PCM_LOOP_FILTER_DISABLED_FLAG BW_FIELD(77, 1)
+#define LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE BW_FIELD(78, 3)
+#define LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE BW_FIELD(81, 3)
+#define NUM_SHORT_TERM_REF_PIC_SETS BW_FIELD(84, 7)
+#define LONG_TERM_REF_PICS_PRESENT_FLAG BW_FIELD(91, 1)
+#define NUM_LONG_TERM_REF_PICS_SPS BW_FIELD(92, 6)
+#define SPS_TEMPORAL_MVP_ENABLED_FLAG BW_FIELD(98, 1)
+#define STRONG_INTRA_SMOOTHING_ENABLED_FLAG BW_FIELD(99, 1)
/* PPS */
-#define PIC_PARAMETER_SET_ID PS_FIELD(128, 6)
-#define PPS_SEQ_PARAMETER_SET_ID PS_FIELD(134, 4)
-#define DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG PS_FIELD(138, 1)
-#define OUTPUT_FLAG_PRESENT_FLAG PS_FIELD(139, 1)
-#define NUM_EXTRA_SLICE_HEADER_BITS PS_FIELD(140, 13)
-#define SIGN_DATA_HIDING_ENABLED_FLAG PS_FIELD(153, 1)
-#define CABAC_INIT_PRESENT_FLAG PS_FIELD(154, 1)
-#define NUM_REF_IDX_L0_DEFAULT_ACTIVE PS_FIELD(155, 4)
-#define NUM_REF_IDX_L1_DEFAULT_ACTIVE PS_FIELD(159, 4)
-#define INIT_QP_MINUS26 PS_FIELD(163, 7)
-#define CONSTRAINED_INTRA_PRED_FLAG PS_FIELD(170, 1)
-#define TRANSFORM_SKIP_ENABLED_FLAG PS_FIELD(171, 1)
-#define CU_QP_DELTA_ENABLED_FLAG PS_FIELD(172, 1)
-#define LOG2_MIN_CU_QP_DELTA_SIZE PS_FIELD(173, 3)
-#define PPS_CB_QP_OFFSET PS_FIELD(176, 5)
-#define PPS_CR_QP_OFFSET PS_FIELD(181, 5)
-#define PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG PS_FIELD(186, 1)
-#define WEIGHTED_PRED_FLAG PS_FIELD(187, 1)
-#define WEIGHTED_BIPRED_FLAG PS_FIELD(188, 1)
-#define TRANSQUANT_BYPASS_ENABLED_FLAG PS_FIELD(189, 1)
-#define TILES_ENABLED_FLAG PS_FIELD(190, 1)
-#define ENTROPY_CODING_SYNC_ENABLED_FLAG PS_FIELD(191, 1)
-#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG PS_FIELD(192, 1)
-#define LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG PS_FIELD(193, 1)
-#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG PS_FIELD(194, 1)
-#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG PS_FIELD(195, 1)
-#define PPS_BETA_OFFSET_DIV2 PS_FIELD(196, 4)
-#define PPS_TC_OFFSET_DIV2 PS_FIELD(200, 4)
-#define LISTS_MODIFICATION_PRESENT_FLAG PS_FIELD(204, 1)
-#define LOG2_PARALLEL_MERGE_LEVEL PS_FIELD(205, 3)
-#define SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG PS_FIELD(208, 1)
-#define NUM_TILE_COLUMNS PS_FIELD(212, 5)
-#define NUM_TILE_ROWS PS_FIELD(217, 5)
-#define COLUMN_WIDTH(i) PS_FIELD(256 + ((i) * 8), 8)
-#define ROW_HEIGHT(i) PS_FIELD(416 + ((i) * 8), 8)
-#define SCALING_LIST_ADDRESS PS_FIELD(592, 32)
+#define PIC_PARAMETER_SET_ID BW_FIELD(128, 6)
+#define PPS_SEQ_PARAMETER_SET_ID BW_FIELD(134, 4)
+#define DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG BW_FIELD(138, 1)
+#define OUTPUT_FLAG_PRESENT_FLAG BW_FIELD(139, 1)
+#define NUM_EXTRA_SLICE_HEADER_BITS BW_FIELD(140, 13)
+#define SIGN_DATA_HIDING_ENABLED_FLAG BW_FIELD(153, 1)
+#define CABAC_INIT_PRESENT_FLAG BW_FIELD(154, 1)
+#define NUM_REF_IDX_L0_DEFAULT_ACTIVE BW_FIELD(155, 4)
+#define NUM_REF_IDX_L1_DEFAULT_ACTIVE BW_FIELD(159, 4)
+#define INIT_QP_MINUS26 BW_FIELD(163, 7)
+#define CONSTRAINED_INTRA_PRED_FLAG BW_FIELD(170, 1)
+#define TRANSFORM_SKIP_ENABLED_FLAG BW_FIELD(171, 1)
+#define CU_QP_DELTA_ENABLED_FLAG BW_FIELD(172, 1)
+#define LOG2_MIN_CU_QP_DELTA_SIZE BW_FIELD(173, 3)
+#define PPS_CB_QP_OFFSET BW_FIELD(176, 5)
+#define PPS_CR_QP_OFFSET BW_FIELD(181, 5)
+#define PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG BW_FIELD(186, 1)
+#define WEIGHTED_PRED_FLAG BW_FIELD(187, 1)
+#define WEIGHTED_BIPRED_FLAG BW_FIELD(188, 1)
+#define TRANSQUANT_BYPASS_ENABLED_FLAG BW_FIELD(189, 1)
+#define TILES_ENABLED_FLAG BW_FIELD(190, 1)
+#define ENTROPY_CODING_SYNC_ENABLED_FLAG BW_FIELD(191, 1)
+#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG BW_FIELD(192, 1)
+#define LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG BW_FIELD(193, 1)
+#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG BW_FIELD(194, 1)
+#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG BW_FIELD(195, 1)
+#define PPS_BETA_OFFSET_DIV2 BW_FIELD(196, 4)
+#define PPS_TC_OFFSET_DIV2 BW_FIELD(200, 4)
+#define LISTS_MODIFICATION_PRESENT_FLAG BW_FIELD(204, 1)
+#define LOG2_PARALLEL_MERGE_LEVEL BW_FIELD(205, 3)
+#define SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG BW_FIELD(208, 1)
+#define NUM_TILE_COLUMNS BW_FIELD(212, 5)
+#define NUM_TILE_ROWS BW_FIELD(217, 5)
+#define COLUMN_WIDTH(i) BW_FIELD(256 + ((i) * 8), 8)
+#define ROW_HEIGHT(i) BW_FIELD(416 + ((i) * 8), 8)
+#define SCALING_LIST_ADDRESS BW_FIELD(592, 32)
/* Data structure describing auxiliary buffer format. */
struct rkvdec_hevc_priv_tbl {
@@ -123,20 +116,6 @@ struct rkvdec_hevc_ctx {
struct rkvdec_regs regs;
};
-static void set_ps_field(u32 *buf, struct rkvdec_ps_field field, u32 value)
-{
- u8 bit = field.offset % 32, word = field.offset / 32;
- u64 mask = GENMASK_ULL(bit + field.len - 1, bit);
- u64 val = ((u64)value << bit) & mask;
-
- buf[word] &= ~mask;
- buf[word] |= val;
- if (bit + field.len > 32) {
- buf[word + 1] &= ~(mask >> 32);
- buf[word + 1] |= val >> 32;
- }
-}
-
static void assemble_hw_pps(struct rkvdec_ctx *ctx,
struct rkvdec_hevc_run *run)
{
@@ -159,7 +138,7 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
memset(hw_ps, 0, sizeof(*hw_ps));
-#define WRITE_PPS(value, field) set_ps_field(hw_ps->info, field, value)
+#define WRITE_PPS(value, field) rkvdec_set_bw_field(hw_ps->info, field, value)
/* write sps */
WRITE_PPS(sps->video_parameter_set_id, VIDEO_PARAMETER_SET_ID);
WRITE_PPS(sps->seq_parameter_set_id, SEQ_PARAMETER_SET_ID);
@@ -321,17 +300,17 @@ static void assemble_sw_rps(struct rkvdec_ctx *ctx,
int i, j;
unsigned int lowdelay;
-#define WRITE_RPS(value, field) set_ps_field(hw_ps->info, field, value)
+#define WRITE_RPS(value, field) rkvdec_set_bw_field(hw_ps->info, field, value)
-#define REF_PIC_LONG_TERM_L0(i) PS_FIELD((i) * 5, 1)
-#define REF_PIC_IDX_L0(i) PS_FIELD(1 + ((i) * 5), 4)
-#define REF_PIC_LONG_TERM_L1(i) PS_FIELD(((i) < 5 ? 75 : 132) + ((i) * 5), 1)
-#define REF_PIC_IDX_L1(i) PS_FIELD(((i) < 4 ? 76 : 128) + ((i) * 5), 4)
+#define REF_PIC_LONG_TERM_L0(n) BW_FIELD((n) * 5, 1)
+#define REF_PIC_IDX_L0(n) BW_FIELD(1 + ((n) * 5), 4)
+#define REF_PIC_LONG_TERM_L1(n) BW_FIELD(((n) < 5 ? 75 : 132) + ((n) * 5), 1)
+#define REF_PIC_IDX_L1(n) BW_FIELD(((n) < 4 ? 76 : 128) + ((n) * 5), 4)
-#define LOWDELAY PS_FIELD(182, 1)
-#define LONG_TERM_RPS_BIT_OFFSET PS_FIELD(183, 10)
-#define SHORT_TERM_RPS_BIT_OFFSET PS_FIELD(193, 9)
-#define NUM_RPS_POC PS_FIELD(202, 4)
+#define LOWDELAY BW_FIELD(182, 1)
+#define LONG_TERM_RPS_BIT_OFFSET BW_FIELD(183, 10)
+#define SHORT_TERM_RPS_BIT_OFFSET BW_FIELD(193, 9)
+#define NUM_RPS_POC BW_FIELD(202, 4)
for (j = 0; j < run->num_slices; j++) {
uint st_bit_offset = 0;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 1/4] media: rkvdec: Introduce a global bitwriter helper
From: Detlev Casanova @ 2026-04-02 14:06 UTC (permalink / raw)
To: Ezequiel Garcia, Mauro Carvalho Chehab, Heiko Stuebner,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Jonas Karlman, Nicolas Dufresne
Cc: linux-kernel, linux-media, linux-rockchip, linux-arm-kernel, llvm,
kernel, Detlev Casanova
In-Reply-To: <20260402-rkvdec-use-bitwriter-v3-0-2072474ceaf4@collabora.com>
The use of structures with bitfields is good when the values are
somewhat aligned.
More mis-alignement means that compilers need to do more gymanstics
to edit the fields values.
Some cases have been reported with CLang on specific architectures
like armhf and hexagon, where the compiler would allocate a bigger
local stack than needed or even completely freeze during compilation.
Some fixes have been provided to ease the issues, but the real fix
here is to use a bitwriter instead of heavily unaligned bitfields.
This is a preparation commit to provide a global bitwriter interface
for the whole driver.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
.../platform/rockchip/rkvdec/rkvdec-bitwriter.h | 39 ++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-bitwriter.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-bitwriter.h
new file mode 100644
index 000000000000..2a5c271ade91
--- /dev/null
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-bitwriter.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Rockchip Video Decoder bit writer
+ *
+ * Copyright (C) 2026 Collabora, Ltd.
+ * Detlev Casanova <detlev.casanova@collabora.com>
+ * Copyright (C) 2019 Collabora, Ltd.
+ * Boris Brezillon <boris.brezillon@collabora.com>
+ */
+
+#ifndef RKVDEC_BIT_WRITER_H_
+#define RKVDEC_BIT_WRITER_H_
+
+#include <linux/types.h>
+#include <linux/bits.h>
+
+struct rkvdec_bw_field {
+ u16 offset;
+ u8 len;
+};
+
+#define BW_FIELD(_offset, _len) ((struct rkvdec_bw_field){ _offset, _len })
+
+static inline void rkvdec_set_bw_field(u32 *buf, struct rkvdec_bw_field field, u32 value)
+{
+ u8 bit = field.offset % 32;
+ u16 word = field.offset / 32;
+ u64 mask = GENMASK_ULL(bit + field.len - 1, bit);
+ u64 val = ((u64)value << bit) & mask;
+
+ buf[word] &= ~mask;
+ buf[word] |= val;
+ if (bit + field.len > 32) {
+ buf[word + 1] &= ~(mask >> 32);
+ buf[word + 1] |= val >> 32;
+ }
+}
+
+#endif /* RKVDEC_BIT_WRITER_H_ */
--
2.53.0
^ permalink raw reply related
* [PATCH v3 0/4] media: rkvdec: Switch to using a bitwriter
From: Detlev Casanova @ 2026-04-02 14:06 UTC (permalink / raw)
To: Ezequiel Garcia, Mauro Carvalho Chehab, Heiko Stuebner,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Jonas Karlman, Nicolas Dufresne
Cc: linux-kernel, linux-media, linux-rockchip, linux-arm-kernel, llvm,
kernel, Detlev Casanova
Using bitfields in large structures where fields are mostly unaligned can
be hard on the compiler.
Issues have been reported with clang ([1], [2]) and, even though those
issues are addressed by clang devs, some setup can't or won't update clang
just to compile a driver.
Even when fixed, the compiler still might have to allocate a bigger stack
frame to manage misalignement. Coupled with other features like KASAN, the
stack becomes larger than the kernel's maximum [3].
To avoid this, let's drop the bitfield implementation and switch to a
bitwriter. There is already one for the older variants, so make it global
and use it in other variants.
Note that only buffer structures are switched to the bitwriter. The
registers representation structures are kept with bitfields, as they are
properly aligned every 32 bits and don't require heavy stack overhead.
Also note that the VDPU381 SPS and PPS structs are kept with bitfields,
for the same reason that they are small and aligned enough not to require
heavy stack overhead.
[1]: https://lore.kernel.org/oe-kbuild-all/202601211924.rqKS2Ihm-lkp@intel.com/
[2]: https://github.com/llvm/llvm-project/issues/178535
[3]: https://yhbt.net/lore/llvm/20260121230406.GA2625738@ax162/T/#mad878ec24a8224e1387ef5e73cb77b9ada55e3f2
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
Changes in v3:
- Change bitwriter function to static inline instead of its own object
- Link to v2: https://patch.msgid.link/20260327-rkvdec-use-bitwriter-v2-0-a5a4754b0518@collabora.com
Changes in v2:
- Don't use BW_FIELD to compute buffer size
- Use correct size for buffers
- Fix missed indentation issues
- Link to v1: https://patch.msgid.link/20260327-rkvdec-use-bitwriter-v1-0-982cf872b590@collabora.com
---
Detlev Casanova (4):
media: rkvdec: Introduce a global bitwriter helper
media: rkvdec: Use the global bitwriter instead of local one
media: rkvdec: common: Drop bitfields for the bitwriter
media: rkvdec: vdpu383: Drop bitfields for the bitwriter
.../platform/rockchip/rkvdec/rkvdec-bitwriter.h | 39 ++
.../platform/rockchip/rkvdec/rkvdec-h264-common.c | 51 +--
.../platform/rockchip/rkvdec/rkvdec-h264-common.h | 40 +-
.../media/platform/rockchip/rkvdec/rkvdec-h264.c | 109 ++---
.../platform/rockchip/rkvdec/rkvdec-hevc-common.c | 93 +---
.../platform/rockchip/rkvdec/rkvdec-hevc-common.h | 57 +--
.../media/platform/rockchip/rkvdec/rkvdec-hevc.c | 171 +++----
.../platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c | 351 ++++++--------
.../platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c | 502 +++++++++------------
9 files changed, 562 insertions(+), 851 deletions(-)
---
base-commit: d0c3bcd5b8976159d835a897254048e078f447e6
change-id: 20260327-rkvdec-use-bitwriter-f1d149b3cf7c
Best regards,
--
Detlev Casanova <detlev.casanova@collabora.com>
^ permalink raw reply
* [PATCH v3 3/4] media: rkvdec: common: Drop bitfields for the bitwriter
From: Detlev Casanova @ 2026-04-02 14:06 UTC (permalink / raw)
To: Ezequiel Garcia, Mauro Carvalho Chehab, Heiko Stuebner,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Jonas Karlman, Nicolas Dufresne
Cc: linux-kernel, linux-media, linux-rockchip, linux-arm-kernel, llvm,
kernel, Detlev Casanova
In-Reply-To: <20260402-rkvdec-use-bitwriter-v3-0-2072474ceaf4@collabora.com>
Currently, the common code files for hevc and h264 use structs with
bitfields to represent the HW RPS buffer.
Because the bitfields are mostly unaligned and numerous, it brings compiler
issues, especially with clang.
To prevent that, switch to using the global bitwriter previously
introduced instead.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
.../platform/rockchip/rkvdec/rkvdec-h264-common.c | 51 +-----------
.../platform/rockchip/rkvdec/rkvdec-h264-common.h | 40 +++-------
.../platform/rockchip/rkvdec/rkvdec-hevc-common.c | 93 ++++------------------
.../platform/rockchip/rkvdec/rkvdec-hevc-common.h | 57 ++++---------
4 files changed, 44 insertions(+), 197 deletions(-)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
index e28f06394470..54639512e456 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.c
@@ -21,51 +21,6 @@
#define RKVDEC_NUM_REFLIST 3
-static void set_dpb_info(struct rkvdec_rps_entry *entries,
- u8 reflist,
- u8 refnum,
- u8 info,
- bool bottom)
-{
- struct rkvdec_rps_entry *entry = &entries[(reflist * 4) + refnum / 8];
- u8 idx = refnum % 8;
-
- switch (idx) {
- case 0:
- entry->dpb_info0 = info;
- entry->bottom_flag0 = bottom;
- break;
- case 1:
- entry->dpb_info1 = info;
- entry->bottom_flag1 = bottom;
- break;
- case 2:
- entry->dpb_info2 = info;
- entry->bottom_flag2 = bottom;
- break;
- case 3:
- entry->dpb_info3 = info;
- entry->bottom_flag3 = bottom;
- break;
- case 4:
- entry->dpb_info4 = info;
- entry->bottom_flag4 = bottom;
- break;
- case 5:
- entry->dpb_info5 = info;
- entry->bottom_flag5 = bottom;
- break;
- case 6:
- entry->dpb_info6 = info;
- entry->bottom_flag6 = bottom;
- break;
- case 7:
- entry->dpb_info7 = info;
- entry->bottom_flag7 = bottom;
- break;
- }
-}
-
void lookup_ref_buf_idx(struct rkvdec_ctx *ctx,
struct rkvdec_h264_run *run)
{
@@ -111,7 +66,7 @@ void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
if (!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE))
continue;
- hw_rps->frame_num[i] = builder->refs[i].frame_num;
+ rkvdec_set_bw_field(hw_rps->info, RPS_FRAME_NUM(i), builder->refs[i].frame_num);
}
for (j = 0; j < RKVDEC_NUM_REFLIST; j++) {
@@ -138,7 +93,9 @@ void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
dpb_valid = !!(run->ref_buf[ref->index]);
bottom = ref->fields == V4L2_H264_BOTTOM_FIELD_REF;
- set_dpb_info(hw_rps->entries, j, i, ref->index | (dpb_valid << 4), bottom);
+ rkvdec_set_bw_field(hw_rps->info, RPS_ENTRY_DPB_INFO(j, i),
+ ref->index | (dpb_valid << 4));
+ rkvdec_set_bw_field(hw_rps->info, RPS_ENTRY_BOTTOM_FLAG(j, i), bottom);
}
}
}
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
index 5336370507d6..f04b700b863c 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264-common.h
@@ -16,6 +16,7 @@
#include <media/v4l2-mem2mem.h>
#include "rkvdec.h"
+#include "rkvdec-bitwriter.h"
struct rkvdec_h264_scaling_list {
u8 scaling_list_4x4[6][16];
@@ -38,39 +39,16 @@ struct rkvdec_h264_run {
struct vb2_buffer *ref_buf[V4L2_H264_NUM_DPB_ENTRIES];
};
-struct rkvdec_rps_entry {
- u32 dpb_info0: 5;
- u32 bottom_flag0: 1;
- u32 view_index_off0: 1;
- u32 dpb_info1: 5;
- u32 bottom_flag1: 1;
- u32 view_index_off1: 1;
- u32 dpb_info2: 5;
- u32 bottom_flag2: 1;
- u32 view_index_off2: 1;
- u32 dpb_info3: 5;
- u32 bottom_flag3: 1;
- u32 view_index_off3: 1;
- u32 dpb_info4: 5;
- u32 bottom_flag4: 1;
- u32 view_index_off4: 1;
- u32 dpb_info5: 5;
- u32 bottom_flag5: 1;
- u32 view_index_off5: 1;
- u32 dpb_info6: 5;
- u32 bottom_flag6: 1;
- u32 view_index_off6: 1;
- u32 dpb_info7: 5;
- u32 bottom_flag7: 1;
- u32 view_index_off7: 1;
-} __packed;
+#define RPS_FRAME_NUM(i) BW_FIELD((i) * 16, 16)
+#define RPS_ENTRY_DPB_INFO(l, e) BW_FIELD(288 + (l) * 7 * 32 + (e) * 7, 5) //l: 0-2, e: 0-31
+#define RPS_ENTRY_BOTTOM_FLAG(l, e) BW_FIELD(293 + (l) * 7 * 32 + (e) * 7, 1) //l: 0-2, e: 0-31
+#define RPS_ENTRY_VIEW_INDEX_OFF(l, e) BW_FIELD(294 + (l) * 7 * 32 + (e) * 7, 1) //l: 0-2, e: 0-31
+
+#define RKVDEC_H264_RPS_SIZE ALIGN(288 + 3 * 7 * 32, 128)
struct rkvdec_rps {
- u16 frame_num[16];
- u32 reserved0;
- struct rkvdec_rps_entry entries[12];
- u32 reserved1[66];
-} __packed;
+ u32 info[RKVDEC_H264_RPS_SIZE / 8 / 4];
+};
void lookup_ref_buf_idx(struct rkvdec_ctx *ctx, struct rkvdec_h264_run *run);
void assemble_hw_rps(struct v4l2_h264_reflist_builder *builder,
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
index 3119f3bc9f98..f89602075121 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
@@ -74,72 +74,6 @@ void compute_tiles_non_uniform(struct rkvdec_hevc_run *run, u16 log2_min_cb_size
row_height[i] = pic_in_cts_height - sum;
}
-static void set_ref_poc(struct rkvdec_rps_short_term_ref_set *set, int poc, int value, int flag)
-{
- switch (poc) {
- case 0:
- set->delta_poc0 = value;
- set->used_flag0 = flag;
- break;
- case 1:
- set->delta_poc1 = value;
- set->used_flag1 = flag;
- break;
- case 2:
- set->delta_poc2 = value;
- set->used_flag2 = flag;
- break;
- case 3:
- set->delta_poc3 = value;
- set->used_flag3 = flag;
- break;
- case 4:
- set->delta_poc4 = value;
- set->used_flag4 = flag;
- break;
- case 5:
- set->delta_poc5 = value;
- set->used_flag5 = flag;
- break;
- case 6:
- set->delta_poc6 = value;
- set->used_flag6 = flag;
- break;
- case 7:
- set->delta_poc7 = value;
- set->used_flag7 = flag;
- break;
- case 8:
- set->delta_poc8 = value;
- set->used_flag8 = flag;
- break;
- case 9:
- set->delta_poc9 = value;
- set->used_flag9 = flag;
- break;
- case 10:
- set->delta_poc10 = value;
- set->used_flag10 = flag;
- break;
- case 11:
- set->delta_poc11 = value;
- set->used_flag11 = flag;
- break;
- case 12:
- set->delta_poc12 = value;
- set->used_flag12 = flag;
- break;
- case 13:
- set->delta_poc13 = value;
- set->used_flag13 = flag;
- break;
- case 14:
- set->delta_poc14 = value;
- set->used_flag14 = flag;
- break;
- }
-}
-
static void assemble_scalingfactor0(struct rkvdec_ctx *ctx, u8 *output,
const struct v4l2_ctrl_hevc_scaling_matrix *input)
{
@@ -218,10 +152,11 @@ static void rkvdec_hevc_assemble_hw_lt_rps(struct rkvdec_hevc_run *run, struct r
return;
for (int i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
- rps->refs[i].lt_ref_pic_poc_lsb =
- run->ext_sps_lt_rps[i].lt_ref_pic_poc_lsb_sps;
- rps->refs[i].used_by_curr_pic_lt_flag =
- !!(run->ext_sps_lt_rps[i].flags & V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT);
+ rkvdec_set_bw_field(rps->info, RPS_LT_REF_PIC_POC_LSB(i),
+ run->ext_sps_lt_rps[i].lt_ref_pic_poc_lsb_sps);
+ rkvdec_set_bw_field(rps->info, RPS_LT_REF_USED_BY_CURR_PIC(i),
+ !!(run->ext_sps_lt_rps[i].flags &
+ V4L2_HEVC_EXT_SPS_LT_RPS_FLAG_USED_LT));
}
}
@@ -235,18 +170,24 @@ static void rkvdec_hevc_assemble_hw_st_rps(struct rkvdec_hevc_run *run, struct r
int j = 0;
const struct calculated_rps_st_set *set = &calculated_rps_st_sets[i];
- rps->short_term_ref_sets[i].num_negative = set->num_negative_pics;
- rps->short_term_ref_sets[i].num_positive = set->num_positive_pics;
+ rkvdec_set_bw_field(rps->info, RPS_ST_REF_SET_NUM_NEGATIVE(i),
+ set->num_negative_pics);
+ rkvdec_set_bw_field(rps->info, RPS_ST_REF_SET_NUM_POSITIVE(i),
+ set->num_positive_pics);
for (; j < set->num_negative_pics; j++) {
- set_ref_poc(&rps->short_term_ref_sets[i], j,
- set->delta_poc_s0[j], set->used_by_curr_pic_s0[j]);
+ rkvdec_set_bw_field(rps->info, RPS_ST_REF_SET_DELTA_POC(i, j),
+ set->delta_poc_s0[j]);
+ rkvdec_set_bw_field(rps->info, RPS_ST_REF_SET_USED(i, j),
+ set->used_by_curr_pic_s0[j]);
}
poc = j;
for (j = 0; j < set->num_positive_pics; j++) {
- set_ref_poc(&rps->short_term_ref_sets[i], poc + j,
- set->delta_poc_s1[j], set->used_by_curr_pic_s1[j]);
+ rkvdec_set_bw_field(rps->info, RPS_ST_REF_SET_DELTA_POC(i, poc + j),
+ set->delta_poc_s1[j]);
+ rkvdec_set_bw_field(rps->info, RPS_ST_REF_SET_USED(i, poc + j),
+ set->used_by_curr_pic_s1[j]);
}
}
}
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
index 6f4faca4c091..2a9b7719ab2d 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.h
@@ -19,53 +19,24 @@
#include <linux/types.h>
#include "rkvdec.h"
+#include "rkvdec-bitwriter.h"
-struct rkvdec_rps_refs {
- u16 lt_ref_pic_poc_lsb;
- u16 used_by_curr_pic_lt_flag : 1;
- u16 reserved : 15;
-} __packed;
+#define RPS_LT_REF_PIC_POC_LSB(i) BW_FIELD(0 + (i) * 32, 16) // i: 0-31
+#define RPS_LT_REF_USED_BY_CURR_PIC(i) BW_FIELD(16 + (i) * 32, 1) // i: 0-31
-struct rkvdec_rps_short_term_ref_set {
- u32 num_negative : 4;
- u32 num_positive : 4;
- u32 delta_poc0 : 16;
- u32 used_flag0 : 1;
- u32 delta_poc1 : 16;
- u32 used_flag1 : 1;
- u32 delta_poc2 : 16;
- u32 used_flag2 : 1;
- u32 delta_poc3 : 16;
- u32 used_flag3 : 1;
- u32 delta_poc4 : 16;
- u32 used_flag4 : 1;
- u32 delta_poc5 : 16;
- u32 used_flag5 : 1;
- u32 delta_poc6 : 16;
- u32 used_flag6 : 1;
- u32 delta_poc7 : 16;
- u32 used_flag7 : 1;
- u32 delta_poc8 : 16;
- u32 used_flag8 : 1;
- u32 delta_poc9 : 16;
- u32 used_flag9 : 1;
- u32 delta_poc10 : 16;
- u32 used_flag10 : 1;
- u32 delta_poc11 : 16;
- u32 used_flag11 : 1;
- u32 delta_poc12 : 16;
- u32 used_flag12 : 1;
- u32 delta_poc13 : 16;
- u32 used_flag13 : 1;
- u32 delta_poc14 : 16;
- u32 used_flag14 : 1;
- u32 reserved_bits : 25;
- u32 reserved[3];
-} __packed;
+#define RPS_ST_REF_SET_NUM_NEGATIVE(i) BW_FIELD(1024 + ((i) * 384), 4) // i: 0-63
+#define RPS_ST_REF_SET_NUM_POSITIVE(i) BW_FIELD(1028 + ((i) * 384), 4) // i: 0-63
+
+// i: 0-63, j: 0-14
+#define RPS_ST_REF_SET_DELTA_POC(i, j) BW_FIELD(1032 + ((i) * 384) + ((j) * 17), 16)
+
+// i: 0-63, j: 0-14
+#define RPS_ST_REF_SET_USED(i, j) BW_FIELD(1048 + ((i) * 384) + ((j) * 17), 1)
+
+#define RKVDEC_RPS_HEVC_SIZE ALIGN(1032 + 64 * 384, 128)
struct rkvdec_rps {
- struct rkvdec_rps_refs refs[32];
- struct rkvdec_rps_short_term_ref_set short_term_ref_sets[64];
+ u32 info[RKVDEC_RPS_HEVC_SIZE / 8 / 4];
} __packed;
struct rkvdec_hevc_run {
--
2.53.0
^ permalink raw reply related
* [PATCH v3 4/4] media: rkvdec: vdpu383: Drop bitfields for the bitwriter
From: Detlev Casanova @ 2026-04-02 14:06 UTC (permalink / raw)
To: Ezequiel Garcia, Mauro Carvalho Chehab, Heiko Stuebner,
Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt,
Jonas Karlman, Nicolas Dufresne
Cc: linux-kernel, linux-media, linux-rockchip, linux-arm-kernel, llvm,
kernel, Detlev Casanova
In-Reply-To: <20260402-rkvdec-use-bitwriter-v3-0-2072474ceaf4@collabora.com>
The VDPU383 support for hevc and h264 use structs with bitfields to
represent the SPS and PPS.
Because the fields are mostly unaligned and numerous, it brings compiler
issues, especially with clang.
To prevent that, switch to using the global bitwriter previously
introduced instead.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
.../platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c | 351 ++++++--------
.../platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c | 502 +++++++++------------
2 files changed, 360 insertions(+), 493 deletions(-)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
index fb4f849d7366..5ec755733916 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c
@@ -15,105 +15,64 @@
#include "rkvdec-cabac.h"
#include "rkvdec-vdpu383-regs.h"
#include "rkvdec-h264-common.h"
-
-struct rkvdec_sps {
- u16 seq_parameter_set_id: 4;
- u16 profile_idc: 8;
- u16 constraint_set3_flag: 1;
- u16 chroma_format_idc: 2;
- u16 bit_depth_luma: 3;
- u16 bit_depth_chroma: 3;
- u16 qpprime_y_zero_transform_bypass_flag: 1;
- u16 log2_max_frame_num_minus4: 4;
- u16 max_num_ref_frames: 5;
- u16 pic_order_cnt_type: 2;
- u16 log2_max_pic_order_cnt_lsb_minus4: 4;
- u16 delta_pic_order_always_zero_flag: 1;
-
- u16 pic_width_in_mbs: 16;
- u16 pic_height_in_mbs: 16;
-
- u16 frame_mbs_only_flag: 1;
- u16 mb_adaptive_frame_field_flag: 1;
- u16 direct_8x8_inference_flag: 1;
- u16 mvc_extension_enable: 1;
- u16 num_views: 2;
- u16 view_id0: 10;
- u16 view_id1: 10;
-} __packed;
-
-struct rkvdec_pps {
- u32 pic_parameter_set_id: 8;
- u32 pps_seq_parameter_set_id: 5;
- u32 entropy_coding_mode_flag: 1;
- u32 bottom_field_pic_order_in_frame_present_flag: 1;
- u32 num_ref_idx_l0_default_active_minus1: 5;
- u32 num_ref_idx_l1_default_active_minus1: 5;
- u32 weighted_pred_flag: 1;
- u32 weighted_bipred_idc: 2;
- u32 pic_init_qp_minus26: 7;
- u32 pic_init_qs_minus26: 6;
- u32 chroma_qp_index_offset: 5;
- u32 deblocking_filter_control_present_flag: 1;
- u32 constrained_intra_pred_flag: 1;
- u32 redundant_pic_cnt_present: 1;
- u32 transform_8x8_mode_flag: 1;
- u32 second_chroma_qp_index_offset: 5;
- u32 scaling_list_enable_flag: 1;
- u32 is_longterm: 16;
- u32 voidx: 16;
-
- // dpb
- u32 pic_field_flag: 1;
- u32 pic_associated_flag: 1;
- u32 cur_top_field: 32;
- u32 cur_bot_field: 32;
-
- u32 top_field_order_cnt0: 32;
- u32 bot_field_order_cnt0: 32;
- u32 top_field_order_cnt1: 32;
- u32 bot_field_order_cnt1: 32;
- u32 top_field_order_cnt2: 32;
- u32 bot_field_order_cnt2: 32;
- u32 top_field_order_cnt3: 32;
- u32 bot_field_order_cnt3: 32;
- u32 top_field_order_cnt4: 32;
- u32 bot_field_order_cnt4: 32;
- u32 top_field_order_cnt5: 32;
- u32 bot_field_order_cnt5: 32;
- u32 top_field_order_cnt6: 32;
- u32 bot_field_order_cnt6: 32;
- u32 top_field_order_cnt7: 32;
- u32 bot_field_order_cnt7: 32;
- u32 top_field_order_cnt8: 32;
- u32 bot_field_order_cnt8: 32;
- u32 top_field_order_cnt9: 32;
- u32 bot_field_order_cnt9: 32;
- u32 top_field_order_cnt10: 32;
- u32 bot_field_order_cnt10: 32;
- u32 top_field_order_cnt11: 32;
- u32 bot_field_order_cnt11: 32;
- u32 top_field_order_cnt12: 32;
- u32 bot_field_order_cnt12: 32;
- u32 top_field_order_cnt13: 32;
- u32 bot_field_order_cnt13: 32;
- u32 top_field_order_cnt14: 32;
- u32 bot_field_order_cnt14: 32;
- u32 top_field_order_cnt15: 32;
- u32 bot_field_order_cnt15: 32;
-
- u32 ref_field_flags: 16;
- u32 ref_topfield_used: 16;
- u32 ref_botfield_used: 16;
- u32 ref_colmv_use_flag: 16;
-
- u32 reserved0: 30;
- u32 reserved[3];
-} __packed;
+#include "rkvdec-bitwriter.h"
+
+#define SEQ_PARAMETER_SET_ID BW_FIELD(0, 4)
+#define PROFILE_IDC BW_FIELD(4, 8)
+#define CONSTRAINT_SET3_FLAG BW_FIELD(12, 1)
+#define CHROMA_FORMAT_IDC BW_FIELD(13, 2)
+#define BIT_DEPTH_LUMA BW_FIELD(15, 3)
+#define BIT_DEPTH_CHROMA BW_FIELD(18, 3)
+#define QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG BW_FIELD(21, 1)
+#define LOG2_MAX_FRAME_NUM_MINUS4 BW_FIELD(22, 4)
+#define MAX_NUM_REF_FRAMES BW_FIELD(26, 5)
+#define PIC_ORDER_CNT_TYPE BW_FIELD(31, 2)
+#define LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 BW_FIELD(33, 4)
+#define DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG BW_FIELD(37, 1)
+#define PIC_WIDTH_IN_MBS BW_FIELD(38, 16)
+#define PIC_HEIGHT_IN_MBS BW_FIELD(54, 16)
+#define FRAME_MBS_ONLY_FLAG BW_FIELD(70, 1)
+#define MB_ADAPTIVE_FRAME_FIELD_FLAG BW_FIELD(71, 1)
+#define DIRECT_8X8_INFERENCE_FLAG BW_FIELD(72, 1)
+#define MVC_EXTENSION_ENABLE BW_FIELD(73, 1)
+#define NUM_VIEWS BW_FIELD(74, 2)
+#define VIEW_ID(i) BW_FIELD(76 + ((i) * 10), 10) // i: 0-1
+
+#define PIC_PARAMETER_SET_ID BW_FIELD(96, 8)
+#define PPS_SEQ_PARAMETER_SET_ID BW_FIELD(104, 5)
+#define ENTROPY_CODING_MODE_FLAG BW_FIELD(109, 1)
+#define BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG BW_FIELD(110, 1)
+#define NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(i) BW_FIELD(111 + ((i) * 5), 5) // i: 0-1
+#define WEIGHTED_PRED_FLAG BW_FIELD(121, 1)
+#define WEIGHTED_BIPRED_IDC BW_FIELD(122, 2)
+#define PIC_INIT_QP_MINUS26 BW_FIELD(124, 7)
+#define PIC_INIT_QS_MINUS26 BW_FIELD(131, 6)
+#define CHROMA_QP_INDEX_OFFSET BW_FIELD(137, 5)
+#define DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG BW_FIELD(142, 1)
+#define CONSTRAINED_INTRA_PRED_FLAG BW_FIELD(143, 1)
+#define REDUNDANT_PIC_CNT_PRESENT BW_FIELD(144, 1)
+#define TRANSFORM_8X8_MODE_FLAG BW_FIELD(145, 1)
+#define SECOND_CHROMA_QP_INDEX_OFFSET BW_FIELD(146, 5)
+#define SCALING_LIST_ENABLE_FLAG BW_FIELD(151, 1)
+#define IS_LONG_TERM(i) BW_FIELD(152 + (i), 1) // i: 0-15
+
+#define PIC_FIELD_FLAG BW_FIELD(184, 1)
+#define PIC_ASSOCIATED_FLAG BW_FIELD(185, 1)
+#define CUR_TOP_FIELD BW_FIELD(186, 32)
+#define CUR_BOT_FIELD BW_FIELD(218, 32)
+
+#define TOP_FIELD_ORDER_CNT(i) BW_FIELD(250 + (i) * 64, 32) // i: 0-15
+#define BOT_FIELD_ORDER_CNT(i) BW_FIELD(282 + (i) * 64, 32) // i: 0-15
+
+#define REF_FIELD_FLAGS(i) BW_FIELD(1274 + (i), 1) // i: 0-15
+#define REF_TOPFIELD_USED(i) BW_FIELD(1290 + (i), 1) // i: 0-15
+#define REF_BOTFIELD_USED(i) BW_FIELD(1306 + (i), 1) // i: 0-15
+#define REF_COLMV_USE_FLAG(i) BW_FIELD(1322 + (i), 1) // i: 0-15
+
+#define SPS_SIZE ALIGN(1322 + 16, 128)
struct rkvdec_sps_pps {
- struct rkvdec_sps sps;
- struct rkvdec_pps pps;
+ u32 info[SPS_SIZE / 8 / 4];
} __packed;
/* Data structure describing auxiliary buffer format. */
@@ -130,67 +89,6 @@ struct rkvdec_h264_ctx {
struct vdpu383_regs_h26x regs;
};
-static noinline_for_stack void set_field_order_cnt(struct rkvdec_pps *pps, const struct v4l2_h264_dpb_entry *dpb)
-{
- pps->top_field_order_cnt0 = dpb[0].top_field_order_cnt;
- pps->bot_field_order_cnt0 = dpb[0].bottom_field_order_cnt;
- pps->top_field_order_cnt1 = dpb[1].top_field_order_cnt;
- pps->bot_field_order_cnt1 = dpb[1].bottom_field_order_cnt;
- pps->top_field_order_cnt2 = dpb[2].top_field_order_cnt;
- pps->bot_field_order_cnt2 = dpb[2].bottom_field_order_cnt;
- pps->top_field_order_cnt3 = dpb[3].top_field_order_cnt;
- pps->bot_field_order_cnt3 = dpb[3].bottom_field_order_cnt;
- pps->top_field_order_cnt4 = dpb[4].top_field_order_cnt;
- pps->bot_field_order_cnt4 = dpb[4].bottom_field_order_cnt;
- pps->top_field_order_cnt5 = dpb[5].top_field_order_cnt;
- pps->bot_field_order_cnt5 = dpb[5].bottom_field_order_cnt;
- pps->top_field_order_cnt6 = dpb[6].top_field_order_cnt;
- pps->bot_field_order_cnt6 = dpb[6].bottom_field_order_cnt;
- pps->top_field_order_cnt7 = dpb[7].top_field_order_cnt;
- pps->bot_field_order_cnt7 = dpb[7].bottom_field_order_cnt;
- pps->top_field_order_cnt8 = dpb[8].top_field_order_cnt;
- pps->bot_field_order_cnt8 = dpb[8].bottom_field_order_cnt;
- pps->top_field_order_cnt9 = dpb[9].top_field_order_cnt;
- pps->bot_field_order_cnt9 = dpb[9].bottom_field_order_cnt;
- pps->top_field_order_cnt10 = dpb[10].top_field_order_cnt;
- pps->bot_field_order_cnt10 = dpb[10].bottom_field_order_cnt;
- pps->top_field_order_cnt11 = dpb[11].top_field_order_cnt;
- pps->bot_field_order_cnt11 = dpb[11].bottom_field_order_cnt;
- pps->top_field_order_cnt12 = dpb[12].top_field_order_cnt;
- pps->bot_field_order_cnt12 = dpb[12].bottom_field_order_cnt;
- pps->top_field_order_cnt13 = dpb[13].top_field_order_cnt;
- pps->bot_field_order_cnt13 = dpb[13].bottom_field_order_cnt;
- pps->top_field_order_cnt14 = dpb[14].top_field_order_cnt;
- pps->bot_field_order_cnt14 = dpb[14].bottom_field_order_cnt;
- pps->top_field_order_cnt15 = dpb[15].top_field_order_cnt;
- pps->bot_field_order_cnt15 = dpb[15].bottom_field_order_cnt;
-}
-
-static noinline_for_stack void set_dec_params(struct rkvdec_pps *pps, const struct v4l2_ctrl_h264_decode_params *dec_params)
-{
- const struct v4l2_h264_dpb_entry *dpb = dec_params->dpb;
-
- for (int i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
- if (dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM)
- pps->is_longterm |= (1 << i);
- pps->ref_field_flags |=
- (!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD)) << i;
- pps->ref_colmv_use_flag |=
- (!!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE)) << i;
- pps->ref_topfield_used |=
- (!!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF)) << i;
- pps->ref_botfield_used |=
- (!!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF)) << i;
- }
- pps->pic_field_flag =
- !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC);
- pps->pic_associated_flag =
- !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD);
-
- pps->cur_top_field = dec_params->top_field_order_cnt;
- pps->cur_bot_field = dec_params->bottom_field_order_cnt;
-}
-
static void assemble_hw_pps(struct rkvdec_ctx *ctx,
struct rkvdec_h264_run *run)
{
@@ -202,6 +100,7 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
struct rkvdec_h264_priv_tbl *priv_tbl = h264_ctx->priv_tbl.cpu;
struct rkvdec_sps_pps *hw_ps;
u32 pic_width, pic_height;
+ int i;
/*
* HW read the SPS/PPS information from PPS packet index by PPS id.
@@ -213,23 +112,25 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
memset(hw_ps, 0, sizeof(*hw_ps));
/* write sps */
- hw_ps->sps.seq_parameter_set_id = sps->seq_parameter_set_id;
- hw_ps->sps.profile_idc = sps->profile_idc;
- hw_ps->sps.constraint_set3_flag = !!(sps->constraint_set_flags & (1 << 3));
- hw_ps->sps.chroma_format_idc = sps->chroma_format_idc;
- hw_ps->sps.bit_depth_luma = sps->bit_depth_luma_minus8;
- hw_ps->sps.bit_depth_chroma = sps->bit_depth_chroma_minus8;
- hw_ps->sps.qpprime_y_zero_transform_bypass_flag =
- !!(sps->flags & V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS);
- hw_ps->sps.log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4;
- hw_ps->sps.max_num_ref_frames = sps->max_num_ref_frames;
- hw_ps->sps.pic_order_cnt_type = sps->pic_order_cnt_type;
- hw_ps->sps.log2_max_pic_order_cnt_lsb_minus4 =
- sps->log2_max_pic_order_cnt_lsb_minus4;
- hw_ps->sps.delta_pic_order_always_zero_flag =
- !!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO);
- hw_ps->sps.mvc_extension_enable = 0;
- hw_ps->sps.num_views = 0;
+ rkvdec_set_bw_field(hw_ps->info, SEQ_PARAMETER_SET_ID, sps->seq_parameter_set_id);
+ rkvdec_set_bw_field(hw_ps->info, PROFILE_IDC, sps->profile_idc);
+ rkvdec_set_bw_field(hw_ps->info, CONSTRAINT_SET3_FLAG,
+ !!(sps->constraint_set_flags & (1 << 3)));
+ rkvdec_set_bw_field(hw_ps->info, CHROMA_FORMAT_IDC, sps->chroma_format_idc);
+ rkvdec_set_bw_field(hw_ps->info, BIT_DEPTH_LUMA, sps->bit_depth_luma_minus8);
+ rkvdec_set_bw_field(hw_ps->info, BIT_DEPTH_CHROMA, sps->bit_depth_chroma_minus8);
+ rkvdec_set_bw_field(hw_ps->info, QPPRIME_Y_ZERO_TRANSFORM_BYPASS_FLAG,
+ !!(sps->flags & V4L2_H264_SPS_FLAG_QPPRIME_Y_ZERO_TRANSFORM_BYPASS));
+ rkvdec_set_bw_field(hw_ps->info, LOG2_MAX_FRAME_NUM_MINUS4,
+ sps->log2_max_frame_num_minus4);
+ rkvdec_set_bw_field(hw_ps->info, MAX_NUM_REF_FRAMES, sps->max_num_ref_frames);
+ rkvdec_set_bw_field(hw_ps->info, PIC_ORDER_CNT_TYPE, sps->pic_order_cnt_type);
+ rkvdec_set_bw_field(hw_ps->info, LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4,
+ sps->log2_max_pic_order_cnt_lsb_minus4);
+ rkvdec_set_bw_field(hw_ps->info, DELTA_PIC_ORDER_ALWAYS_ZERO_FLAG,
+ !!(sps->flags & V4L2_H264_SPS_FLAG_DELTA_PIC_ORDER_ALWAYS_ZERO));
+ rkvdec_set_bw_field(hw_ps->info, MVC_EXTENSION_ENABLE, 0);
+ rkvdec_set_bw_field(hw_ps->info, NUM_VIEWS, 0);
/*
* Use the SPS values since they are already in macroblocks
@@ -245,48 +146,72 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
if (!!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC))
pic_height /= 2;
- hw_ps->sps.pic_width_in_mbs = pic_width;
- hw_ps->sps.pic_height_in_mbs = pic_height;
+ rkvdec_set_bw_field(hw_ps->info, PIC_WIDTH_IN_MBS, pic_width);
+ rkvdec_set_bw_field(hw_ps->info, PIC_HEIGHT_IN_MBS, pic_height);
- hw_ps->sps.frame_mbs_only_flag =
- !!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY);
- hw_ps->sps.mb_adaptive_frame_field_flag =
- !!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD);
- hw_ps->sps.direct_8x8_inference_flag =
- !!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE);
+ rkvdec_set_bw_field(hw_ps->info, FRAME_MBS_ONLY_FLAG,
+ !!(sps->flags & V4L2_H264_SPS_FLAG_FRAME_MBS_ONLY));
+ rkvdec_set_bw_field(hw_ps->info, MB_ADAPTIVE_FRAME_FIELD_FLAG,
+ !!(sps->flags & V4L2_H264_SPS_FLAG_MB_ADAPTIVE_FRAME_FIELD));
+ rkvdec_set_bw_field(hw_ps->info, DIRECT_8X8_INFERENCE_FLAG,
+ !!(sps->flags & V4L2_H264_SPS_FLAG_DIRECT_8X8_INFERENCE));
/* write pps */
- hw_ps->pps.pic_parameter_set_id = pps->pic_parameter_set_id;
- hw_ps->pps.pps_seq_parameter_set_id = pps->seq_parameter_set_id;
- hw_ps->pps.entropy_coding_mode_flag =
- !!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE);
- hw_ps->pps.bottom_field_pic_order_in_frame_present_flag =
- !!(pps->flags & V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT);
- hw_ps->pps.num_ref_idx_l0_default_active_minus1 =
- pps->num_ref_idx_l0_default_active_minus1;
- hw_ps->pps.num_ref_idx_l1_default_active_minus1 =
- pps->num_ref_idx_l1_default_active_minus1;
- hw_ps->pps.weighted_pred_flag =
- !!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED);
- hw_ps->pps.weighted_bipred_idc = pps->weighted_bipred_idc;
- hw_ps->pps.pic_init_qp_minus26 = pps->pic_init_qp_minus26;
- hw_ps->pps.pic_init_qs_minus26 = pps->pic_init_qs_minus26;
- hw_ps->pps.chroma_qp_index_offset = pps->chroma_qp_index_offset;
- hw_ps->pps.deblocking_filter_control_present_flag =
- !!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT);
- hw_ps->pps.constrained_intra_pred_flag =
- !!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED);
- hw_ps->pps.redundant_pic_cnt_present =
- !!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT);
- hw_ps->pps.transform_8x8_mode_flag =
- !!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE);
- hw_ps->pps.second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset;
- hw_ps->pps.scaling_list_enable_flag =
- !!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT);
-
- set_field_order_cnt(&hw_ps->pps, dpb);
- set_dec_params(&hw_ps->pps, dec_params);
+ rkvdec_set_bw_field(hw_ps->info, PIC_PARAMETER_SET_ID, pps->pic_parameter_set_id);
+ rkvdec_set_bw_field(hw_ps->info, PPS_SEQ_PARAMETER_SET_ID, pps->seq_parameter_set_id);
+ rkvdec_set_bw_field(hw_ps->info, ENTROPY_CODING_MODE_FLAG,
+ !!(pps->flags & V4L2_H264_PPS_FLAG_ENTROPY_CODING_MODE));
+ rkvdec_set_bw_field(hw_ps->info, BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT_FLAG,
+ !!(pps->flags &
+ V4L2_H264_PPS_FLAG_BOTTOM_FIELD_PIC_ORDER_IN_FRAME_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(0),
+ pps->num_ref_idx_l0_default_active_minus1);
+ rkvdec_set_bw_field(hw_ps->info, NUM_REF_IDX_L_DEFAULT_ACTIVE_MINUS1(1),
+ pps->num_ref_idx_l1_default_active_minus1);
+ rkvdec_set_bw_field(hw_ps->info, WEIGHTED_PRED_FLAG,
+ !!(pps->flags & V4L2_H264_PPS_FLAG_WEIGHTED_PRED));
+ rkvdec_set_bw_field(hw_ps->info, WEIGHTED_BIPRED_IDC, pps->weighted_bipred_idc);
+ rkvdec_set_bw_field(hw_ps->info, PIC_INIT_QP_MINUS26, pps->pic_init_qp_minus26);
+ rkvdec_set_bw_field(hw_ps->info, PIC_INIT_QS_MINUS26, pps->pic_init_qs_minus26);
+ rkvdec_set_bw_field(hw_ps->info, CHROMA_QP_INDEX_OFFSET, pps->chroma_qp_index_offset);
+ rkvdec_set_bw_field(hw_ps->info, DEBLOCKING_FILTER_CONTROL_PRESENT_FLAG,
+ !!(pps->flags & V4L2_H264_PPS_FLAG_DEBLOCKING_FILTER_CONTROL_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, CONSTRAINED_INTRA_PRED_FLAG,
+ !!(pps->flags & V4L2_H264_PPS_FLAG_CONSTRAINED_INTRA_PRED));
+ rkvdec_set_bw_field(hw_ps->info, REDUNDANT_PIC_CNT_PRESENT,
+ !!(pps->flags & V4L2_H264_PPS_FLAG_REDUNDANT_PIC_CNT_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, TRANSFORM_8X8_MODE_FLAG,
+ !!(pps->flags & V4L2_H264_PPS_FLAG_TRANSFORM_8X8_MODE));
+ rkvdec_set_bw_field(hw_ps->info, SECOND_CHROMA_QP_INDEX_OFFSET,
+ pps->second_chroma_qp_index_offset);
+ rkvdec_set_bw_field(hw_ps->info, SCALING_LIST_ENABLE_FLAG,
+ !!(pps->flags & V4L2_H264_PPS_FLAG_SCALING_MATRIX_PRESENT));
+
+ for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
+ rkvdec_set_bw_field(hw_ps->info, TOP_FIELD_ORDER_CNT(i),
+ dpb[i].top_field_order_cnt);
+ rkvdec_set_bw_field(hw_ps->info, BOT_FIELD_ORDER_CNT(i),
+ dpb[i].bottom_field_order_cnt);
+
+ rkvdec_set_bw_field(hw_ps->info, IS_LONG_TERM(i),
+ !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_LONG_TERM));
+ rkvdec_set_bw_field(hw_ps->info, REF_FIELD_FLAGS(i),
+ !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_FIELD));
+ rkvdec_set_bw_field(hw_ps->info, REF_COLMV_USE_FLAG(i),
+ !!(dpb[i].flags & V4L2_H264_DPB_ENTRY_FLAG_ACTIVE));
+ rkvdec_set_bw_field(hw_ps->info, REF_TOPFIELD_USED(i),
+ !!(dpb[i].fields & V4L2_H264_TOP_FIELD_REF));
+ rkvdec_set_bw_field(hw_ps->info, REF_BOTFIELD_USED(i),
+ !!(dpb[i].fields & V4L2_H264_BOTTOM_FIELD_REF));
+ }
+
+ rkvdec_set_bw_field(hw_ps->info, PIC_FIELD_FLAG,
+ !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC));
+ rkvdec_set_bw_field(hw_ps->info, PIC_ASSOCIATED_FLAG,
+ !!(dec_params->flags & V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD));
+ rkvdec_set_bw_field(hw_ps->info, CUR_TOP_FIELD, dec_params->top_field_order_cnt);
+ rkvdec_set_bw_field(hw_ps->info, CUR_BOT_FIELD, dec_params->bottom_field_order_cnt);
}
static void rkvdec_write_regs(struct rkvdec_ctx *ctx)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
index 96d938ee70b0..3575338a531a 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c
@@ -13,149 +13,106 @@
#include "rkvdec-rcb.h"
#include "rkvdec-hevc-common.h"
#include "rkvdec-vdpu383-regs.h"
+#include "rkvdec-bitwriter.h"
+
+#define VIDEO_PARAMETER_SET_ID BW_FIELD(0, 4)
+#define SEQ_PARAMETER_SET_ID BW_FIELD(4, 4)
+#define CHROMA_FORMAT_IDC BW_FIELD(8, 2)
+#define PIC_WIDTH_IN_LUMA_SAMPLES BW_FIELD(10, 16)
+#define PIC_HEIGHT_IN_LUMA_SAMPLES BW_FIELD(26, 16)
+#define BIT_DEPTH_LUMA BW_FIELD(42, 3)
+#define BIT_DEPTH_CHROMA BW_FIELD(45, 3)
+#define LOG2_MAX_PIC_ORDER_CNT_LSB BW_FIELD(48, 5)
+#define LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE BW_FIELD(53, 2)
+#define LOG2_MIN_LUMA_CODING_BLOCK_SIZE BW_FIELD(55, 3)
+#define LOG2_MIN_TRANSFORM_BLOCK_SIZE BW_FIELD(58, 3)
+#define LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE BW_FIELD(61, 2)
+#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTER BW_FIELD(63, 3)
+#define MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA BW_FIELD(66, 3)
+#define SCALING_LIST_ENABLED_FLAG BW_FIELD(69, 1)
+#define AMP_ENABLED_FLAG BW_FIELD(70, 1)
+#define SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG BW_FIELD(71, 1)
+#define PCM_ENABLED_FLAG BW_FIELD(72, 1)
+#define PCM_SAMPLE_BIT_DEPTH_LUMA BW_FIELD(73, 4)
+#define PCM_SAMPLE_BIT_DEPTH_CHROMA BW_FIELD(77, 4)
+#define PCM_LOOP_FILTER_DISABLED_FLAG BW_FIELD(81, 1)
+#define LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE BW_FIELD(82, 3)
+#define LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE BW_FIELD(85, 3)
+#define NUM_SHORT_TERM_REF_PIC_SETS BW_FIELD(88, 7)
+#define LONG_TERM_REF_PICS_PRESENT_FLAG BW_FIELD(95, 1)
+#define NUM_LONG_TERM_REF_PICS_SPS BW_FIELD(96, 6)
+#define SPS_TEMPORAL_MVP_ENABLED_FLAG BW_FIELD(102, 1)
+#define STRONG_INTRA_SMOOTHING_ENABLED_FLAG BW_FIELD(103, 1)
+#define SPS_MAX_DEC_PIC_BUFFERING_MINUS1 BW_FIELD(111, 4)
+#define SEPARATE_COLOUR_PLANE_FLAG BW_FIELD(115, 1)
+#define HIGH_PRECISION_OFFSETS_ENABLED_FLAG BW_FIELD(116, 1)
+#define PERSISTENT_RICE_ADAPTATION_ENABLED_FLAG BW_FIELD(117, 1)
+
+/* PPS */
+#define PIC_PARAMETER_SET_ID BW_FIELD(118, 6)
+#define PPS_SEQ_PARAMETER_SET_ID BW_FIELD(124, 4)
+#define DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG BW_FIELD(128, 1)
+#define OUTPUT_FLAG_PRESENT_FLAG BW_FIELD(129, 1)
+#define NUM_EXTRA_SLICE_HEADER_BITS BW_FIELD(130, 13)
+#define SIGN_DATA_HIDING_ENABLED_FLAG BW_FIELD(143, 1)
+#define CABAC_INIT_PRESENT_FLAG BW_FIELD(144, 1)
+#define NUM_REF_IDX_L0_DEFAULT_ACTIVE BW_FIELD(145, 4)
+#define NUM_REF_IDX_L1_DEFAULT_ACTIVE BW_FIELD(149, 4)
+#define INIT_QP_MINUS26 BW_FIELD(153, 7)
+#define CONSTRAINED_INTRA_PRED_FLAG BW_FIELD(160, 1)
+#define TRANSFORM_SKIP_ENABLED_FLAG BW_FIELD(161, 1)
+#define CU_QP_DELTA_ENABLED_FLAG BW_FIELD(162, 1)
+#define LOG2_MIN_CU_QP_DELTA_SIZE BW_FIELD(163, 3)
+#define PPS_CB_QP_OFFSET BW_FIELD(166, 5)
+#define PPS_CR_QP_OFFSET BW_FIELD(171, 5)
+#define PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG BW_FIELD(176, 1)
+#define WEIGHTED_PRED_FLAG BW_FIELD(177, 1)
+#define WEIGHTED_BIPRED_FLAG BW_FIELD(178, 1)
+#define TRANSQUANT_BYPASS_ENABLED_FLAG BW_FIELD(179, 1)
+#define TILES_ENABLED_FLAG BW_FIELD(180, 1)
+#define ENTROPY_CODING_SYNC_ENABLED_FLAG BW_FIELD(181, 1)
+#define PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG BW_FIELD(182, 1)
+#define LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG BW_FIELD(183, 1)
+#define DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG BW_FIELD(184, 1)
+#define PPS_DEBLOCKING_FILTER_DISABLED_FLAG BW_FIELD(185, 1)
+#define PPS_BETA_OFFSET_DIV2 BW_FIELD(186, 4)
+#define PPS_TC_OFFSET_DIV2 BW_FIELD(190, 4)
+#define LISTS_MODIFICATION_PRESENT_FLAG BW_FIELD(194, 1)
+#define LOG2_PARALLEL_MERGE_LEVEL BW_FIELD(195, 3)
+#define SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG BW_FIELD(198, 1)
+
+/* pps extensions */
+#define LOG2_MAX_TRANSFORM_SKIP_BLOCK_SIZE BW_FIELD(202, 2)
+#define CROSS_COMPONENT_PREDICTION_ENABLED_FLAG BW_FIELD(204, 1)
+#define CHROMA_QP_OFFSET_LIST_ENABLED_FLAG BW_FIELD(205, 1)
+#define LOG2_MIN_CU_CHROMA_QP_DELTA_SIZE BW_FIELD(206, 3)
+#define CB_QP_OFFSET_LIST(i) BW_FIELD(209 + (i) * 5, 5) // i: 0-5
+#define CB_CR_OFFSET_LIST(i) BW_FIELD(239 + (i) * 5, 5) // i: 0-5
+#define CHROMA_QP_OFFSET_LIST_LEN_MINUS1 BW_FIELD(269, 3)
+
+/* mvc0 && mvc1 */
+#define MVC_FF BW_FIELD(272, 16)
+#define MVC_00 BW_FIELD(288, 9)
+
+/* poc info */
+#define RESERVED2 BW_FIELD(297, 3)
+#define CURRENT_POC BW_FIELD(300, 32)
+#define REF_PIC_POC(i) BW_FIELD(332 + (i) * 32, 32) // i: 0-14
+#define RESERVED3 BW_FIELD(812, 32)
+#define REF_IS_VALID(i) BW_FIELD(844 + (i), 1) // i: 0-14
+#define RESERVED4 BW_FIELD(859, 1)
+
+/* tile info*/
+#define NUM_TILE_COLUMNS BW_FIELD(860, 5)
+#define NUM_TILE_ROWS BW_FIELD(865, 5)
+#define COLUMN_WIDTH(i) BW_FIELD(870 + (i) * 12, 12) // i: 0-19
+#define ROW_HEIGHT(i) BW_FIELD(1110 + (i) * 12, 12) // i: 0-21
+
+#define HEVC_SPS_SIZE ALIGN(1110 + 22 * 12, 256)
struct rkvdec_hevc_sps_pps {
- // SPS
- u16 video_parameters_set_id : 4;
- u16 seq_parameters_set_id_sps : 4;
- u16 chroma_format_idc : 2;
- u16 width : 16;
- u16 height : 16;
- u16 bit_depth_luma : 3;
- u16 bit_depth_chroma : 3;
- u16 max_pic_order_count_lsb : 5;
- u16 diff_max_min_luma_coding_block_size : 2;
- u16 min_luma_coding_block_size : 3;
- u16 min_transform_block_size : 3;
- u16 diff_max_min_transform_block_size : 2;
- u16 max_transform_hierarchy_depth_inter : 3;
- u16 max_transform_hierarchy_depth_intra : 3;
- u16 scaling_list_enabled_flag : 1;
- u16 amp_enabled_flag : 1;
- u16 sample_adaptive_offset_enabled_flag : 1;
- u16 pcm_enabled_flag : 1;
- u16 pcm_sample_bit_depth_luma : 4;
- u16 pcm_sample_bit_depth_chroma : 4;
- u16 pcm_loop_filter_disabled_flag : 1;
- u16 diff_max_min_pcm_luma_coding_block_size : 3;
- u16 min_pcm_luma_coding_block_size : 3;
- u16 num_short_term_ref_pic_sets : 7;
- u16 long_term_ref_pics_present_flag : 1;
- u16 num_long_term_ref_pics_sps : 6;
- u16 sps_temporal_mvp_enabled_flag : 1;
- u16 strong_intra_smoothing_enabled_flag : 1;
- u16 reserved0 : 7;
- u16 sps_max_dec_pic_buffering_minus1 : 4;
- u16 separate_colour_plane_flag : 1;
- u16 high_precision_offsets_enabled_flag : 1;
- u16 persistent_rice_adaptation_enabled_flag : 1;
-
- // PPS
- u16 picture_parameters_set_id : 6;
- u16 seq_parameters_set_id_pps : 4;
- u16 dependent_slice_segments_enabled_flag : 1;
- u16 output_flag_present_flag : 1;
- u16 num_extra_slice_header_bits : 13;
- u16 sign_data_hiding_enabled_flag : 1;
- u16 cabac_init_present_flag : 1;
- u16 num_ref_idx_l0_default_active : 4;
- u16 num_ref_idx_l1_default_active : 4;
- u16 init_qp_minus26 : 7;
- u16 constrained_intra_pred_flag : 1;
- u16 transform_skip_enabled_flag : 1;
- u16 cu_qp_delta_enabled_flag : 1;
- u16 log2_min_cb_size : 3;
- u16 pps_cb_qp_offset : 5;
- u16 pps_cr_qp_offset : 5;
- u16 pps_slice_chroma_qp_offsets_present_flag : 1;
- u16 weighted_pred_flag : 1;
- u16 weighted_bipred_flag : 1;
- u16 transquant_bypass_enabled_flag : 1;
- u16 tiles_enabled_flag : 1;
- u16 entropy_coding_sync_enabled_flag : 1;
- u16 pps_loop_filter_across_slices_enabled_flag : 1;
- u16 loop_filter_across_tiles_enabled_flag : 1;
- u16 deblocking_filter_override_enabled_flag : 1;
- u16 pps_deblocking_filter_disabled_flag : 1;
- u16 pps_beta_offset_div2 : 4;
- u16 pps_tc_offset_div2 : 4;
- u16 lists_modification_present_flag : 1;
- u16 log2_parallel_merge_level : 3;
- u16 slice_segment_header_extension_present_flag : 1;
- u16 reserved1 : 3;
-
- // pps extensions
- u16 log2_max_transform_skip_block_size : 2;
- u16 cross_component_prediction_enabled_flag : 1;
- u16 chroma_qp_offset_list_enabled_flag : 1;
- u16 log2_min_cu_chroma_qp_delta_size : 3;
- u16 cb_qp_offset_list0 : 5;
- u16 cb_qp_offset_list1 : 5;
- u16 cb_qp_offset_list2 : 5;
- u16 cb_qp_offset_list3 : 5;
- u16 cb_qp_offset_list4 : 5;
- u16 cb_qp_offset_list5 : 5;
- u16 cb_cr_offset_list0 : 5;
- u16 cb_cr_offset_list1 : 5;
- u16 cb_cr_offset_list2 : 5;
- u16 cb_cr_offset_list3 : 5;
- u16 cb_cr_offset_list4 : 5;
- u16 cb_cr_offset_list5 : 5;
- u16 chroma_qp_offset_list_len_minus1 : 3;
-
- /* mvc0 && mvc1 */
- u16 mvc_ff : 16;
- u16 mvc_00 : 9;
-
- /* poc info */
- u16 reserved2 : 3;
- u32 current_poc : 32;
- u32 ref_pic_poc0 : 32;
- u32 ref_pic_poc1 : 32;
- u32 ref_pic_poc2 : 32;
- u32 ref_pic_poc3 : 32;
- u32 ref_pic_poc4 : 32;
- u32 ref_pic_poc5 : 32;
- u32 ref_pic_poc6 : 32;
- u32 ref_pic_poc7 : 32;
- u32 ref_pic_poc8 : 32;
- u32 ref_pic_poc9 : 32;
- u32 ref_pic_poc10 : 32;
- u32 ref_pic_poc11 : 32;
- u32 ref_pic_poc12 : 32;
- u32 ref_pic_poc13 : 32;
- u32 ref_pic_poc14 : 32;
- u32 reserved3 : 32;
- u32 ref_is_valid : 15;
- u32 reserved4 : 1;
-
- /* tile info*/
- u16 num_tile_columns : 5;
- u16 num_tile_rows : 5;
- u32 column_width0 : 24;
- u32 column_width1 : 24;
- u32 column_width2 : 24;
- u32 column_width3 : 24;
- u32 column_width4 : 24;
- u32 column_width5 : 24;
- u32 column_width6 : 24;
- u32 column_width7 : 24;
- u32 column_width8 : 24;
- u32 column_width9 : 24;
- u32 row_height0 : 24;
- u32 row_height1 : 24;
- u32 row_height2 : 24;
- u32 row_height3 : 24;
- u32 row_height4 : 24;
- u32 row_height5 : 24;
- u32 row_height6 : 24;
- u32 row_height7 : 24;
- u32 row_height8 : 24;
- u32 row_height9 : 24;
- u32 row_height10 : 24;
- u32 reserved5 : 2;
- u32 padding;
-} __packed;
+ u32 info[HEVC_SPS_SIZE / 8 / 4];
+};
struct rkvdec_hevc_priv_tbl {
struct rkvdec_hevc_sps_pps param_set;
@@ -171,51 +128,6 @@ struct rkvdec_hevc_ctx {
struct vdpu383_regs_h26x regs;
};
-static void set_column_row(struct rkvdec_hevc_sps_pps *hw_ps, u16 *column, u16 *row)
-{
- hw_ps->column_width0 = column[0] | (column[1] << 12);
- hw_ps->row_height0 = row[0] | (row[1] << 12);
- hw_ps->column_width1 = column[2] | (column[3] << 12);
- hw_ps->row_height1 = row[2] | (row[3] << 12);
- hw_ps->column_width2 = column[4] | (column[5] << 12);
- hw_ps->row_height2 = row[4] | (row[5] << 12);
- hw_ps->column_width3 = column[6] | (column[7] << 12);
- hw_ps->row_height3 = row[6] | (row[7] << 12);
- hw_ps->column_width4 = column[8] | (column[9] << 12);
- hw_ps->row_height4 = row[8] | (row[9] << 12);
- hw_ps->column_width5 = column[10] | (column[11] << 12);
- hw_ps->row_height5 = row[10] | (row[11] << 12);
- hw_ps->column_width6 = column[12] | (column[13] << 12);
- hw_ps->row_height6 = row[12] | (row[13] << 12);
- hw_ps->column_width7 = column[14] | (column[15] << 12);
- hw_ps->row_height7 = row[14] | (row[15] << 12);
- hw_ps->column_width8 = column[16] | (column[17] << 12);
- hw_ps->row_height8 = row[16] | (row[17] << 12);
- hw_ps->column_width9 = column[18] | (column[19] << 12);
- hw_ps->row_height9 = row[18] | (row[19] << 12);
-
- hw_ps->row_height10 = row[20] | (row[21] << 12);
-}
-
-static void set_pps_ref_pic_poc(struct rkvdec_hevc_sps_pps *hw_ps, const struct v4l2_hevc_dpb_entry *dpb)
-{
- hw_ps->ref_pic_poc0 = dpb[0].pic_order_cnt_val;
- hw_ps->ref_pic_poc1 = dpb[1].pic_order_cnt_val;
- hw_ps->ref_pic_poc2 = dpb[2].pic_order_cnt_val;
- hw_ps->ref_pic_poc3 = dpb[3].pic_order_cnt_val;
- hw_ps->ref_pic_poc4 = dpb[4].pic_order_cnt_val;
- hw_ps->ref_pic_poc5 = dpb[5].pic_order_cnt_val;
- hw_ps->ref_pic_poc6 = dpb[6].pic_order_cnt_val;
- hw_ps->ref_pic_poc7 = dpb[7].pic_order_cnt_val;
- hw_ps->ref_pic_poc8 = dpb[8].pic_order_cnt_val;
- hw_ps->ref_pic_poc9 = dpb[9].pic_order_cnt_val;
- hw_ps->ref_pic_poc10 = dpb[10].pic_order_cnt_val;
- hw_ps->ref_pic_poc11 = dpb[11].pic_order_cnt_val;
- hw_ps->ref_pic_poc12 = dpb[12].pic_order_cnt_val;
- hw_ps->ref_pic_poc13 = dpb[13].pic_order_cnt_val;
- hw_ps->ref_pic_poc14 = dpb[14].pic_order_cnt_val;
-}
-
static void assemble_hw_pps(struct rkvdec_ctx *ctx,
struct rkvdec_hevc_run *run)
{
@@ -245,104 +157,130 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
memset(hw_ps, 0, sizeof(*hw_ps));
/* write sps */
- hw_ps->video_parameters_set_id = sps->video_parameter_set_id;
- hw_ps->seq_parameters_set_id_sps = sps->seq_parameter_set_id;
- hw_ps->chroma_format_idc = sps->chroma_format_idc;
+ rkvdec_set_bw_field(hw_ps->info, VIDEO_PARAMETER_SET_ID, sps->video_parameter_set_id);
+ rkvdec_set_bw_field(hw_ps->info, SEQ_PARAMETER_SET_ID, sps->seq_parameter_set_id);
+ rkvdec_set_bw_field(hw_ps->info, CHROMA_FORMAT_IDC, sps->chroma_format_idc);
log2_min_cb_size = sps->log2_min_luma_coding_block_size_minus3 + 3;
width = sps->pic_width_in_luma_samples;
height = sps->pic_height_in_luma_samples;
- hw_ps->width = width;
- hw_ps->height = height;
- hw_ps->bit_depth_luma = sps->bit_depth_luma_minus8 + 8;
- hw_ps->bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
- hw_ps->max_pic_order_count_lsb = sps->log2_max_pic_order_cnt_lsb_minus4 + 4;
- hw_ps->diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_luma_coding_block_size;
- hw_ps->min_luma_coding_block_size = sps->log2_min_luma_coding_block_size_minus3 + 3;
- hw_ps->min_transform_block_size = sps->log2_min_luma_transform_block_size_minus2 + 2;
- hw_ps->diff_max_min_transform_block_size =
- sps->log2_diff_max_min_luma_transform_block_size;
- hw_ps->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
- hw_ps->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
- hw_ps->scaling_list_enabled_flag =
- !!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED);
- hw_ps->amp_enabled_flag = !!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED);
- hw_ps->sample_adaptive_offset_enabled_flag =
- !!(sps->flags & V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET);
+
+ rkvdec_set_bw_field(hw_ps->info, PIC_WIDTH_IN_LUMA_SAMPLES, width);
+ rkvdec_set_bw_field(hw_ps->info, PIC_HEIGHT_IN_LUMA_SAMPLES, height);
+ rkvdec_set_bw_field(hw_ps->info, BIT_DEPTH_LUMA, sps->bit_depth_luma_minus8 + 8);
+ rkvdec_set_bw_field(hw_ps->info, BIT_DEPTH_CHROMA, sps->bit_depth_chroma_minus8 + 8);
+ rkvdec_set_bw_field(hw_ps->info, LOG2_MAX_PIC_ORDER_CNT_LSB,
+ sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
+ rkvdec_set_bw_field(hw_ps->info, LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE,
+ sps->log2_diff_max_min_luma_coding_block_size);
+ rkvdec_set_bw_field(hw_ps->info, LOG2_MIN_LUMA_CODING_BLOCK_SIZE,
+ sps->log2_min_luma_coding_block_size_minus3 + 3);
+ rkvdec_set_bw_field(hw_ps->info, LOG2_MIN_TRANSFORM_BLOCK_SIZE,
+ sps->log2_min_luma_transform_block_size_minus2 + 2);
+ rkvdec_set_bw_field(hw_ps->info, LOG2_DIFF_MAX_MIN_LUMA_TRANSFORM_BLOCK_SIZE,
+ sps->log2_diff_max_min_luma_transform_block_size);
+ rkvdec_set_bw_field(hw_ps->info, MAX_TRANSFORM_HIERARCHY_DEPTH_INTER,
+ sps->max_transform_hierarchy_depth_inter);
+ rkvdec_set_bw_field(hw_ps->info, MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA,
+ sps->max_transform_hierarchy_depth_intra);
+ rkvdec_set_bw_field(hw_ps->info, SCALING_LIST_ENABLED_FLAG,
+ !!(sps->flags & V4L2_HEVC_SPS_FLAG_SCALING_LIST_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, AMP_ENABLED_FLAG,
+ !!(sps->flags & V4L2_HEVC_SPS_FLAG_AMP_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, SAMPLE_ADAPTIVE_OFFSET_ENABLED_FLAG,
+ !!(sps->flags & V4L2_HEVC_SPS_FLAG_SAMPLE_ADAPTIVE_OFFSET));
pcm_enabled = !!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_ENABLED);
- hw_ps->pcm_enabled_flag = pcm_enabled;
- hw_ps->pcm_sample_bit_depth_luma =
- pcm_enabled ? sps->pcm_sample_bit_depth_luma_minus1 + 1 : 0;
- hw_ps->pcm_sample_bit_depth_chroma =
- pcm_enabled ? sps->pcm_sample_bit_depth_chroma_minus1 + 1 : 0;
- hw_ps->pcm_loop_filter_disabled_flag =
- !!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED);
- hw_ps->diff_max_min_pcm_luma_coding_block_size =
- sps->log2_diff_max_min_pcm_luma_coding_block_size;
- hw_ps->min_pcm_luma_coding_block_size =
- pcm_enabled ? sps->log2_min_pcm_luma_coding_block_size_minus3 + 3 : 0;
- hw_ps->num_short_term_ref_pic_sets = sps->num_short_term_ref_pic_sets;
- hw_ps->long_term_ref_pics_present_flag =
- !!(sps->flags & V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT);
- hw_ps->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
- hw_ps->sps_temporal_mvp_enabled_flag =
- !!(sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED);
- hw_ps->strong_intra_smoothing_enabled_flag =
- !!(sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED);
- hw_ps->sps_max_dec_pic_buffering_minus1 = sps->sps_max_dec_pic_buffering_minus1;
+ rkvdec_set_bw_field(hw_ps->info, PCM_ENABLED_FLAG, pcm_enabled);
+ rkvdec_set_bw_field(hw_ps->info, PCM_SAMPLE_BIT_DEPTH_LUMA,
+ pcm_enabled ? sps->pcm_sample_bit_depth_luma_minus1 + 1 : 0);
+ rkvdec_set_bw_field(hw_ps->info, PCM_SAMPLE_BIT_DEPTH_CHROMA,
+ pcm_enabled ? sps->pcm_sample_bit_depth_chroma_minus1 + 1 : 0);
+ rkvdec_set_bw_field(hw_ps->info, PCM_LOOP_FILTER_DISABLED_FLAG,
+ !!(sps->flags & V4L2_HEVC_SPS_FLAG_PCM_LOOP_FILTER_DISABLED));
+ rkvdec_set_bw_field(hw_ps->info, LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE,
+ sps->log2_diff_max_min_pcm_luma_coding_block_size);
+ rkvdec_set_bw_field(hw_ps->info, LOG2_MIN_PCM_LUMA_CODING_BLOCK_SIZE,
+ pcm_enabled ? sps->log2_min_pcm_luma_coding_block_size_minus3 + 3 : 0);
+ rkvdec_set_bw_field(hw_ps->info, NUM_SHORT_TERM_REF_PIC_SETS,
+ sps->num_short_term_ref_pic_sets);
+ rkvdec_set_bw_field(hw_ps->info, LONG_TERM_REF_PICS_PRESENT_FLAG,
+ !!(sps->flags & V4L2_HEVC_SPS_FLAG_LONG_TERM_REF_PICS_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, NUM_LONG_TERM_REF_PICS_SPS,
+ sps->num_long_term_ref_pics_sps);
+ rkvdec_set_bw_field(hw_ps->info, SPS_TEMPORAL_MVP_ENABLED_FLAG,
+ !!(sps->flags & V4L2_HEVC_SPS_FLAG_SPS_TEMPORAL_MVP_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, STRONG_INTRA_SMOOTHING_ENABLED_FLAG,
+ !!(sps->flags & V4L2_HEVC_SPS_FLAG_STRONG_INTRA_SMOOTHING_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, SPS_MAX_DEC_PIC_BUFFERING_MINUS1,
+ sps->sps_max_dec_pic_buffering_minus1);
/* write pps */
- hw_ps->picture_parameters_set_id = pps->pic_parameter_set_id;
- hw_ps->seq_parameters_set_id_pps = sps->seq_parameter_set_id;
- hw_ps->dependent_slice_segments_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED);
- hw_ps->output_flag_present_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT);
- hw_ps->num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
- hw_ps->sign_data_hiding_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED);
- hw_ps->cabac_init_present_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT);
- hw_ps->num_ref_idx_l0_default_active = pps->num_ref_idx_l0_default_active_minus1 + 1;
- hw_ps->num_ref_idx_l1_default_active = pps->num_ref_idx_l1_default_active_minus1 + 1;
- hw_ps->init_qp_minus26 = pps->init_qp_minus26;
- hw_ps->constrained_intra_pred_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED);
- hw_ps->transform_skip_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED);
- hw_ps->cu_qp_delta_enabled_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED);
- hw_ps->log2_min_cb_size = log2_min_cb_size +
- sps->log2_diff_max_min_luma_coding_block_size -
- pps->diff_cu_qp_delta_depth;
- hw_ps->pps_cb_qp_offset = pps->pps_cb_qp_offset;
- hw_ps->pps_cr_qp_offset = pps->pps_cr_qp_offset;
- hw_ps->pps_slice_chroma_qp_offsets_present_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT);
- hw_ps->weighted_pred_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED);
- hw_ps->weighted_bipred_flag = !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED);
- hw_ps->transquant_bypass_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED);
+ rkvdec_set_bw_field(hw_ps->info, PIC_PARAMETER_SET_ID, pps->pic_parameter_set_id);
+ rkvdec_set_bw_field(hw_ps->info, SEQ_PARAMETER_SET_ID, sps->seq_parameter_set_id);
+ rkvdec_set_bw_field(hw_ps->info, DEPENDENT_SLICE_SEGMENTS_ENABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_DEPENDENT_SLICE_SEGMENT_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, OUTPUT_FLAG_PRESENT_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_OUTPUT_FLAG_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, NUM_EXTRA_SLICE_HEADER_BITS,
+ pps->num_extra_slice_header_bits);
+ rkvdec_set_bw_field(hw_ps->info, SIGN_DATA_HIDING_ENABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_SIGN_DATA_HIDING_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, CABAC_INIT_PRESENT_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_CABAC_INIT_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, NUM_REF_IDX_L0_DEFAULT_ACTIVE,
+ pps->num_ref_idx_l0_default_active_minus1 + 1);
+ rkvdec_set_bw_field(hw_ps->info, NUM_REF_IDX_L1_DEFAULT_ACTIVE,
+ pps->num_ref_idx_l1_default_active_minus1 + 1);
+ rkvdec_set_bw_field(hw_ps->info, INIT_QP_MINUS26, pps->init_qp_minus26);
+ rkvdec_set_bw_field(hw_ps->info, CONSTRAINED_INTRA_PRED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_CONSTRAINED_INTRA_PRED));
+ rkvdec_set_bw_field(hw_ps->info, TRANSFORM_SKIP_ENABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSFORM_SKIP_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, CU_QP_DELTA_ENABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_CU_QP_DELTA_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, LOG2_MIN_CU_QP_DELTA_SIZE, log2_min_cb_size +
+ sps->log2_diff_max_min_luma_coding_block_size -
+ pps->diff_cu_qp_delta_depth);
+ rkvdec_set_bw_field(hw_ps->info, PPS_CB_QP_OFFSET, pps->pps_cb_qp_offset);
+ rkvdec_set_bw_field(hw_ps->info, PPS_CR_QP_OFFSET, pps->pps_cr_qp_offset);
+ rkvdec_set_bw_field(hw_ps->info, PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT_FLAG,
+ !!(pps->flags &
+ V4L2_HEVC_PPS_FLAG_PPS_SLICE_CHROMA_QP_OFFSETS_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, WEIGHTED_PRED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_PRED));
+ rkvdec_set_bw_field(hw_ps->info, WEIGHTED_BIPRED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_WEIGHTED_BIPRED));
+ rkvdec_set_bw_field(hw_ps->info, TRANSQUANT_BYPASS_ENABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_TRANSQUANT_BYPASS_ENABLED));
tiles_enabled = !!(pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED);
- hw_ps->tiles_enabled_flag = tiles_enabled;
- hw_ps->entropy_coding_sync_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED);
- hw_ps->pps_loop_filter_across_slices_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED);
- hw_ps->loop_filter_across_tiles_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED);
- hw_ps->deblocking_filter_override_enabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED);
- hw_ps->pps_deblocking_filter_disabled_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER);
- hw_ps->pps_beta_offset_div2 = pps->pps_beta_offset_div2;
- hw_ps->pps_tc_offset_div2 = pps->pps_tc_offset_div2;
- hw_ps->lists_modification_present_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT);
- hw_ps->log2_parallel_merge_level = pps->log2_parallel_merge_level_minus2 + 2;
- hw_ps->slice_segment_header_extension_present_flag =
- !!(pps->flags & V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT);
- hw_ps->num_tile_columns = tiles_enabled ? pps->num_tile_columns_minus1 + 1 : 1;
- hw_ps->num_tile_rows = tiles_enabled ? pps->num_tile_rows_minus1 + 1 : 1;
- hw_ps->mvc_ff = 0xffff;
+ rkvdec_set_bw_field(hw_ps->info, TILES_ENABLED_FLAG, tiles_enabled);
+ rkvdec_set_bw_field(hw_ps->info, ENTROPY_CODING_SYNC_ENABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_ENTROPY_CODING_SYNC_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED_FLAG,
+ !!(pps->flags &
+ V4L2_HEVC_PPS_FLAG_PPS_LOOP_FILTER_ACROSS_SLICES_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, LOOP_FILTER_ACROSS_TILES_ENABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, DEBLOCKING_FILTER_OVERRIDE_ENABLED_FLAG,
+ !!(pps->flags &
+ V4L2_HEVC_PPS_FLAG_DEBLOCKING_FILTER_OVERRIDE_ENABLED));
+ rkvdec_set_bw_field(hw_ps->info, PPS_DEBLOCKING_FILTER_DISABLED_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_PPS_DISABLE_DEBLOCKING_FILTER));
+ rkvdec_set_bw_field(hw_ps->info, PPS_BETA_OFFSET_DIV2, pps->pps_beta_offset_div2);
+ rkvdec_set_bw_field(hw_ps->info, PPS_TC_OFFSET_DIV2, pps->pps_tc_offset_div2);
+ rkvdec_set_bw_field(hw_ps->info, LISTS_MODIFICATION_PRESENT_FLAG,
+ !!(pps->flags & V4L2_HEVC_PPS_FLAG_LISTS_MODIFICATION_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, LOG2_PARALLEL_MERGE_LEVEL,
+ pps->log2_parallel_merge_level_minus2 + 2);
+ rkvdec_set_bw_field(hw_ps->info, SLICE_SEGMENT_HEADER_EXTENSION_PRESENT_FLAG,
+ !!(pps->flags &
+ V4L2_HEVC_PPS_FLAG_SLICE_SEGMENT_HEADER_EXTENSION_PRESENT));
+ rkvdec_set_bw_field(hw_ps->info, NUM_TILE_COLUMNS,
+ tiles_enabled ? pps->num_tile_columns_minus1 + 1 : 1);
+ rkvdec_set_bw_field(hw_ps->info, NUM_TILE_ROWS,
+ tiles_enabled ? pps->num_tile_rows_minus1 + 1 : 1);
+ rkvdec_set_bw_field(hw_ps->info, MVC_FF, 0xffff);
// Setup tiles information
memset(column_width, 0, sizeof(column_width));
@@ -367,15 +305,19 @@ static void assemble_hw_pps(struct rkvdec_ctx *ctx,
row_height[0] = (height + max_cu_width - 1) / max_cu_width;
}
- set_column_row(hw_ps, column_width, row_height);
+ for (i = 0; i < 20; i++)
+ rkvdec_set_bw_field(hw_ps->info, COLUMN_WIDTH(i), column_width[i]);
+ for (i = 0; i < 22; i++)
+ rkvdec_set_bw_field(hw_ps->info, ROW_HEIGHT(i), row_height[i]);
// Setup POC information
- hw_ps->current_poc = dec_params->pic_order_cnt_val;
+ rkvdec_set_bw_field(hw_ps->info, CURRENT_POC, dec_params->pic_order_cnt_val);
- set_pps_ref_pic_poc(hw_ps, dec_params->dpb);
for (i = 0; i < ARRAY_SIZE(dec_params->dpb); i++) {
- u32 valid = !!(dec_params->num_active_dpb_entries > i);
- hw_ps->ref_is_valid |= valid << i;
+ rkvdec_set_bw_field(hw_ps->info, REF_IS_VALID(i),
+ !!(dec_params->num_active_dpb_entries > i));
+ rkvdec_set_bw_field(hw_ps->info, REF_PIC_POC(i),
+ dec_params->dpb[i].pic_order_cnt_val);
}
}
--
2.53.0
^ permalink raw reply related
* [PATCH] ARM: setup: NUL-terminate the fpe= emulator type
From: Pengpeng Hou @ 2026-04-02 13:50 UTC (permalink / raw)
To: linux-arm-kernel; +Cc: jbohac, akpm, linux-kernel, pengpeng
fpe_setup() copies the boot-time fpe= value into fpe_type[8] with a
raw 8-byte memcpy(). The NWFPE path later checks that value with
strcmp() to decide whether to install the emulator.
If the command line provides an 8-byte fpe= value, fpe_type is left
without a trailing NUL and strcmp() reads past the end of the array.
Store the option with strscpy() and leave room for the terminator.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
arch/arm/kernel/setup.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0bfd66c7ada0..815a53a8584d 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -24,6 +24,7 @@
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/proc_fs.h>
+#include <linux/string.h>
#include <linux/memblock.h>
#include <linux/bug.h>
#include <linux/compiler.h>
@@ -65,11 +66,11 @@
#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
-char fpe_type[8];
+char fpe_type[9];
static int __init fpe_setup(char *line)
{
- memcpy(fpe_type, line, 8);
+ strscpy(fpe_type, line, sizeof(fpe_type));
return 1;
}
--
2.50.1 (Apple Git-155)
^ permalink raw reply related
* Re: [PATCH 3/8] firmware: sysfb: Make CONFIG_SYSFB a user-selectable option
From: Thomas Zimmermann @ 2026-04-02 14:10 UTC (permalink / raw)
To: Arnd Bergmann, Javier Martinez Canillas, Ard Biesheuvel,
Ilias Apalodimas, Huacai Chen, WANG Xuerui, Maarten Lankhorst,
Maxime Ripard, Dave Airlie, Simona Vetter, K. Y. Srinivasan,
Haiyang Zhang, Wei Liu, Dexuan Cui, longli, Helge Deller
Cc: linux-arm-kernel, loongarch, linux-efi, linux-riscv, dri-devel,
linux-hyperv, linux-fbdev
In-Reply-To: <78f76717-8f1e-41d6-92f7-261df96b84b6@app.fastmail.com>
Hi
Am 02.04.26 um 15:08 schrieb Arnd Bergmann:
> On Thu, Apr 2, 2026, at 11:09, Thomas Zimmermann wrote:
>> Add a descriptive string and help text to CONFIG_SYSFB, so that users
>> can modify it. Flip all implicit selects in the Kconfig options into
>> dependencies. This avoids cyclic dependencies in the config.
>>
>> Enabling CONFIG_SYSFB makes the kernel provide a device for the firmware
>> framebuffer. As this can (slightly) affect system behavior, having a
>> user-facing option seems preferable. Some users might also want to set
>> every detail of their kernel config.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> I don't really like this part of the series and would prefer
> to keep CONFIG_SYSFB hidden as much as possible as an x86
> (and EFI) specific implementation detail, with the hope
> of eventually seperating out the x86 bits from the EFI ones.
You mean, you want to use the EFI-provided framebuffers without the
intermediate step of going through sysfb_primary_display?
In that case, CONFIG_SYSFB would become an x86-internal thing, right?
>
> In general, I am always in favor of properly using Kconfig
> dependencies over 'select' statements, for the same reasons
> you describe, but I don't want the the x86 logic for
> the legacy VESA and VGA console handling to leak into more
> architectures than necessary.
>
> Do you think we could instead move the sysfb_init()
> function into the same two places that contain the
> sysfb_primary_display definition (arch/x86/kernel/setup.c,
> drivers/firmware/efi/efi-init.c) and simplify the efi version
> to take out the x86 bits? That would reduce the rest
> of sysfb-primary.c to the logic to unregister the device,
> and that could then be selected by both x86 and EFI.
No, I'm more than happy that sysfb finally consolidates all the
init-framebuffer setup and detection that floated around in the kernel.
I would not want it to be duplicated again.
For now, we could certainly keep CONFIG_SYSFB hidden and autoselected.
Although I think this will require soem sort of solution at a later point.
Best regards
Thomas
>
> Arnd
--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstr. 146, 90461 Nürnberg, Germany, www.suse.com
GF: Jochen Jaser, Andrew McDonald, Werner Knoblich, (HRB 36809, AG Nürnberg)
^ permalink raw reply
* [PATCH] Bluetooth: btmtk: hide unused btmtk_mt6639_devs[] array
From: Arnd Bergmann @ 2026-04-02 14:11 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
AngeloGioacchino Del Regno, Javier Tia
Cc: Arnd Bergmann, Chris Lu, Kees Cook, Johan Hovold, Sean Wang,
Jiande Lu, linux-bluetooth, linux-kernel, linux-arm-kernel,
linux-mediatek
From: Arnd Bergmann <arnd@arndb.de>
When USB support is disabled, the array is not referenced anywhere,
causing a warning:
drivers/bluetooth/btmtk.c:35:3: error: 'btmtk_mt6639_devs' defined but not used [-Werror=unused-const-variable=]
35 | } btmtk_mt6639_devs[] = {
| ^~~~~~~~~~~~~~~~~
Move it into the #ifdef block.
Fixes: 4cdd001ff03f ("Bluetooth: btmtk: Add MT6639 (MT7927) Bluetooth support")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/bluetooth/btmtk.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 099188bf772e..6fb6ca274808 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -25,22 +25,6 @@
/* It is for mt79xx iso data transmission setting */
#define MTK_ISO_THRESHOLD 264
-/* Known MT6639 (MT7927) Bluetooth USB devices.
- * Used to scope the zero-CHIPID workaround to real MT6639 hardware,
- * since some boards return 0x0000 from the MMIO chip ID register.
- */
-static const struct {
- u16 vendor;
- u16 product;
-} btmtk_mt6639_devs[] = {
- { 0x0489, 0xe13a }, /* ASUS ROG Crosshair X870E Hero */
- { 0x0489, 0xe0fa }, /* Lenovo Legion Pro 7 16ARX9 */
- { 0x0489, 0xe10f }, /* Gigabyte Z790 AORUS MASTER X */
- { 0x0489, 0xe110 }, /* MSI X870E Ace Max */
- { 0x0489, 0xe116 }, /* TP-Link Archer TBE550E */
- { 0x13d3, 0x3588 }, /* ASUS ROG STRIX X870E-E */
-};
-
struct btmtk_patch_header {
u8 datetime[16];
u8 platform[4];
@@ -483,6 +467,22 @@ int btmtk_process_coredump(struct hci_dev *hdev, struct sk_buff *skb)
EXPORT_SYMBOL_GPL(btmtk_process_coredump);
#if IS_ENABLED(CONFIG_BT_HCIBTUSB_MTK)
+/* Known MT6639 (MT7927) Bluetooth USB devices.
+ * Used to scope the zero-CHIPID workaround to real MT6639 hardware,
+ * since some boards return 0x0000 from the MMIO chip ID register.
+ */
+static const struct {
+ u16 vendor;
+ u16 product;
+} btmtk_mt6639_devs[] = {
+ { 0x0489, 0xe13a }, /* ASUS ROG Crosshair X870E Hero */
+ { 0x0489, 0xe0fa }, /* Lenovo Legion Pro 7 16ARX9 */
+ { 0x0489, 0xe10f }, /* Gigabyte Z790 AORUS MASTER X */
+ { 0x0489, 0xe110 }, /* MSI X870E Ace Max */
+ { 0x0489, 0xe116 }, /* TP-Link Archer TBE550E */
+ { 0x13d3, 0x3588 }, /* ASUS ROG STRIX X870E-E */
+};
+
static void btmtk_usb_wmt_recv(struct urb *urb)
{
struct hci_dev *hdev = urb->context;
--
2.39.5
^ permalink raw reply related
* [PATCH v5 0/4] ARM: omap1: use real firmware node lookup for GPIOs on Nokia 770
From: Bartosz Golaszewski @ 2026-04-02 14:15 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Andy Shevchenko, Daniel Scally, Heikki Krogerus, Sakari Ailus,
Aaro Koskinen, Janusz Krzysztofik, Tony Lindgren, Russell King,
Dmitry Torokhov, Kevin Hilman, Arnd Bergmann
Cc: brgl, driver-core, linux-kernel, linux-acpi, linux-arm-kernel,
linux-omap, Bartosz Golaszewski
Mergin strategy: It would be awesome if patches 1-3 could make v7.1
through the driver core tree after which the final patch could go
through ARM-SoC separately in v7.2.
This converts Nokia 770 to using real firmware node lookup for GPIOs by
attaching the software nodes describing GPIO controllers to their target
devices.
As determined by Aaro's testing, both omap16xx_gpio_init() and
software_node_init() run in postcore_initcall() so we need to make
software nodes available earlier hence the new patches in v4.
Please note that while the goal of this series is to allow Nokia 770 to
use software nodes earlier, we're not modifying core kernel code just to
accomodate an old ARM platform - more such conversions are coming up so
the change will be useful to more consumers of the software node API.
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
Changes in v5:
- Put ksysfs_init() in a separate new header
- Remove software_node_exit() in a separate patch
- Link to v4: https://patch.msgid.link/20260330-nokia770-gpio-swnodes-v4-0-b68592e977d0@oss.qualcomm.com
Changes in v4:
- Add patches making software nodes available earlier
- Remove stray newline
- Link to v3: https://lore.kernel.org/all/20260212112508.73500-1-bartosz.golaszewski@oss.qualcomm.com/
Changes in v3:
- fix references to the MPU node
Changes in v2:
- fix build with CONFIG_I2C_CBUS_GPIO
- only export the two symbols that are actually required by the nokia
board file
---
Bartosz Golaszewski (4):
kernel: ksysfs: initialize kernel_kobj earlier
software node: remove software_node_exit()
driver core: make software nodes available earlier
ARM: omap1: enable real software node lookup of GPIOs on Nokia 770
MAINTAINERS | 1 +
arch/arm/mach-omap1/board-nokia770.c | 30 +++++-------------------------
arch/arm/mach-omap1/common.h | 3 +++
arch/arm/mach-omap1/gpio16xx.c | 28 +++++++++++++++++++++++++++-
drivers/base/base.h | 1 +
drivers/base/init.c | 1 +
drivers/base/swnode.c | 13 ++-----------
include/linux/ksysfs.h | 8 ++++++++
init/main.c | 2 ++
kernel/ksysfs.c | 9 ++++-----
10 files changed, 54 insertions(+), 42 deletions(-)
---
base-commit: bd0f139e5fc11182777b81cefc3893ea508544ec
change-id: 20260330-nokia770-gpio-swnodes-5da8ba35946e
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox