Import of kernel-6.12.0-211.39.1.el10_2

This commit is contained in:
almalinux-bot-kernel 2026-08-01 05:18:39 +00:00
parent 7c0a92f0e1
commit 4c4ddb2cb6
26 changed files with 271 additions and 149 deletions

View File

@ -12,7 +12,7 @@ RHEL_MINOR = 2
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 211.38.1
RHEL_RELEASE = 211.39.1
#
# RHEL_REBASE_NUM

View File

@ -373,7 +373,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
struct log_c *lc;
uint32_t region_size;
unsigned int region_count;
sector_t region_count;
size_t bitset_size, buf_size;
int r;
char dummy;
@ -401,6 +401,10 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
}
region_count = dm_sector_div_up(ti->len, region_size);
if (region_count > UINT_MAX) {
DMWARN("region count exceeds limit of %u", UINT_MAX);
return -EINVAL;
}
lc = kmalloc(sizeof(*lc), GFP_KERNEL);
if (!lc) {

View File

@ -172,13 +172,12 @@ static void vxcan_setup(struct net_device *dev)
/* forward declaration for rtnl_create_link() */
static struct rtnl_link_ops vxcan_link_ops;
static int vxcan_newlink(struct net *net, struct net_device *dev,
static int vxcan_newlink(struct net *peer_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
struct vxcan_priv *priv;
struct net_device *peer;
struct net *peer_net;
struct nlattr *peer_tb[IFLA_MAX + 1], **tbp = tb;
char ifname[IFNAMSIZ];
@ -188,14 +187,10 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
/* register peer device */
if (data && data[VXCAN_INFO_PEER]) {
struct nlattr *nla_peer;
struct nlattr *nla_peer = data[VXCAN_INFO_PEER];
nla_peer = data[VXCAN_INFO_PEER];
ifmp = nla_data(nla_peer);
err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
if (err < 0)
return err;
rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
tbp = peer_tb;
}
@ -207,23 +202,15 @@ static int vxcan_newlink(struct net *net, struct net_device *dev,
name_assign_type = NET_NAME_ENUM;
}
peer_net = rtnl_link_get_net(net, tbp);
if (IS_ERR(peer_net))
return PTR_ERR(peer_net);
peer = rtnl_create_link(peer_net, ifname, name_assign_type,
&vxcan_link_ops, tbp, extack);
if (IS_ERR(peer)) {
put_net(peer_net);
if (IS_ERR(peer))
return PTR_ERR(peer);
}
if (ifmp && dev->ifindex)
peer->ifindex = ifmp->ifi_index;
err = register_netdevice(peer);
put_net(peer_net);
peer_net = NULL;
if (err < 0) {
free_netdev(peer);
return err;
@ -302,6 +289,7 @@ static struct rtnl_link_ops vxcan_link_ops = {
.newlink = vxcan_newlink,
.dellink = vxcan_dellink,
.policy = vxcan_policy,
.peer_type = VXCAN_INFO_PEER,
.maxtype = VXCAN_INFO_MAX,
.get_link_net = vxcan_get_link_net,
};

View File

@ -71,8 +71,6 @@
#define GVE_DEFAULT_HEADER_BUFFER_SIZE 128
#define DQO_QPL_DEFAULT_TX_PAGES 512
/* Maximum TSO size supported on DQO */
#define GVE_DQO_TX_MAX 0x3FFFF
@ -646,6 +644,7 @@ struct gve_ptype_lut {
/* Parameters for allocating resources for tx queues */
struct gve_tx_alloc_rings_cfg {
struct gve_queue_config *qcfg;
u16 pages_per_qpl;
u16 ring_size;
u16 start_idx;
@ -661,6 +660,7 @@ struct gve_rx_alloc_rings_cfg {
/* tx config is also needed to determine QPL ids */
struct gve_queue_config *qcfg;
struct gve_queue_config *qcfg_tx;
u16 pages_per_qpl;
u16 ring_size;
u16 packet_buffer_size;
@ -738,7 +738,8 @@ struct gve_priv {
u16 min_rx_desc_cnt;
bool modify_ring_size_enabled;
bool default_min_ring_size;
u16 tx_pages_per_qpl; /* Suggested number of pages per qpl for TX queues by NIC */
u16 tx_pages_per_qpl;
u16 rx_pages_per_qpl;
u64 max_registered_pages;
u64 num_registered_pages; /* num pages registered with NIC */
struct bpf_prog *xdp_prog; /* XDP BPF program */
@ -1071,14 +1072,6 @@ static inline u32 gve_rx_start_qpl_id(const struct gve_queue_config *tx_cfg)
return gve_get_rx_qpl_id(tx_cfg, 0);
}
static inline u32 gve_get_rx_pages_per_qpl_dqo(u32 rx_desc_cnt)
{
/* For DQO, page count should be more than ring size for
* out-of-order completions. Set it to two times of ring size.
*/
return 2 * rx_desc_cnt;
}
/* Returns the correct dma direction for tx and rx qpls */
static inline enum dma_data_direction gve_qpl_dma_dir(struct gve_priv *priv,
int id)
@ -1178,6 +1171,9 @@ int gve_reset(struct gve_priv *priv, bool attempt_teardown);
void gve_get_curr_alloc_cfgs(struct gve_priv *priv,
struct gve_tx_alloc_rings_cfg *tx_alloc_cfg,
struct gve_rx_alloc_rings_cfg *rx_alloc_cfg);
void gve_update_num_qpl_pages(struct gve_priv *priv,
struct gve_rx_alloc_rings_cfg *rx_alloc_cfg,
struct gve_tx_alloc_rings_cfg *tx_alloc_cfg);
int gve_adjust_config(struct gve_priv *priv,
struct gve_tx_alloc_rings_cfg *tx_alloc_cfg,
struct gve_rx_alloc_rings_cfg *rx_alloc_cfg);

View File

@ -911,14 +911,6 @@ static void gve_enable_supported_features(struct gve_priv *priv,
priv->dev->max_mtu = be16_to_cpu(dev_op_jumbo_frames->max_mtu);
}
/* Override pages for qpl for DQO-QPL */
if (dev_op_dqo_qpl) {
priv->tx_pages_per_qpl =
be16_to_cpu(dev_op_dqo_qpl->tx_pages_per_qpl);
if (priv->tx_pages_per_qpl == 0)
priv->tx_pages_per_qpl = DQO_QPL_DEFAULT_TX_PAGES;
}
if (dev_op_buffer_sizes &&
(supported_features_mask & GVE_SUP_BUFFER_SIZES_MASK)) {
priv->max_rx_buffer_size =
@ -934,12 +926,10 @@ static void gve_enable_supported_features(struct gve_priv *priv,
if (dev_op_modify_ring &&
(supported_features_mask & GVE_SUP_MODIFY_RING_MASK)) {
priv->modify_ring_size_enabled = true;
/* max ring size for DQO QPL should not be overwritten because of device limit */
if (priv->queue_format != GVE_DQO_QPL_FORMAT) {
priv->max_rx_desc_cnt = be16_to_cpu(dev_op_modify_ring->max_rx_ring_size);
priv->max_tx_desc_cnt = be16_to_cpu(dev_op_modify_ring->max_tx_ring_size);
}
priv->max_rx_desc_cnt =
be16_to_cpu(dev_op_modify_ring->max_rx_ring_size);
priv->max_tx_desc_cnt =
be16_to_cpu(dev_op_modify_ring->max_tx_ring_size);
if (priv->default_min_ring_size) {
/* If device hasn't provided minimums, use default minimums */
priv->min_tx_desc_cnt = GVE_DEFAULT_MIN_TX_RING_SIZE;

View File

@ -10,6 +10,7 @@
#include <linux/filter.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/sched.h>
@ -926,6 +927,7 @@ static void gve_tx_get_curr_alloc_cfg(struct gve_priv *priv,
cfg->qcfg = &priv->tx_cfg;
cfg->raw_addressing = !gve_is_qpl(priv);
cfg->ring_size = priv->tx_desc_cnt;
cfg->pages_per_qpl = priv->tx_pages_per_qpl;
cfg->start_idx = 0;
cfg->num_rings = gve_num_tx_queues(priv);
cfg->tx = priv->tx;
@ -981,12 +983,48 @@ static int gve_alloc_xdp_rings(struct gve_priv *priv)
return 0;
}
void gve_update_num_qpl_pages(struct gve_priv *priv,
struct gve_rx_alloc_rings_cfg *rx_alloc_cfg,
struct gve_tx_alloc_rings_cfg *tx_alloc_cfg)
{
u64 ideal_tx_pages, ideal_rx_pages;
u16 tx_num_queues, rx_num_queues;
u64 max_pages, tx_pages;
if (priv->queue_format == GVE_GQI_QPL_FORMAT) {
rx_alloc_cfg->pages_per_qpl = rx_alloc_cfg->ring_size;
} else if (priv->queue_format == GVE_DQO_QPL_FORMAT) {
/*
* We want 2 pages per RX descriptor and half a page per TX
* descriptor, which means the fraction ideal_tx_pages /
* (ideal_tx_pages + ideal_rx_pages) of the pages we allocate
* should be for TX. Shrink proportionally as necessary to avoid
* allocating more than max_registered_pages total pages.
*/
tx_num_queues = tx_alloc_cfg->qcfg->num_queues;
rx_num_queues = rx_alloc_cfg->qcfg->num_queues;
ideal_tx_pages = tx_alloc_cfg->ring_size * tx_num_queues / 2;
ideal_rx_pages = rx_alloc_cfg->ring_size * rx_num_queues * 2;
max_pages = min(priv->max_registered_pages,
ideal_tx_pages + ideal_rx_pages);
tx_pages = div64_u64(max_pages * ideal_tx_pages,
ideal_tx_pages + ideal_rx_pages);
tx_alloc_cfg->pages_per_qpl = div_u64(tx_pages, tx_num_queues);
rx_alloc_cfg->pages_per_qpl = div_u64(max_pages - tx_pages,
rx_num_queues);
}
}
static int gve_queues_mem_alloc(struct gve_priv *priv,
struct gve_tx_alloc_rings_cfg *tx_alloc_cfg,
struct gve_rx_alloc_rings_cfg *rx_alloc_cfg)
{
int err;
gve_update_num_qpl_pages(priv, rx_alloc_cfg, tx_alloc_cfg);
if (gve_is_gqi(priv))
err = gve_tx_alloc_rings_gqi(priv, tx_alloc_cfg);
else
@ -1281,6 +1319,7 @@ static void gve_rx_get_curr_alloc_cfg(struct gve_priv *priv,
cfg->raw_addressing = !gve_is_qpl(priv);
cfg->enable_header_split = priv->header_split_enabled;
cfg->ring_size = priv->rx_desc_cnt;
cfg->pages_per_qpl = priv->rx_pages_per_qpl;
cfg->packet_buffer_size = gve_is_gqi(priv) ?
GVE_DEFAULT_RX_BUFFER_SIZE :
priv->data_buffer_size_dqo;
@ -1360,6 +1399,8 @@ static int gve_queues_start(struct gve_priv *priv,
priv->rx_cfg = *rx_alloc_cfg->qcfg;
priv->tx_desc_cnt = tx_alloc_cfg->ring_size;
priv->rx_desc_cnt = rx_alloc_cfg->ring_size;
priv->tx_pages_per_qpl = tx_alloc_cfg->pages_per_qpl;
priv->rx_pages_per_qpl = rx_alloc_cfg->pages_per_qpl;
if (priv->xdp_prog)
priv->num_xdp_queues = priv->rx_cfg.num_queues;

View File

@ -272,7 +272,6 @@ int gve_rx_alloc_ring_gqi(struct gve_priv *priv,
struct device *hdev = &priv->pdev->dev;
u32 slots = cfg->ring_size;
int filled_pages;
int qpl_page_cnt;
u32 qpl_id = 0;
size_t bytes;
int err;
@ -308,10 +307,8 @@ int gve_rx_alloc_ring_gqi(struct gve_priv *priv,
if (!rx->data.raw_addressing) {
qpl_id = gve_get_rx_qpl_id(cfg->qcfg_tx, rx->q_num);
qpl_page_cnt = cfg->ring_size;
rx->data.qpl = gve_alloc_queue_page_list(priv, qpl_id,
qpl_page_cnt);
cfg->pages_per_qpl);
if (!rx->data.qpl) {
err = -ENOMEM;
goto abort_with_copy_pool;

View File

@ -178,7 +178,7 @@ static int gve_alloc_page_dqo(struct gve_rx_ring *rx,
return err;
} else {
idx = rx->dqo.next_qpl_page_idx;
if (idx >= gve_get_rx_pages_per_qpl_dqo(priv->rx_desc_cnt)) {
if (idx >= priv->rx_pages_per_qpl) {
net_err_ratelimited("%s: Out of QPL pages\n",
priv->dev->name);
return -ENOMEM;
@ -382,7 +382,6 @@ int gve_rx_alloc_ring_dqo(struct gve_priv *priv,
int idx)
{
struct device *hdev = &priv->pdev->dev;
int qpl_page_cnt;
size_t size;
u32 qpl_id;
@ -397,7 +396,7 @@ int gve_rx_alloc_ring_dqo(struct gve_priv *priv,
rx->dqo.num_buf_states = cfg->raw_addressing ?
min_t(s16, S16_MAX, buffer_queue_slots * 4) :
gve_get_rx_pages_per_qpl_dqo(cfg->ring_size);
cfg->pages_per_qpl;
rx->dqo.buf_states = kvcalloc(rx->dqo.num_buf_states,
sizeof(rx->dqo.buf_states[0]),
GFP_KERNEL);
@ -426,10 +425,8 @@ int gve_rx_alloc_ring_dqo(struct gve_priv *priv,
if (!cfg->raw_addressing) {
qpl_id = gve_get_rx_qpl_id(cfg->qcfg_tx, rx->q_num);
qpl_page_cnt = gve_get_rx_pages_per_qpl_dqo(cfg->ring_size);
rx->dqo.qpl = gve_alloc_queue_page_list(priv, qpl_id,
qpl_page_cnt);
cfg->pages_per_qpl);
if (!rx->dqo.qpl)
goto err;
rx->dqo.next_qpl_page_idx = 0;

View File

@ -261,7 +261,6 @@ static int gve_tx_alloc_ring_gqi(struct gve_priv *priv,
int idx)
{
struct device *hdev = &priv->pdev->dev;
int qpl_page_cnt;
u32 qpl_id = 0;
size_t bytes;
@ -288,10 +287,8 @@ static int gve_tx_alloc_ring_gqi(struct gve_priv *priv,
tx->dev = hdev;
if (!tx->raw_addressing) {
qpl_id = gve_tx_qpl_id(priv, tx->q_num);
qpl_page_cnt = priv->tx_pages_per_qpl;
tx->tx_fifo.qpl = gve_alloc_queue_page_list(priv, qpl_id,
qpl_page_cnt);
cfg->pages_per_qpl);
if (!tx->tx_fifo.qpl)
goto abort_with_desc;

View File

@ -287,7 +287,6 @@ static int gve_tx_alloc_ring_dqo(struct gve_priv *priv,
{
struct device *hdev = &priv->pdev->dev;
int num_pending_packets;
int qpl_page_cnt;
size_t bytes;
u32 qpl_id;
int i;
@ -357,10 +356,8 @@ static int gve_tx_alloc_ring_dqo(struct gve_priv *priv,
if (!cfg->raw_addressing) {
qpl_id = gve_tx_qpl_id(priv, tx->q_num);
qpl_page_cnt = priv->tx_pages_per_qpl;
tx->dqo.qpl = gve_alloc_queue_page_list(priv, qpl_id,
qpl_page_cnt);
cfg->pages_per_qpl);
if (!tx->dqo.qpl)
goto err;

View File

@ -326,7 +326,7 @@ static int netkit_validate(struct nlattr *tb[], struct nlattr *data[],
static struct rtnl_link_ops netkit_link_ops;
static int netkit_new_link(struct net *src_net, struct net_device *dev,
static int netkit_new_link(struct net *peer_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
@ -339,7 +339,6 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,
struct net_device *peer;
char ifname[IFNAMSIZ];
struct netkit *nk;
struct net *net;
int err;
if (data) {
@ -353,12 +352,7 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,
if (data[IFLA_NETKIT_PEER_INFO]) {
attr = data[IFLA_NETKIT_PEER_INFO];
ifmp = nla_data(attr);
err = rtnl_nla_parse_ifinfomsg(peer_tb, attr, extack);
if (err < 0)
return err;
err = netkit_validate(peer_tb, NULL, extack);
if (err < 0)
return err;
rtnl_nla_parse_ifinfomsg(peer_tb, attr, extack);
tbp = peer_tb;
}
if (data[IFLA_NETKIT_POLICY]) {
@ -388,16 +382,10 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,
(tb[IFLA_ADDRESS] || tbp[IFLA_ADDRESS]))
return -EOPNOTSUPP;
net = rtnl_link_get_net(src_net, tbp);
if (IS_ERR(net))
return PTR_ERR(net);
peer = rtnl_create_link(net, ifname, ifname_assign_type,
peer = rtnl_create_link(peer_net, ifname, ifname_assign_type,
&netkit_link_ops, tbp, extack);
if (IS_ERR(peer)) {
put_net(net);
if (IS_ERR(peer))
return PTR_ERR(peer);
}
netif_inherit_tso_max(peer, dev);
@ -413,7 +401,6 @@ static int netkit_new_link(struct net *src_net, struct net_device *dev,
bpf_mprog_bundle_init(&nk->bundle);
err = register_netdevice(peer);
put_net(net);
if (err < 0)
goto err_register_peer;
netif_carrier_off(peer);
@ -953,6 +940,7 @@ static struct rtnl_link_ops netkit_link_ops = {
.fill_info = netkit_fill_info,
.policy = netkit_policy,
.validate = netkit_validate,
.peer_type = IFLA_NETKIT_PEER_INFO,
.maxtype = IFLA_NETKIT_MAX,
};

View File

@ -1766,7 +1766,7 @@ static int veth_init_queues(struct net_device *dev, struct nlattr *tb[])
return 0;
}
static int veth_newlink(struct net *src_net, struct net_device *dev,
static int veth_newlink(struct net *peer_net, struct net_device *dev,
struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
@ -1777,24 +1777,15 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
struct nlattr *peer_tb[IFLA_MAX + 1], **tbp;
unsigned char name_assign_type;
struct ifinfomsg *ifmp;
struct net *net;
/*
* create and register peer first
*/
if (data != NULL && data[VETH_INFO_PEER] != NULL) {
struct nlattr *nla_peer;
if (data && data[VETH_INFO_PEER]) {
struct nlattr *nla_peer = data[VETH_INFO_PEER];
nla_peer = data[VETH_INFO_PEER];
ifmp = nla_data(nla_peer);
err = rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
if (err < 0)
return err;
err = veth_validate(peer_tb, NULL, extack);
if (err < 0)
return err;
rtnl_nla_parse_ifinfomsg(peer_tb, nla_peer, extack);
tbp = peer_tb;
} else {
ifmp = NULL;
@ -1809,16 +1800,10 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
name_assign_type = NET_NAME_ENUM;
}
net = rtnl_link_get_net(src_net, tbp);
if (IS_ERR(net))
return PTR_ERR(net);
peer = rtnl_create_link(net, ifname, name_assign_type,
peer = rtnl_create_link(peer_net, ifname, name_assign_type,
&veth_link_ops, tbp, extack);
if (IS_ERR(peer)) {
put_net(net);
if (IS_ERR(peer))
return PTR_ERR(peer);
}
if (!ifmp || !tbp[IFLA_ADDRESS])
eth_hw_addr_random(peer);
@ -1829,8 +1814,6 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,
netif_inherit_tso_max(peer, dev);
err = register_netdevice(peer);
put_net(net);
net = NULL;
if (err < 0)
goto err_register_peer;
@ -1953,6 +1936,7 @@ static struct rtnl_link_ops veth_link_ops = {
.newlink = veth_newlink,
.dellink = veth_dellink,
.policy = veth_policy,
.peer_type = VETH_INFO_PEER,
.maxtype = VETH_INFO_MAX,
.get_link_net = veth_get_link_net,
.get_num_tx_queues = veth_get_num_queues,

View File

@ -282,11 +282,20 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head)
{
struct scsi_cmnd *scmd = container_of(head, typeof(*scmd), rcu);
struct Scsi_Host *shost = scmd->device->host;
unsigned int busy = scsi_host_busy(shost);
unsigned int busy;
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_failed++;
spin_unlock_irqrestore(shost->host_lock, flags);
/*
* The counting of busy requests needs to occur after adding to
* host_failed or after the lock acquire for adding to host_failed
* to prevent a race with host unbusy and missing an eh wakeup.
*/
busy = scsi_host_busy(shost);
spin_lock_irqsave(shost->host_lock, flags);
scsi_eh_wakeup(shost, busy);
spin_unlock_irqrestore(shost->host_lock, flags);
}

View File

@ -376,6 +376,14 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd)
rcu_read_lock();
__clear_bit(SCMD_STATE_INFLIGHT, &cmd->state);
if (unlikely(scsi_host_in_recovery(shost))) {
/*
* Ensure the clear of SCMD_STATE_INFLIGHT is visible to
* other CPUs before counting busy requests. Otherwise,
* reordering can cause CPUs to race and miss an eh wakeup
* when no CPU sees all busy requests as done or timed out.
*/
smp_mb();
unsigned int busy = scsi_host_busy(shost);
spin_lock_irqsave(shost->host_lock, flags);

View File

@ -17,6 +17,7 @@
#include "fanotify/fanotify.h"
#include "fdinfo.h"
#include "fsnotify.h"
#include "../internal.h"
#if defined(CONFIG_PROC_FS)
@ -46,11 +47,14 @@ static void show_mark_fhandle(struct seq_file *m, struct inode *inode)
size = f->handle_bytes >> 2;
ret = exportfs_encode_fid(inode, (struct fid *)f->f_handle, &size);
if ((ret == FILEID_INVALID) || (ret < 0)) {
WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret);
if (!super_trylock_shared(inode->i_sb))
return;
ret = exportfs_encode_fid(inode, (struct fid *)f->f_handle, &size);
up_read(&inode->i_sb->s_umount);
if ((ret == FILEID_INVALID) || (ret < 0))
return;
}
f->handle_type = ret;
f->handle_bytes = size * sizeof(u32);

View File

@ -444,9 +444,8 @@ struct ovl_fh *ovl_encode_real_fh(struct ovl_fs *ofs, struct inode *realinode,
buflen = (dwords << 2);
err = -EIO;
if (WARN_ON(fh_type < 0) ||
WARN_ON(buflen > MAX_HANDLE_SZ) ||
WARN_ON(fh_type == FILEID_INVALID))
if (fh_type < 0 || fh_type == FILEID_INVALID ||
WARN_ON(buflen > MAX_HANDLE_SZ))
goto out_err;
fh->fb.version = OVL_FH_VERSION;

View File

@ -2,6 +2,7 @@
#ifndef __NET_RTNETLINK_H
#define __NET_RTNETLINK_H
#include <linux/rh_kabi.h>
#include <linux/rtnetlink.h>
#include <net/netlink.h>
@ -67,6 +68,7 @@ static inline int rtnl_msg_family(const struct nlmsghdr *nlh)
* @list: Used internally
* @kind: Identifier
* @netns_refund: Physical device, move to init_net on netns exit
* @peer_type: Peer device specific netlink attribute number (e.g. VETH_INFO_PEER)
* @maxtype: Highest device specific netlink attribute number
* @policy: Netlink policy for device specific attribute validation
* @validate: Optional validation function for netlink/changelink parameters
@ -107,6 +109,7 @@ struct rtnl_link_ops {
void (*setup)(struct net_device *dev);
bool netns_refund;
RH_KABI_FILL_HOLE(const u16 peer_type)
unsigned int maxtype;
const struct nla_policy *policy;
int (*validate)(struct nlattr *tb[],

View File

@ -1,2 +1,2 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
kernel.almalinux,1,AlmaLinux,kernel-core,6.12.0-211.38.1.el10.x86_64,mailto:security@almalinux.org
kernel.almalinux,1,AlmaLinux,kernel-core,6.12.0-211.39.1.el10.x86_64,mailto:security@almalinux.org

View File

@ -2107,9 +2107,11 @@ static void rv_task_fork(struct task_struct *p)
static bool need_futex_hash_allocate_default(u64 clone_flags)
{
if ((clone_flags & (CLONE_THREAD | CLONE_VM)) != (CLONE_THREAD | CLONE_VM))
return false;
return true;
/*
* Allocate a default futex hash for any sibling that will
* share the parent's mm, except vfork.
*/
return (clone_flags & (CLONE_VM | CLONE_VFORK)) == CLONE_VM;
}
/*
@ -2492,10 +2494,6 @@ __latent_entropy struct task_struct *copy_process(
if (retval)
goto bad_fork_cancel_cgroup;
/*
* Allocate a default futex hash for the user process once the first
* thread spawns.
*/
if (need_futex_hash_allocate_default(clone_flags)) {
retval = futex_hash_allocate_default();
if (retval)

View File

@ -2355,9 +2355,10 @@ int rtnl_nla_parse_ifinfomsg(struct nlattr **tb, const struct nlattr *nla_peer,
}
EXPORT_SYMBOL(rtnl_nla_parse_ifinfomsg);
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
static struct net *rtnl_link_get_net_ifla(struct nlattr *tb[])
{
struct net *net;
struct net *net = NULL;
/* Examine the link attributes and figure out which
* network namespace we are talking about.
*/
@ -2365,8 +2366,17 @@ struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
else if (tb[IFLA_NET_NS_FD])
net = get_net_ns_by_fd(nla_get_u32(tb[IFLA_NET_NS_FD]));
else
return net;
}
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
{
struct net *net = rtnl_link_get_net_ifla(tb);
if (!net)
net = get_net(src_net);
return net;
}
EXPORT_SYMBOL(rtnl_link_get_net);
@ -3514,6 +3524,7 @@ static int rtnl_group_changelink(const struct sk_buff *skb,
static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
const struct rtnl_link_ops *ops,
struct net *peer_net,
const struct nlmsghdr *nlh,
struct nlattr **tb, struct nlattr **data,
struct netlink_ext_ack *extack)
@ -3565,8 +3576,13 @@ static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm,
dev->ifindex = ifm->ifi_index;
if (link_net)
net = link_net;
if (peer_net)
net = peer_net;
if (ops->newlink)
err = ops->newlink(link_net ? : net, dev, tb, data, extack);
err = ops->newlink(net, dev, tb, data, extack);
else
err = register_netdevice(dev);
if (err < 0) {
@ -3615,6 +3631,44 @@ struct rtnl_newlink_tbs {
struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1];
};
static struct net *rtnl_get_peer_net(struct sk_buff *skb,
const struct rtnl_link_ops *ops,
struct nlattr *tbp[],
struct nlattr *data[],
struct netlink_ext_ack *extack)
{
struct nlattr *tb[IFLA_MAX + 1], **attrs;
struct net *net;
int err;
if (!data || !data[ops->peer_type]) {
attrs = tbp;
} else {
err = rtnl_nla_parse_ifinfomsg(tb, data[ops->peer_type], extack);
if (err < 0)
return ERR_PTR(err);
if (ops->validate) {
err = ops->validate(tb, NULL, extack);
if (err < 0)
return ERR_PTR(err);
}
attrs = tb;
}
net = rtnl_link_get_net_ifla(attrs);
if (IS_ERR_OR_NULL(net))
return net;
if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
put_net(net);
return ERR_PTR(-EPERM);
}
return net;
}
static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
struct rtnl_newlink_tbs *tbs,
struct netlink_ext_ack *extack)
@ -3625,6 +3679,7 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
struct net_device *master_dev;
struct net *net = sock_net(skb->sk);
const struct rtnl_link_ops *ops;
struct net *peer_net = NULL;
struct nlattr **slave_data;
char kind[MODULE_NAME_LEN];
struct net_device *dev;
@ -3703,12 +3758,20 @@ replay:
if (err < 0)
return err;
}
if (ops->peer_type) {
peer_net = rtnl_get_peer_net(skb, ops, tb, data, extack);
if (IS_ERR(peer_net))
return PTR_ERR(peer_net);
}
}
slave_data = NULL;
if (m_ops) {
if (m_ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE)
return -EINVAL;
if (m_ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE) {
err = -EINVAL;
goto put_net;
}
if (m_ops->slave_maxtype &&
linkinfo[IFLA_INFO_SLAVE_DATA]) {
@ -3718,7 +3781,7 @@ replay:
m_ops->slave_policy,
extack);
if (err < 0)
return err;
goto put_net;
slave_data = tbs->slave_attr;
}
}
@ -3726,51 +3789,67 @@ replay:
if (dev) {
int status = 0;
if (nlh->nlmsg_flags & NLM_F_EXCL)
return -EEXIST;
if (nlh->nlmsg_flags & NLM_F_REPLACE)
return -EOPNOTSUPP;
if (nlh->nlmsg_flags & NLM_F_EXCL) {
err = -EEXIST;
goto put_net;
}
if (nlh->nlmsg_flags & NLM_F_REPLACE) {
err = -EOPNOTSUPP;
goto put_net;
}
if (linkinfo[IFLA_INFO_DATA]) {
if (!ops || ops != dev->rtnl_link_ops ||
!ops->changelink)
return -EOPNOTSUPP;
!ops->changelink) {
err = -EOPNOTSUPP;
goto put_net;
}
err = ops->changelink(dev, tb, data, extack);
if (err < 0)
return err;
goto put_net;
status |= DO_SETLINK_NOTIFY;
}
if (linkinfo[IFLA_INFO_SLAVE_DATA]) {
if (!m_ops || !m_ops->slave_changelink)
return -EOPNOTSUPP;
if (!m_ops || !m_ops->slave_changelink) {
err = -EOPNOTSUPP;
goto put_net;
}
err = m_ops->slave_changelink(master_dev, dev, tb,
slave_data, extack);
if (err < 0)
return err;
goto put_net;
status |= DO_SETLINK_NOTIFY;
}
return do_setlink(skb, dev, ifm, extack, tb, status);
err = do_setlink(skb, dev, ifm, extack, tb, status);
goto put_net;
}
if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
/* No dev found and NLM_F_CREATE not set. Requested dev does not exist,
* or it's for a group
*/
if (link_specified)
return -ENODEV;
if (tb[IFLA_GROUP])
return rtnl_group_changelink(skb, net,
nla_get_u32(tb[IFLA_GROUP]),
ifm, extack, tb);
return -ENODEV;
if (link_specified) {
err = -ENODEV;
goto put_net;
}
if (tb[IFLA_GROUP]) {
err = rtnl_group_changelink(skb, net,
nla_get_u32(tb[IFLA_GROUP]),
ifm, extack, tb);
goto put_net;
}
err = -ENODEV;
goto put_net;
}
if (tb[IFLA_MAP] || tb[IFLA_PROTINFO])
return -EOPNOTSUPP;
if (tb[IFLA_MAP] || tb[IFLA_PROTINFO]) {
err = -EOPNOTSUPP;
goto put_net;
}
if (!ops) {
#ifdef CONFIG_MODULES
@ -3784,10 +3863,18 @@ replay:
}
#endif
NL_SET_ERR_MSG(extack, "Unknown device type");
return -EOPNOTSUPP;
err = -EOPNOTSUPP;
goto put_net;
}
return rtnl_newlink_create(skb, ifm, ops, nlh, tb, data, extack);
err = rtnl_newlink_create(skb, ifm, ops, peer_net, nlh, tb, data,
extack);
put_net:
if (peer_net)
put_net(peer_net);
return err;
}
static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,

View File

@ -279,7 +279,17 @@ static int rpl_input(struct sk_buff *skb)
if (!dst) {
ip6_route_input(skb);
/* ip6_route_input() sets a NOREF dst; force a refcount on it
* before caching or further use.
*/
skb_dst_force(skb);
dst = skb_dst(skb);
if (unlikely(!dst)) {
err = -ENETUNREACH;
goto drop;
}
if (!dst->error) {
local_bh_disable();
dst_cache_set_ip6(&rlwt->cache, dst,

View File

@ -499,7 +499,16 @@ static int seg6_input_core(struct net *net, struct sock *sk,
if (!dst) {
ip6_route_input(skb);
/* ip6_route_input() sets a NOREF dst; force a refcount on it
* before caching or further use.
*/
skb_dst_force(skb);
dst = skb_dst(skb);
if (unlikely(!dst)) {
err = -ENETUNREACH;
goto drop;
}
/* cache only if we don't create a dst reference loop */
if (!dst->error && lwtst != dst->lwtstate) {

View File

@ -1,3 +1,19 @@
* Thu Jul 23 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.39.1.el10_2]
- futex: Drop CLONE_THREAD requirement for private default hash alloc (Audra Mitchell) [RHEL-193518] {CVE-2026-52973}
- net: ipv6: fix NOREF dst use in seg6 and rpl lwtunnels (Antoine Tenart) [RHEL-179299] {CVE-2026-46099}
- scsi: core: Wake up the error handler when final completions race against each other (CKI Backport Bot) [RHEL-189651] {CVE-2026-23110}
- dm log: fix out-of-bounds write due to region_count overflow (CKI Backport Bot) [RHEL-188547] {CVE-2026-53059}
- rtnetlink: add missing netlink_ns_capable() check for peer netns (Guillaume Nault) [RHEL-172537] {CVE-2026-31692}
- rtnetlink: Try the outer netns attribute in rtnl_get_peer_net(). (Guillaume Nault) [RHEL-172537] {CVE-2026-31692}
- rtnetlink: fix double call of rtnl_link_get_net_ifla() (Guillaume Nault) [RHEL-172537] {CVE-2026-31692}
- netkit: Set IFLA_NETKIT_PEER_INFO to netkit_link_ops.peer_type. (Guillaume Nault) [RHEL-172537] {CVE-2026-31692}
- vxcan: Set VXCAN_INFO_PEER to vxcan_link_ops.peer_type. (Guillaume Nault) [RHEL-172537] {CVE-2026-31692}
- veth: Set VETH_INFO_PEER to veth_link_ops.peer_type. (Guillaume Nault) [RHEL-172537] {CVE-2026-31692}
- rtnetlink: Add peer_type in struct rtnl_link_ops. (Guillaume Nault) [RHEL-172537] {CVE-2026-31692}
- fs/notify: call exportfs_encode_fid with s_umount (Jay Shin) [RHEL-169188] {CVE-2025-40237}
- fs: relax assertions on failure to encode file handles (Jay Shin) [RHEL-169188]
Resolves: RHEL-169188, RHEL-172537, RHEL-179299, RHEL-188547, RHEL-189651, RHEL-193518
* Wed Jul 22 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.38.1.el10_2]
- net: gro: don't merge zcopy skbs (CKI Backport Bot) [RHEL-177856] {CVE-2026-46323}
Resolves: RHEL-177856

View File

@ -1,2 +1,2 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
kernel-uki-virt-addons.almalinux,1,AlmaLinux,kernel-uki-virt-addons,6.12.0-211.38.1.el10.x86_64,mailto:security@almalinux.org
kernel-uki-virt-addons.almalinux,1,AlmaLinux,kernel-uki-virt-addons,6.12.0-211.39.1.el10.x86_64,mailto:security@almalinux.org

View File

@ -1,2 +1,2 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
kernel-uki-virt.almalinux,1,AlmaLinux,kernel-uki-virt,6.12.0-211.38.1.el10.x86_64,mailto:security@almalinux.org
kernel-uki-virt.almalinux,1,AlmaLinux,kernel-uki-virt,6.12.0-211.39.1.el10.x86_64,mailto:security@almalinux.org