Hi,
While testing Linux kernel 6.12.42 on OpenWrt, we observed a
regression in IPv6 Router Advertisement (RA) handling for the default
router.
Affected commits
The following commits appear related and may have introduced the issue:
ipv6: fix possible infinite loop in fib6_info_uses_dev():
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=…
ipv6: prevent infinite loop in rt6_nlmsg_size():
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=…
ipv6: annotate data-races around rt->fib6_nsiblings:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=…
Problem description:
In Linux kernel 6.12.42, IPv6 FIB multipath and concurrent access
handling was made stricter (READ_ONCE / WRITE_ONCE + RCU retry).
The RA “Automatic” mode relies on checking whether a local default route exists.
With the stricter FIB handling, this check can fail in multipath scenarios.
As a result, RA does not advertise a default route, and IPv6 clients
on LAN fail to receive the default gateway.
Steps to reproduce
Run OpenWrt with kernel 6.12.42 on a router with br-lan bridge.
Configure IPv6 RA in Automatic default router mode.
Observe that no default route is advertised to clients (though
prefixes may still be delivered).
Expected behavior
Router Advertisement should continue to advertise the default route as
in kernel 6.12.41 and earlier.
Client IPv6 connectivity should not break.
Actual behavior
RA fails to advertise a default route in Automatic mode.
Clients do not install a default IPv6 route → connectivity fails.
Temporary workaround
Change RA default router mode from Automatic → Always / Use available
prefixes in OpenWrt.
This bypasses the dependency on local default route check and restores
correct RA behavior.
Additional notes
This appears to be an unintended side effect of the stricter FIB
handling changes introduced in 6.12.42. Please advise if this has
already been reported or if I should prepare a minimal reproducer
outside OpenWrt.
Thanks,
[GitHub: mgz0227]
Since commits
7b9eb53e8591 ("media: cx18: Access v4l2_fh from file")
9ba9d11544f9 ("media: ivtv: Access v4l2_fh from file")
All the ioctl handlers access their private data structures
from file *
The ivtv and cx18 drivers call the ioctl handlers from their
DVB layer without a valid file *, causing invalid memory access.
The issue has been reported by smatch in
"[bug report] media: cx18: Access v4l2_fh from file"
Fix this by providing wrappers for the ioctl handlers to be
used by the DVB layer that do not require a valid file *.
Signed-off-by: Jacopo Mondi <jacopo.mondi(a)ideasonboard.com>
---
Changes in v2:
- Add Cc: stable(a)vger.kernel.org per-patch
---
Jacopo Mondi (2):
media: cx18: Fix invalid access to file *
media: ivtv: Fix invalid access to file *
drivers/media/pci/cx18/cx18-driver.c | 6 +++---
drivers/media/pci/cx18/cx18-ioctl.c | 26 ++++++++++++++++++++------
drivers/media/pci/cx18/cx18-ioctl.h | 8 +++++---
drivers/media/pci/ivtv/ivtv-driver.c | 4 ++--
drivers/media/pci/ivtv/ivtv-ioctl.c | 22 +++++++++++++++++-----
drivers/media/pci/ivtv/ivtv-ioctl.h | 6 ++++--
6 files changed, 51 insertions(+), 21 deletions(-)
---
base-commit: a75b8d198c55e9eb5feb6f6e155496305caba2dc
change-id: 20250818-cx18-v4l2-fh-7eaa6199fdde
Best regards,
--
Jacopo Mondi <jacopo.mondi(a)ideasonboard.com>
Since commits
7b9eb53e8591 ("media: cx18: Access v4l2_fh from file")
9ba9d11544f9 ("media: ivtv: Access v4l2_fh from file")
All the ioctl handlers access their private data structures
from file *
The ivtv and cx18 drivers call the ioctl handlers from their
DVB layer without a valid file *, causing invalid memory access.
The issue has been reported by smatch in
"[bug report] media: cx18: Access v4l2_fh from file"
Fix this by providing wrappers for the ioctl handlers to be
used by the DVB layer that do not require a valid file *.
Signed-off-by: Jacopo Mondi <jacopo.mondi(a)ideasonboard.com>
---
Jacopo Mondi (2):
media: cx18: Fix invalid access to file *
media: ivtv: Fix invalid access to file *
drivers/media/pci/cx18/cx18-driver.c | 6 +++---
drivers/media/pci/cx18/cx18-ioctl.c | 26 ++++++++++++++++++++------
drivers/media/pci/cx18/cx18-ioctl.h | 8 +++++---
drivers/media/pci/ivtv/ivtv-driver.c | 4 ++--
drivers/media/pci/ivtv/ivtv-ioctl.c | 22 +++++++++++++++++-----
drivers/media/pci/ivtv/ivtv-ioctl.h | 6 ++++--
6 files changed, 51 insertions(+), 21 deletions(-)
---
base-commit: a75b8d198c55e9eb5feb6f6e155496305caba2dc
change-id: 20250818-cx18-v4l2-fh-7eaa6199fdde
Best regards,
--
Jacopo Mondi <jacopo.mondi(a)ideasonboard.com>
[ Upstream commit a238487f7965d102794ed9f8aff0b667cd2ae886 ]
The 4xxx drivers hardcode the ring to service mapping. However, when
additional configurations where added to the driver, the mappings were
not updated. This implies that an incorrect mapping might be reported
through pfvf for certain configurations.
This is a backport of the upstream commit with modifications, as the
original patch does not apply cleanly to kernel v6.1.x. The logic has
been simplified to reflect the limited configurations of the QAT driver
in this version: crypto-only and compression.
Instead of dynamically computing the ring to service mappings, these are
now hardcoded to simplify the backport.
Fixes: 0cec19c761e5 ("crypto: qat - add support for compression for 4xxx")
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu(a)intel.com>
Reviewed-by: Damian Muszynski <damian.muszynski(a)intel.com>
Reviewed-by: Tero Kristo <tero.kristo(a)linux.intel.com>
Signed-off-by: Herbert Xu <herbert(a)gondor.apana.org.au>
(cherry-picked from commit a238487f7965d102794ed9f8aff0b667cd2ae886)
[Giovanni: backport to 6.1.y, conflict resolved simplifying the logic
in the function get_ring_to_svc_map() as the QAT driver in v6.1 supports
only limited configurations (crypto only and compression). Differs from
upstream as the ring to service mapping is hardcoded rather than being
dynamically computed.]
Reviewed-by: Ahsan Atta <ahsan.atta(a)intel.com>
Tested-by: Ahsan Atta <ahsan.atta(a)intel.com>
Signed-off-by: Giovanni Cabiddu <giovanni.cabiddu(a)intel.com>
---
V1 -> V2: changed signed-off-by area:
* added (cherry-picked from ...) after last tag from upstream commit
* added a note explaining how this backport differs from the original patch
* added a new Signed-off-by tag for the backport author.
drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c | 13 +++++++++++++
drivers/crypto/qat/qat_common/adf_accel_devices.h | 1 +
drivers/crypto/qat/qat_common/adf_gen4_hw_data.h | 6 ++++++
drivers/crypto/qat/qat_common/adf_init.c | 3 +++
4 files changed, 23 insertions(+)
diff --git a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
index fda5f699ff57..65b52c692add 100644
--- a/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
+++ b/drivers/crypto/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -297,6 +297,18 @@ static char *uof_get_name(struct adf_accel_dev *accel_dev, u32 obj_num)
return NULL;
}
+static u16 get_ring_to_svc_map(struct adf_accel_dev *accel_dev)
+{
+ switch (get_service_enabled(accel_dev)) {
+ case SVC_CY:
+ return ADF_GEN4_DEFAULT_RING_TO_SRV_MAP;
+ case SVC_DC:
+ return ADF_GEN4_DEFAULT_RING_TO_SRV_MAP_DC;
+ }
+
+ return 0;
+}
+
static u32 uof_get_ae_mask(struct adf_accel_dev *accel_dev, u32 obj_num)
{
switch (get_service_enabled(accel_dev)) {
@@ -353,6 +365,7 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data)
hw_data->uof_get_ae_mask = uof_get_ae_mask;
hw_data->set_msix_rttable = set_msix_default_rttable;
hw_data->set_ssm_wdtimer = adf_gen4_set_ssm_wdtimer;
+ hw_data->get_ring_to_svc_map = get_ring_to_svc_map;
hw_data->disable_iov = adf_disable_sriov;
hw_data->ring_pair_reset = adf_gen4_ring_pair_reset;
hw_data->enable_pm = adf_gen4_enable_pm;
diff --git a/drivers/crypto/qat/qat_common/adf_accel_devices.h b/drivers/crypto/qat/qat_common/adf_accel_devices.h
index ad01d99e6e2b..7993d0f82dea 100644
--- a/drivers/crypto/qat/qat_common/adf_accel_devices.h
+++ b/drivers/crypto/qat/qat_common/adf_accel_devices.h
@@ -176,6 +176,7 @@ struct adf_hw_device_data {
void (*get_arb_info)(struct arb_info *arb_csrs_info);
void (*get_admin_info)(struct admin_info *admin_csrs_info);
enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self);
+ u16 (*get_ring_to_svc_map)(struct adf_accel_dev *accel_dev);
int (*alloc_irq)(struct adf_accel_dev *accel_dev);
void (*free_irq)(struct adf_accel_dev *accel_dev);
void (*enable_error_correction)(struct adf_accel_dev *accel_dev);
diff --git a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
index 4fb4b3df5a18..5e653ec755e6 100644
--- a/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
+++ b/drivers/crypto/qat/qat_common/adf_gen4_hw_data.h
@@ -95,6 +95,12 @@ do { \
ADF_RING_BUNDLE_SIZE * (bank) + \
ADF_RING_CSR_RING_SRV_ARB_EN, (value))
+#define ADF_GEN4_DEFAULT_RING_TO_SRV_MAP_DC \
+ (COMP << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \
+ COMP << ADF_CFG_SERV_RING_PAIR_1_SHIFT | \
+ COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT | \
+ COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
+
/* Default ring mapping */
#define ADF_GEN4_DEFAULT_RING_TO_SRV_MAP \
(ASYM << ADF_CFG_SERV_RING_PAIR_0_SHIFT | \
diff --git a/drivers/crypto/qat/qat_common/adf_init.c b/drivers/crypto/qat/qat_common/adf_init.c
index 2e3481270c4b..49f07584f8c9 100644
--- a/drivers/crypto/qat/qat_common/adf_init.c
+++ b/drivers/crypto/qat/qat_common/adf_init.c
@@ -95,6 +95,9 @@ int adf_dev_init(struct adf_accel_dev *accel_dev)
return -EFAULT;
}
+ if (hw_data->get_ring_to_svc_map)
+ hw_data->ring_to_svc_map = hw_data->get_ring_to_svc_map(accel_dev);
+
if (adf_ae_init(accel_dev)) {
dev_err(&GET_DEV(accel_dev),
"Failed to initialise Acceleration Engine\n");
--
2.50.0