Import of kernel-5.14.0-687.17.1.el9_8

This commit is contained in:
almalinux-bot-kernel 2026-06-24 05:25:55 +00:00
parent 9bb58011ba
commit 36c7b56810
43 changed files with 601 additions and 280 deletions

View File

@ -65,35 +65,43 @@ request, where user provides attributes that result in single pin match.
Pin selection
=============
In general, selected pin (the one which signal is driving the dpll
device) can be obtained from ``DPLL_A_PIN_STATE`` attribute, and only
one pin shall be in ``DPLL_PIN_STATE_CONNECTED`` state for any dpll
device.
Pin state (``DPLL_A_PIN_STATE``) reflects the administrative intent set
by the user. Pin operational state (``DPLL_A_PIN_OPERSTATE``) reflects
what the hardware is actually doing with the pin.
Pin selection can be done either manually or automatically, depending
on hardware capabilities and active dpll device work mode
(``DPLL_A_MODE`` attribute). The consequence is that there are
differences for each mode in terms of available pin states, as well as
for the states the user can request for a dpll device.
differences for each mode in terms of available pin states the user can
request for a dpll device.
In manual mode (``DPLL_MODE_MANUAL``) the user can request or receive
one of following pin states:
In manual mode (``DPLL_MODE_MANUAL``) the user can request one of
following pin states:
- ``DPLL_PIN_STATE_CONNECTED`` - the pin is used to drive dpll device
- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not used to drive dpll
- ``DPLL_PIN_STATE_CONNECTED`` - the pin is selected to drive dpll
device
- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not selected to drive
dpll device
In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request or
receive one of following pin states:
In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request one of
following pin states:
- ``DPLL_PIN_STATE_SELECTABLE`` - the pin shall be considered as valid
input for automatic selection algorithm
- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin shall be not considered as
a valid input for automatic selection algorithm
In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can only receive
pin state ``DPLL_PIN_STATE_CONNECTED`` once automatic selection
algorithm locks a dpll device with one of the inputs.
The actual hardware status of a pin is reported via the operational
state (``DPLL_A_PIN_OPERSTATE``) attribute nested under the parent
device:
- ``DPLL_PIN_OPERSTATE_ACTIVE`` - pin is qualified and actively used
by the DPLL
- ``DPLL_PIN_OPERSTATE_STANDBY`` - pin is qualified but not actively
used by the DPLL
- ``DPLL_PIN_OPERSTATE_NO_SIGNAL`` - pin does not have a valid signal
- ``DPLL_PIN_OPERSTATE_QUAL_FAILED`` - pin signal failed qualification
checks
Shared pins
===========
@ -250,6 +258,26 @@ in the ``DPLL_A_PIN_PHASE_OFFSET`` attribute.
``DPLL_A_PHASE_OFFSET_MONITOR`` attr state of a feature
=============================== ========================
Fractional frequency offset
===========================
The fractional frequency offset (FFO) is reported through two attributes
that carry the same measurement at different precisions:
- ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET`` in PPM (parts per million)
- ``DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT`` in PPT (parts per trillion)
Both attributes appear at the top level of a pin and inside each
``pin-parent-device`` nest. Two FFO types are defined:
- ``DPLL_FFO_PORT_RXTX_RATE`` - RX vs TX symbol rate offset (top-level)
- ``DPLL_FFO_PIN_DEVICE`` - pin vs parent DPLL offset (per-parent)
The driver declares which types it supports via the ``supported_ffo``
bitmask in ``struct dpll_pin_ops``. The core only calls the ``ffo_get``
callback for types the driver has opted into. The requested type is
passed to the driver in the ``struct dpll_ffo_param``.
Frequency monitor
=================

View File

@ -212,6 +212,27 @@ definitions:
name: selectable
doc: pin enabled for automatic input selection
render-max: true
-
type: enum
name: pin-operstate
doc: |
defines possible operational states of a pin with respect to its
parent DPLL device, valid values for DPLL_A_PIN_OPERSTATE attribute
entries:
-
name: active
doc: pin is qualified and actively used by the DPLL
value: 1
-
name: standby
doc: pin is qualified but not actively used by the DPLL
-
name: no-signal
doc: pin does not have a valid signal
-
name: qual-failed
doc: pin signal failed qualification (e.g. frequency or phase monitor)
render-max: true
-
type: flags
name: pin-capabilities
@ -427,12 +448,14 @@ attribute-sets:
name: fractional-frequency-offset
type: sint
doc: |
The FFO (Fractional Frequency Offset) between the RX and TX
symbol rate on the media associated with the pin:
(rx_frequency-tx_frequency)/rx_frequency
The FFO (Fractional Frequency Offset) of the pin.
At top level this represents the RX vs TX symbol rate
offset on the media associated with the pin. Inside
the pin-parent-device nest it represents the frequency
offset between the pin and its parent DPLL device.
Value is in PPM (parts per million).
This may be implemented for example for pin of type
PIN_TYPE_SYNCE_ETH_PORT.
This is a lower-precision version of
fractional-frequency-offset-ppt.
-
name: esync-frequency
type: u64
@ -471,12 +494,14 @@ attribute-sets:
name: fractional-frequency-offset-ppt
type: sint
doc: |
The FFO (Fractional Frequency Offset) of the pin with respect to
the nominal frequency.
Value = (frequency_measured - frequency_nominal) / frequency_nominal
The FFO (Fractional Frequency Offset) of the pin.
At top level this represents the RX vs TX symbol rate
offset on the media associated with the pin. Inside
the pin-parent-device nest it represents the frequency
offset between the pin and its parent DPLL device.
Value is in PPT (parts per trillion, 10^-12).
Note: This attribute provides higher resolution than the standard
fractional-frequency-offset (which is in PPM).
This is a higher-precision version of
fractional-frequency-offset.
-
name: measured-frequency
type: u64
@ -488,6 +513,14 @@ attribute-sets:
Value of (DPLL_A_PIN_MEASURED_FREQUENCY %
DPLL_PIN_MEASURED_FREQUENCY_DIVIDER) is a fractional part
of a measured frequency value.
-
name: operstate
type: u32
enum: pin-operstate
doc: |
Operational state of the pin with respect to its parent DPLL
device. Unlike state (which reflects the administrative intent),
operstate reflects the actual hardware status.
-
name: pin-parent-device
@ -501,8 +534,14 @@ attribute-sets:
name: prio
-
name: state
-
name: operstate
-
name: phase-offset
-
name: fractional-frequency-offset
-
name: fractional-frequency-offset-ppt
-
name: pin-parent-pin
subset-of: pin

View File

@ -547,10 +547,18 @@ void do_secure_storage_access(struct pt_regs *regs)
page = phys_to_page(addr);
if (unlikely(!try_get_page(page)))
break;
rc = arch_make_page_accessible(page);
rc = uv_convert_from_secure(addr);
if (!rc)
clear_bit(PG_arch_1, &page->flags);
put_page(page);
/*
* There are some valid fixup types for kernel
* accesses to donated secure memory. zeropad is one
* of them.
*/
if (rc)
BUG();
return handle_fault_error_nolock(regs, 0);
break;
default:
unreachable();

View File

@ -4547,24 +4547,12 @@ out:
return ret;
}
static void cancel_tasks_sync(struct rbd_device *rbd_dev)
{
dout("%s rbd_dev %p\n", __func__, rbd_dev);
cancel_work_sync(&rbd_dev->acquired_lock_work);
cancel_work_sync(&rbd_dev->released_lock_work);
cancel_delayed_work_sync(&rbd_dev->lock_dwork);
cancel_work_sync(&rbd_dev->unlock_work);
}
/*
* header_rwsem must not be held to avoid a deadlock with
* rbd_dev_refresh() when flushing notifies.
*/
static void rbd_unregister_watch(struct rbd_device *rbd_dev)
{
cancel_tasks_sync(rbd_dev);
mutex_lock(&rbd_dev->watch_mutex);
if (rbd_dev->watch_state == RBD_WATCH_STATE_REGISTERED)
__rbd_unregister_watch(rbd_dev);
@ -6541,10 +6529,18 @@ out_err:
static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
{
dout("%s rbd_dev %p\n", __func__, rbd_dev);
disable_delayed_work_sync(&rbd_dev->lock_dwork);
disable_work_sync(&rbd_dev->unlock_work);
down_write(&rbd_dev->lock_rwsem);
if (__rbd_is_lock_owner(rbd_dev))
__rbd_release_lock(rbd_dev);
up_write(&rbd_dev->lock_rwsem);
flush_work(&rbd_dev->acquired_lock_work);
flush_work(&rbd_dev->released_lock_work);
}
/*

View File

@ -883,7 +883,8 @@ dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
WARN_ON(!ops->direction_get) ||
WARN_ON(ops->measured_freq_get &&
(!dpll_device_ops(dpll)->freq_monitor_get ||
!dpll_device_ops(dpll)->freq_monitor_set)))
!dpll_device_ops(dpll)->freq_monitor_set)) ||
WARN_ON(ops->supported_ffo && !ops->ffo_get))
return -EINVAL;
mutex_lock(&dpll_lock);

View File

@ -324,6 +324,30 @@ dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, struct dpll_pin *pin,
return 0;
}
static int
dpll_msg_add_pin_operstate(struct sk_buff *msg, struct dpll_pin *pin,
struct dpll_pin_ref *ref,
struct netlink_ext_ack *extack)
{
const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
struct dpll_device *dpll = ref->dpll;
enum dpll_pin_operstate operstate;
int ret;
if (!ops->operstate_on_dpll_get)
return 0;
ret = ops->operstate_on_dpll_get(pin,
dpll_pin_on_dpll_priv(dpll, pin),
dpll, dpll_priv(dpll),
&operstate, extack);
if (ret)
return ret;
if (nla_put_u32(msg, DPLL_A_PIN_OPERSTATE, operstate))
return -EMSGSIZE;
return 0;
}
static int
dpll_msg_add_pin_direction(struct sk_buff *msg, struct dpll_pin *pin,
struct dpll_pin_ref *ref,
@ -393,31 +417,34 @@ dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
struct dpll_pin_ref *ref,
enum dpll_ffo_type type,
struct netlink_ext_ack *extack)
{
const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
struct dpll_device *dpll = ref->dpll;
s64 ffo;
struct dpll_ffo_param ffo = { .type = type };
int ret;
if (!ops->ffo_get)
return 0;
ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
dpll, dpll_priv(dpll), &ffo, extack);
/* RHEL: To maintain backward compatibility with older binary modules,
* we must accept a value of zero for .supported_ffo when the type is
* DPLL_FFO_PORT_RXTX_RATE.
*/
if (!ops->ffo_get ||
!((ops->supported_ffo & BIT(type)) ||
(!ops->supported_ffo && type == DPLL_FFO_PORT_RXTX_RATE)))
return 0;
ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(ref->dpll, pin),
ref->dpll, dpll_priv(ref->dpll), &ffo, extack);
if (ret) {
if (ret == -ENODATA)
return 0;
return ret;
}
/* Put the FFO value in PPM to preserve compatibility with older
* programs.
*/
ret = nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
div_s64(ffo, 1000000));
if (ret)
if (nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET,
div_s64(ffo.ffo, 1000000)))
return -EMSGSIZE;
return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
ffo);
return nla_put_sint(msg,
DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
ffo.ffo);
}
static int dpll_msg_add_measured_freq(struct sk_buff *msg, struct dpll_pin *pin,
@ -650,6 +677,9 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
if (ret)
goto nest_cancel;
ret = dpll_msg_add_pin_on_dpll_state(msg, pin, ref, extack);
if (ret)
goto nest_cancel;
ret = dpll_msg_add_pin_operstate(msg, pin, ref, extack);
if (ret)
goto nest_cancel;
ret = dpll_msg_add_pin_prio(msg, pin, ref, extack);
@ -659,6 +689,10 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
if (ret)
goto nest_cancel;
ret = dpll_msg_add_phase_offset(msg, pin, ref, extack);
if (ret)
goto nest_cancel;
ret = dpll_msg_add_ffo(msg, pin, ref,
DPLL_FFO_PIN_DEVICE, extack);
if (ret)
goto nest_cancel;
nla_nest_end(msg, attr);
@ -721,7 +755,8 @@ dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
if (ret)
return ret;
ret = dpll_msg_add_ffo(msg, pin, ref, extack);
ret = dpll_msg_add_ffo(msg, pin, ref,
DPLL_FFO_PORT_RXTX_RATE, extack);
if (ret)
return ret;
ret = dpll_msg_add_measured_freq(msg, pin, ref, extack);

View File

@ -11,12 +11,15 @@
#include <uapi/linux/dpll.h>
/* Common nested types */
const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1] = {
const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_OPERSTATE + 1] = {
[DPLL_A_PIN_PARENT_ID] = { .type = NLA_U32, },
[DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
[DPLL_A_PIN_PRIO] = { .type = NLA_U32, },
[DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
[DPLL_A_PIN_OPERSTATE] = NLA_POLICY_RANGE(NLA_U32, 1, 4),
[DPLL_A_PIN_PHASE_OFFSET] = { .type = NLA_S64, },
[DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET] = { .type = NLA_SINT, },
[DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT] = { .type = NLA_SINT, },
};
const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1] = {

View File

@ -12,7 +12,7 @@
#include <uapi/linux/dpll.h>
/* Common nested types */
extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1];
extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_OPERSTATE + 1];
extern const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1];
extern const struct nla_policy dpll_reference_sync_nl_policy[DPLL_A_PIN_STATE + 1];

View File

@ -18,6 +18,7 @@
int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index)
{
struct zl3073x_chan *chan = &zldev->chan[index];
u64 val;
int rc;
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_MON_STATUS(index),
@ -25,8 +26,34 @@ int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index)
if (rc)
return rc;
return zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index),
&chan->refsel_status);
rc = zl3073x_read_u8(zldev, ZL_REG_DPLL_REFSEL_STATUS(index),
&chan->refsel_status);
if (rc)
return rc;
/* Read df_offset vs tracked reference */
rc = zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index),
ZL_DPLL_DF_READ_SEM);
if (rc)
return rc;
rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_DF_READ(index),
ZL_DPLL_DF_READ_SEM | ZL_DPLL_DF_READ_REF_OFST);
if (rc)
return rc;
rc = zl3073x_poll_zero_u8(zldev, ZL_REG_DPLL_DF_READ(index),
ZL_DPLL_DF_READ_SEM);
if (rc)
return rc;
rc = zl3073x_read_u48(zldev, ZL_REG_DPLL_DF_OFFSET(index), &val);
if (rc)
return rc;
chan->df_offset = sign_extend64(val, 47);
return 0;
}
/**

View File

@ -17,6 +17,7 @@ struct zl3073x_dev;
* @ref_prio: reference priority registers (4 bits per ref, P/N packed)
* @mon_status: monitor status register value
* @refsel_status: reference selection status register value
* @df_offset: frequency offset vs tracked reference in 2^-48 steps
*/
struct zl3073x_chan {
struct_group(cfg,
@ -26,6 +27,7 @@ struct zl3073x_chan {
struct_group(stat,
u8 mon_status;
u8 refsel_status;
s64 df_offset;
);
};
@ -37,6 +39,18 @@ int zl3073x_chan_state_set(struct zl3073x_dev *zldev, u8 index,
int zl3073x_chan_state_update(struct zl3073x_dev *zldev, u8 index);
/**
* zl3073x_chan_df_offset_get - get cached df_offset vs tracked reference
* @chan: pointer to channel state
*
* Return: frequency offset in 2^-48 steps
*/
static inline s64
zl3073x_chan_df_offset_get(const struct zl3073x_chan *chan)
{
return chan->df_offset;
}
/**
* zl3073x_chan_mode_get - get DPLL channel operating mode
* @chan: pointer to channel state

View File

@ -704,44 +704,6 @@ zl3073x_ref_freq_meas_update(struct zl3073x_dev *zldev)
return 0;
}
/**
* zl3073x_ref_ffo_update - update reference fractional frequency offsets
* @zldev: pointer to zl3073x_dev structure
*
* The function asks device to latch the latest measured fractional
* frequency offset values, reads and stores them into the ref state.
*
* Return: 0 on success, <0 on error
*/
static int
zl3073x_ref_ffo_update(struct zl3073x_dev *zldev)
{
int i, rc;
rc = zl3073x_ref_freq_meas_latch(zldev,
ZL_REF_FREQ_MEAS_CTRL_REF_FREQ_OFF);
if (rc)
return rc;
/* Read DPLL-to-REFx frequency offset measurements */
for (i = 0; i < ZL3073X_NUM_REFS; i++) {
s32 value;
/* Read value stored in units of 2^-32 signed */
rc = zl3073x_read_u32(zldev, ZL_REG_REF_FREQ(i), &value);
if (rc)
return rc;
/* Convert to ppt
* ffo = (10^12 * value) / 2^32
* ffo = ( 5^12 * value) / 2^20
*/
zldev->ref[i].ffo = mul_s64_u64_shr(value, 244140625, 20);
}
return 0;
}
static void
zl3073x_dev_periodic_work(struct kthread_work *work)
{
@ -776,13 +738,6 @@ zl3073x_dev_periodic_work(struct kthread_work *work)
}
}
/* Update references' fractional frequency offsets */
rc = zl3073x_ref_ffo_update(zldev);
if (rc)
dev_warn(zldev->dev,
"Failed to update fractional frequency offsets: %pe\n",
ERR_PTR(rc));
list_for_each_entry(zldpll, &zldev->dplls, list)
zl3073x_dpll_changes_check(zldpll);

View File

@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/atomic.h>
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/bug.h>
@ -38,7 +39,7 @@
* @prio: pin priority <0, 14>
* @esync_control: embedded sync is controllable
* @phase_gran: phase adjustment granularity
* @pin_state: last saved pin state
* @operstate: last saved operational state
* @phase_offset: last saved pin phase offset
* @freq_offset: last saved fractional frequency offset
* @measured_freq: last saved measured frequency
@ -55,9 +56,9 @@ struct zl3073x_dpll_pin {
u8 prio;
bool esync_control;
s32 phase_gran;
enum dpll_pin_state pin_state;
enum dpll_pin_operstate operstate;
s64 phase_offset;
s64 freq_offset;
atomic64_t freq_offset;
u32 measured_freq;
};
@ -295,11 +296,15 @@ zl3073x_dpll_input_pin_ref_sync_set(const struct dpll_pin *dpll_pin,
static int
zl3073x_dpll_input_pin_ffo_get(const struct dpll_pin *dpll_pin, void *pin_priv,
const struct dpll_device *dpll, void *dpll_priv,
s64 *ffo, struct netlink_ext_ack *extack)
struct dpll_ffo_param *ffo,
struct netlink_ext_ack *extack)
{
struct zl3073x_dpll_pin *pin = pin_priv;
*ffo = pin->freq_offset;
if (pin->operstate != DPLL_PIN_OPERSTATE_ACTIVE)
return -ENODATA;
ffo->ffo = atomic64_read(&pin->freq_offset);
return 0;
}
@ -500,46 +505,41 @@ zl3073x_dpll_input_pin_phase_adjust_set(const struct dpll_pin *dpll_pin,
}
/**
* zl3073x_dpll_ref_state_get - get status for given input pin
* zl3073x_dpll_ref_operstate_get - get operational state for input pin
* @pin: pointer to pin
* @state: place to store status
* @operstate: place to store operational state
*
* Checks current status for the given input pin and stores the value
* to @state.
* Returns the actual hardware state of the pin: whether it is actively
* used by the DPLL, has no signal, failed qualification, or is simply
* not in use.
*
* Return: 0 on success, <0 on error
*/
static int
zl3073x_dpll_ref_state_get(struct zl3073x_dpll_pin *pin,
enum dpll_pin_state *state)
zl3073x_dpll_ref_operstate_get(struct zl3073x_dpll_pin *pin,
enum dpll_pin_operstate *operstate)
{
struct zl3073x_dpll *zldpll = pin->dpll;
struct zl3073x_dev *zldev = zldpll->dev;
const struct zl3073x_chan *chan;
u8 ref;
const struct zl3073x_ref *ref;
u8 ref_id;
chan = zl3073x_chan_state_get(zldev, zldpll->id);
ref = zl3073x_input_pin_ref_get(pin->id);
ref_id = zl3073x_input_pin_ref_get(pin->id);
/* Check if the pin reference is connected */
if (ref == zl3073x_dpll_connected_ref_get(zldpll)) {
*state = DPLL_PIN_STATE_CONNECTED;
/* Check if this pin is the currently locked reference */
if (ref_id == zl3073x_dpll_connected_ref_get(zldpll)) {
*operstate = DPLL_PIN_OPERSTATE_ACTIVE;
return 0;
}
/* If the DPLL is running in automatic mode and the reference is
* selectable and its monitor does not report any error then report
* pin as selectable.
*/
if (zl3073x_chan_mode_get(chan) == ZL_DPLL_MODE_REFSEL_MODE_AUTO &&
zl3073x_dev_ref_is_status_ok(zldev, ref) &&
zl3073x_chan_ref_is_selectable(chan, ref)) {
*state = DPLL_PIN_STATE_SELECTABLE;
return 0;
}
/* Otherwise report the pin as disconnected */
*state = DPLL_PIN_STATE_DISCONNECTED;
/* Check reference monitor status */
ref = zl3073x_ref_state_get(zldev, ref_id);
if (ref->mon_status & ZL_REF_MON_STATUS_LOS)
*operstate = DPLL_PIN_OPERSTATE_NO_SIGNAL;
else if (!zl3073x_ref_is_status_ok(ref))
*operstate = DPLL_PIN_OPERSTATE_QUAL_FAILED;
else
*operstate = DPLL_PIN_OPERSTATE_STANDBY;
return 0;
}
@ -551,10 +551,48 @@ zl3073x_dpll_input_pin_state_on_dpll_get(const struct dpll_pin *dpll_pin,
void *dpll_priv,
enum dpll_pin_state *state,
struct netlink_ext_ack *extack)
{
struct zl3073x_dpll *zldpll = dpll_priv;
struct zl3073x_dpll_pin *pin = pin_priv;
const struct zl3073x_chan *chan;
u8 mode, ref;
chan = zl3073x_chan_state_get(zldpll->dev, zldpll->id);
ref = zl3073x_input_pin_ref_get(pin->id);
mode = zl3073x_chan_mode_get(chan);
switch (mode) {
case ZL_DPLL_MODE_REFSEL_MODE_REFLOCK:
if (ref == zl3073x_chan_ref_get(chan))
*state = DPLL_PIN_STATE_CONNECTED;
else
*state = DPLL_PIN_STATE_DISCONNECTED;
break;
case ZL_DPLL_MODE_REFSEL_MODE_AUTO:
if (zl3073x_chan_ref_is_selectable(chan, ref))
*state = DPLL_PIN_STATE_SELECTABLE;
else
*state = DPLL_PIN_STATE_DISCONNECTED;
break;
default:
*state = DPLL_PIN_STATE_DISCONNECTED;
break;
}
return 0;
}
static int
zl3073x_dpll_input_pin_operstate_on_dpll_get(const struct dpll_pin *dpll_pin,
void *pin_priv,
const struct dpll_device *dpll,
void *dpll_priv,
enum dpll_pin_operstate *operstate,
struct netlink_ext_ack *extack)
{
struct zl3073x_dpll_pin *pin = pin_priv;
return zl3073x_dpll_ref_state_get(pin, state);
return zl3073x_dpll_ref_operstate_get(pin, operstate);
}
static int
@ -1241,6 +1279,7 @@ zl3073x_dpll_freq_monitor_set(const struct dpll_device *dpll,
}
static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops = {
.supported_ffo = BIT(DPLL_FFO_PIN_DEVICE),
.direction_get = zl3073x_dpll_pin_direction_get,
.esync_get = zl3073x_dpll_input_pin_esync_get,
.esync_set = zl3073x_dpll_input_pin_esync_set,
@ -1248,6 +1287,7 @@ static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops = {
.frequency_get = zl3073x_dpll_input_pin_frequency_get,
.frequency_set = zl3073x_dpll_input_pin_frequency_set,
.measured_freq_get = zl3073x_dpll_input_pin_measured_freq_get,
.operstate_on_dpll_get = zl3073x_dpll_input_pin_operstate_on_dpll_get,
.phase_offset_get = zl3073x_dpll_input_pin_phase_offset_get,
.phase_adjust_get = zl3073x_dpll_input_pin_phase_adjust_get,
.phase_adjust_set = zl3073x_dpll_input_pin_phase_adjust_set,
@ -1663,7 +1703,7 @@ zl3073x_dpll_pin_phase_offset_check(struct zl3073x_dpll_pin *pin)
* 2) For other pins use appropriate ref_phase register if the phase
* monitor feature is enabled.
*/
if (pin->pin_state == DPLL_PIN_STATE_CONNECTED)
if (pin->operstate == DPLL_PIN_OPERSTATE_ACTIVE)
reg = ZL_REG_DPLL_PHASE_ERR_DATA(zldpll->id);
else if (zldpll->phase_monitor)
reg = ZL_REG_REF_PHASE(ref_id);
@ -1695,37 +1735,29 @@ zl3073x_dpll_pin_phase_offset_check(struct zl3073x_dpll_pin *pin)
}
/**
* zl3073x_dpll_pin_ffo_check - check for pin fractional frequency offset change
* zl3073x_dpll_pin_ffo_check - check for FFO change on active pin
* @pin: pin to check
*
* Check for the given pin's fractional frequency change.
*
* Return: true on fractional frequency offset change, false otherwise
* Return: true on change, false otherwise
*/
static bool
zl3073x_dpll_pin_ffo_check(struct zl3073x_dpll_pin *pin)
{
struct zl3073x_dpll *zldpll = pin->dpll;
struct zl3073x_dev *zldev = zldpll->dev;
const struct zl3073x_ref *ref;
u8 ref_id;
const struct zl3073x_chan *chan;
s64 ffo;
/* Get reference monitor status */
ref_id = zl3073x_input_pin_ref_get(pin->id);
ref = zl3073x_ref_state_get(zldev, ref_id);
/* Do not report ffo changes if the reference monitor report errors */
if (!zl3073x_ref_is_status_ok(ref))
if (pin->operstate != DPLL_PIN_OPERSTATE_ACTIVE)
return false;
/* Compare with previous value */
ffo = zl3073x_ref_ffo_get(ref);
if (pin->freq_offset != ffo) {
dev_dbg(zldev->dev, "%s freq offset changed: %lld -> %lld\n",
pin->label, pin->freq_offset, ffo);
pin->freq_offset = ffo;
chan = zl3073x_chan_state_get(zldpll->dev, zldpll->id);
ffo = mul_s64_u64_shr(zl3073x_chan_df_offset_get(chan),
244140625, 36);
if (atomic64_xchg(&pin->freq_offset, ffo) != ffo) {
dev_dbg(zldev->dev, "%s freq offset changed to: %lld\n",
pin->label, ffo);
return true;
}
@ -1828,7 +1860,7 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
}
list_for_each_entry(pin, &zldpll->pins, list) {
enum dpll_pin_state state;
enum dpll_pin_operstate operstate;
bool pin_changed = false;
/* Output pins change checks are not necessary because output
@ -1837,18 +1869,18 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
if (!zl3073x_dpll_is_input_pin(pin))
continue;
rc = zl3073x_dpll_ref_state_get(pin, &state);
rc = zl3073x_dpll_ref_operstate_get(pin, &operstate);
if (rc) {
dev_err(dev,
"Failed to get %s on DPLL%u state: %pe\n",
"Failed to get %s on DPLL%u oper state: %pe\n",
pin->label, zldpll->id, ERR_PTR(rc));
return;
}
if (state != pin->pin_state) {
dev_dbg(dev, "%s state changed: %u->%u\n", pin->label,
pin->pin_state, state);
pin->pin_state = state;
if (operstate != pin->operstate) {
dev_dbg(dev, "%s oper state changed: %u->%u\n",
pin->label, pin->operstate, operstate);
pin->operstate = operstate;
pin_changed = true;
}

View File

@ -22,7 +22,6 @@ struct zl3073x_dev;
* @freq_ratio_n: FEC mode divisor
* @sync_ctrl: reference sync control
* @config: reference config
* @ffo: current fractional frequency offset
* @meas_freq: measured input frequency in Hz
* @mon_status: reference monitor status
*/
@ -40,7 +39,6 @@ struct zl3073x_ref {
u8 config;
);
struct_group(stat, /* Status */
s64 ffo;
u32 meas_freq;
u8 mon_status;
);
@ -58,18 +56,6 @@ int zl3073x_ref_state_update(struct zl3073x_dev *zldev, u8 index);
int zl3073x_ref_freq_factorize(u32 freq, u16 *base, u16 *mult);
/**
* zl3073x_ref_ffo_get - get current fractional frequency offset
* @ref: pointer to ref state
*
* Return: the latest measured fractional frequency offset
*/
static inline s64
zl3073x_ref_ffo_get(const struct zl3073x_ref *ref)
{
return ref->ffo;
}
/**
* zl3073x_ref_meas_freq_get - get measured input frequency
* @ref: pointer to ref state

View File

@ -98,7 +98,14 @@
#define ZL_REG_REF_MON_STATUS(_idx) \
ZL_REG_IDX(_idx, 2, 0x02, 1, ZL3073X_NUM_REFS, 1)
#define ZL_REF_MON_STATUS_OK 0 /* all bits zeroed */
#define ZL_REF_MON_STATUS_OK 0
#define ZL_REF_MON_STATUS_LOS BIT(0)
#define ZL_REF_MON_STATUS_SCM BIT(1)
#define ZL_REF_MON_STATUS_CFM BIT(2)
#define ZL_REF_MON_STATUS_GST BIT(3)
#define ZL_REF_MON_STATUS_PFM BIT(4)
#define ZL_REF_MON_STATUS_ESYNC BIT(6)
#define ZL_REF_MON_STATUS_SPLIT_XO BIT(7)
#define ZL_REG_DPLL_MON_STATUS(_idx) \
ZL_REG_IDX(_idx, 2, 0x10, 1, ZL3073X_MAX_CHANNELS, 1)
@ -157,6 +164,11 @@
#define ZL_DPLL_MODE_REFSEL_MODE_NCO 4
#define ZL_DPLL_MODE_REFSEL_REF GENMASK(7, 4)
#define ZL_REG_DPLL_DF_READ(_idx) \
ZL_REG_IDX(_idx, 5, 0x28, 1, ZL3073X_MAX_CHANNELS, 1)
#define ZL_DPLL_DF_READ_SEM BIT(4)
#define ZL_DPLL_DF_READ_REF_OFST BIT(3)
#define ZL_REG_DPLL_MEAS_CTRL ZL_REG(5, 0x50, 1)
#define ZL_DPLL_MEAS_CTRL_EN BIT(0)
#define ZL_DPLL_MEAS_CTRL_AVG_FACTOR GENMASK(7, 4)
@ -169,6 +181,16 @@
#define ZL_REG_DPLL_PHASE_ERR_DATA(_idx) \
ZL_REG_IDX(_idx, 5, 0x55, 6, ZL3073X_MAX_CHANNELS, 6)
/*******************************
* Register Pages 6-7, DPLL Data
*******************************/
#define ZL_REG_DPLL_DF_OFFSET_03(_idx) \
ZL_REG_IDX(_idx, 6, 0x00, 6, 4, 0x20)
#define ZL_REG_DPLL_DF_OFFSET_4 ZL_REG(7, 0x00, 6)
#define ZL_REG_DPLL_DF_OFFSET(_idx) \
((_idx) < 4 ? ZL_REG_DPLL_DF_OFFSET_03(_idx) : ZL_REG_DPLL_DF_OFFSET_4)
/***********************************
* Register Page 9, Synth and Output
***********************************/

View File

@ -140,8 +140,9 @@ int mana_ib_install_cq_cb(struct mana_ib_dev *mdev, struct mana_ib_cq *cq)
if (cq->queue.id >= gc->max_num_cqs)
return -EINVAL;
/* Create CQ table entry */
WARN_ON(gc->cq_table[cq->queue.id]);
/* Create CQ table entry, sharing a CQ between WQs is not supported */
if (gc->cq_table[cq->queue.id])
return -EINVAL;
if (cq->queue.kmem)
gdma_cq = cq->queue.kmem;
else

View File

@ -21,6 +21,9 @@ static int mana_ib_cfg_vport_steering(struct mana_ib_dev *dev,
gc = mdev_to_gc(dev);
if (rx_hash_key_len > sizeof(req->hashkey))
return -EINVAL;
req_buf_size = struct_size(req, indir_tab, MANA_INDIRECT_TABLE_DEF_SIZE);
req = kzalloc(req_buf_size, GFP_KERNEL);
if (!req)

View File

@ -10731,12 +10731,10 @@ void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx,
struct bnxt_ntuple_filter *ntp_fltr;
int i;
if (netif_running(bp->dev)) {
bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic);
for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) {
if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID)
bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i);
}
bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic);
for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) {
if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID)
bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i);
}
if (!all)
return;

View File

@ -1756,6 +1756,27 @@ static int ibmveth_set_mac_addr(struct net_device *dev, void *p)
return 0;
}
static netdev_features_t ibmveth_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
/* Some physical adapters do not support segmentation offload with
* MSS < 224. Disable GSO for such packets to avoid adapter freeze.
* Note: Single-segment packets (gso_segs == 1) don't need this check
* as they bypass the LSO path and are transmitted without segmentation.
*/
if (skb_is_gso(skb)) {
if (skb_shinfo(skb)->gso_size < IBMVETH_MIN_LSO_MSS) {
netdev_warn_once(dev,
"MSS %u too small for LSO, disabling GSO\n",
skb_shinfo(skb)->gso_size);
features &= ~NETIF_F_GSO_MASK;
}
}
return vlan_features_check(skb, features);
}
static const struct net_device_ops ibmveth_netdev_ops = {
.ndo_open = ibmveth_open,
.ndo_stop = ibmveth_close,
@ -1767,6 +1788,7 @@ static const struct net_device_ops ibmveth_netdev_ops = {
.ndo_set_features = ibmveth_set_features,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = ibmveth_set_mac_addr,
.ndo_features_check = ibmveth_features_check,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ibmveth_poll_controller,
#endif

View File

@ -37,6 +37,7 @@
#define IBMVETH_ILLAN_IPV4_TCP_CSUM 0x0000000000000002UL
#define IBMVETH_ILLAN_ACTIVE_TRUNK 0x0000000000000001UL
#define IBMVETH_MIN_LSO_MSS 224 /* Minimum MSS for LSO */
/* hcall macros */
#define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
plpar_hcall_norets(H_REGISTER_LOGICAL_LAN, ua, buflst, rxq, fltlst, mac)

View File

@ -2789,12 +2789,14 @@ void ice_vsi_set_napi_queues(struct ice_vsi *vsi)
ASSERT_RTNL();
ice_for_each_rxq(vsi, q_idx)
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_RX,
&vsi->rx_rings[q_idx]->q_vector->napi);
if (vsi->rx_rings[q_idx] && vsi->rx_rings[q_idx]->q_vector)
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_RX,
&vsi->rx_rings[q_idx]->q_vector->napi);
ice_for_each_txq(vsi, q_idx)
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_TX,
&vsi->tx_rings[q_idx]->q_vector->napi);
if (vsi->tx_rings[q_idx] && vsi->tx_rings[q_idx]->q_vector)
netif_queue_set_napi(netdev, q_idx, NETDEV_QUEUE_TYPE_TX,
&vsi->tx_rings[q_idx]->q_vector->napi);
/* Also set the interrupt number for the NAPI */
ice_for_each_q_vector(vsi, v_idx) {
struct ice_q_vector *q_vector = vsi->q_vectors[v_idx];

View File

@ -300,7 +300,8 @@ static int mlx5_dpll_state_on_dpll_set(const struct dpll_pin *pin,
static int mlx5_dpll_ffo_get(const struct dpll_pin *pin, void *pin_priv,
const struct dpll_device *dpll, void *dpll_priv,
s64 *ffo, struct netlink_ext_ack *extack)
struct dpll_ffo_param *ffo,
struct netlink_ext_ack *extack)
{
struct mlx5_dpll_synce_status synce_status;
struct mlx5_dpll *mdpll = pin_priv;
@ -309,10 +310,11 @@ static int mlx5_dpll_ffo_get(const struct dpll_pin *pin, void *pin_priv,
err = mlx5_dpll_synce_status_get(mdpll->mdev, &synce_status);
if (err)
return err;
return mlx5_dpll_pin_ffo_get(&synce_status, ffo);
return mlx5_dpll_pin_ffo_get(&synce_status, &ffo->ffo);
}
static const struct dpll_pin_ops mlx5_dpll_pins_ops = {
.supported_ffo = BIT(DPLL_FFO_PORT_RXTX_RATE),
.direction_get = mlx5_dpll_pin_direction_get,
.state_on_dpll_get = mlx5_dpll_state_on_dpll_get,
.state_on_dpll_set = mlx5_dpll_state_on_dpll_set,

View File

@ -390,6 +390,19 @@ static void nvmet_tcp_fatal_error(struct nvmet_tcp_queue *queue)
static void nvmet_tcp_socket_error(struct nvmet_tcp_queue *queue, int status)
{
/*
* Keep rcv_state at RECV_ERR even for the internal -ESHUTDOWN path.
* nvmet_tcp_handle_icreq() can return -ESHUTDOWN after the ICReq has
* already been consumed and queue teardown has started.
*
* If nvmet_tcp_data_ready() or nvmet_tcp_write_space() queues
* nvmet_tcp_io_work() again before nvmet_tcp_release_queue_work()
* cancels it, the queue must not keep that old receive state.
* Otherwise the next nvmet_tcp_io_work() run can reach
* nvmet_tcp_done_recv_pdu() and try to handle the same ICReq again.
*
* That is why queue->rcv_state needs to be updated before we return.
*/
queue->rcv_state = NVMET_TCP_RECV_ERR;
if (status == -EPIPE || status == -ECONNRESET)
kernel_sock_shutdown(queue->sock, SHUT_RDWR);
@ -893,10 +906,25 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
iov.iov_base = icresp;
iov.iov_len = sizeof(*icresp);
ret = kernel_sendmsg(queue->sock, &msg, &iov, 1, iov.iov_len);
if (ret < 0)
if (ret < 0) {
spin_lock_bh(&queue->state_lock);
if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
spin_unlock_bh(&queue->state_lock);
return -ESHUTDOWN;
}
queue->state = NVMET_TCP_Q_FAILED;
spin_unlock_bh(&queue->state_lock);
return ret; /* queue removal will cleanup */
}
spin_lock_bh(&queue->state_lock);
if (queue->state == NVMET_TCP_Q_DISCONNECTING) {
spin_unlock_bh(&queue->state_lock);
/* Tell nvmet_tcp_socket_error() teardown is in progress. */
return -ESHUTDOWN;
}
queue->state = NVMET_TCP_Q_LIVE;
spin_unlock_bh(&queue->state_lock);
nvmet_prepare_receive_pdu(queue);
return 0;
}

View File

@ -1585,6 +1585,15 @@ static ssize_t bindings_show(const struct bus_type *bus, char *buf)
static BUS_ATTR_RO(bindings);
static ssize_t bindings_complete_count_show(const struct bus_type *bus,
char *buf)
{
return sysfs_emit(buf, "%llu\n",
atomic64_read(&ap_bindings_complete_count));
}
static BUS_ATTR_RO(bindings_complete_count);
static ssize_t features_show(const struct bus_type *bus, char *buf)
{
int n = 0;
@ -1625,6 +1634,7 @@ static struct attribute *ap_bus_attrs[] = {
&bus_attr_aqmask.attr,
&bus_attr_scans.attr,
&bus_attr_bindings.attr,
&bus_attr_bindings_complete_count.attr,
&bus_attr_features.attr,
NULL,
};

View File

@ -2751,7 +2751,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
if (!elsio->u.els_logo.els_logo_pyld) {
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
qla2x00_free_fcport(fcport);
return QLA_FUNCTION_FAILED;
}
@ -2776,7 +2775,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode,
if (rval != QLA_SUCCESS) {
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
qla2x00_free_fcport(fcport);
return QLA_FUNCTION_FAILED;
}

View File

@ -914,6 +914,12 @@ static void privcmd_close(struct vm_area_struct *vma)
kfree(pages);
}
static int privcmd_may_split(struct vm_area_struct *area, unsigned long addr)
{
/* Forbid splitting, avoids double free via privcmd_close(). */
return -EINVAL;
}
static vm_fault_t privcmd_fault(struct vm_fault *vmf)
{
printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n",
@ -925,6 +931,7 @@ static vm_fault_t privcmd_fault(struct vm_fault *vmf)
static const struct vm_operations_struct privcmd_vm_ops = {
.close = privcmd_close,
.may_split = privcmd_may_split,
.fault = privcmd_fault
};

View File

@ -317,6 +317,12 @@ static void gfs2_metapath_ra(struct gfs2_glock *gl, __be64 *start, __be64 *end)
}
}
static inline struct buffer_head *
metapath_dibh(struct metapath *mp)
{
return mp->mp_bh[0];
}
static int __fillup_metapath(struct gfs2_inode *ip, struct metapath *mp,
unsigned int x, unsigned int h)
{
@ -661,7 +667,7 @@ static int __gfs2_iomap_alloc(struct inode *inode, struct iomap *iomap,
{
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
struct buffer_head *dibh = mp->mp_bh[0];
struct buffer_head *dibh = metapath_dibh(mp);
u64 bn;
unsigned n, i, blks, alloced = 0, iblks = 0, branch_start = 0;
size_t dblks = iomap->length >> inode->i_blkbits;
@ -1116,10 +1122,18 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length,
goto out_unlock;
break;
default:
goto out_unlock;
goto out;
}
ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp);
if (ret)
goto out_unlock;
out:
if (iomap->type == IOMAP_INLINE) {
iomap->private = metapath_dibh(&mp);
get_bh(iomap->private);
}
out_unlock:
release_metapath(&mp);
@ -1133,6 +1147,9 @@ static int gfs2_iomap_end(struct inode *inode, loff_t pos, loff_t length,
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_sbd *sdp = GFS2_SB(inode);
if (iomap->private)
brelse(iomap->private);
switch (flags & (IOMAP_WRITE | IOMAP_ZERO)) {
case IOMAP_WRITE:
if (flags & IOMAP_DIRECT)

View File

@ -71,6 +71,22 @@ struct dpll_device_ops {
RH_KABI_RESERVE(10)
};
enum dpll_ffo_type {
DPLL_FFO_PORT_RXTX_RATE,
DPLL_FFO_PIN_DEVICE,
__DPLL_FFO_TYPE_MAX,
};
/* RHEL: we have to keep 'ffo' field to be first to preserve compatibility
* with older .ffo_get() callbacks that accepts 's64 *' as parameter instead
* of 'struct dpll_ffo_param *'
*/
struct dpll_ffo_param {
s64 ffo;
enum dpll_ffo_type type;
};
struct dpll_pin_ops {
int (*frequency_set)(const struct dpll_pin *pin, void *pin_priv,
const struct dpll_device *dpll, void *dpll_priv,
@ -124,9 +140,13 @@ struct dpll_pin_ops {
const struct dpll_device *dpll, void *dpll_priv,
const s32 phase_adjust,
struct netlink_ext_ack *extack);
int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
RH_KABI_REPLACE(int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
const struct dpll_device *dpll, void *dpll_priv,
s64 *ffo, struct netlink_ext_ack *extack);
s64 *ffo, struct netlink_ext_ack *extack),
int (*ffo_get)(const struct dpll_pin *pin, void *pin_priv,
const struct dpll_device *dpll, void *dpll_priv,
struct dpll_ffo_param *ffo,
struct netlink_ext_ack *extack))
int (*esync_set)(const struct dpll_pin *pin, void *pin_priv,
const struct dpll_device *dpll, void *dpll_priv,
u64 freq, struct netlink_ext_ack *extack);
@ -149,8 +169,13 @@ struct dpll_pin_ops {
const struct dpll_device *dpll,
void *dpll_priv, u64 *measured_freq,
struct netlink_ext_ack *extack))
RH_KABI_RESERVE(2)
RH_KABI_RESERVE(3)
RH_KABI_USE(2, int (*operstate_on_dpll_get)(const struct dpll_pin *pin,
void *pin_priv,
const struct dpll_device *dpll,
void *dpll_priv,
enum dpll_pin_operstate *operstate,
struct netlink_ext_ack *extack))
RH_KABI_USE(3, unsigned long supported_ffo)
RH_KABI_RESERVE(4)
RH_KABI_RESERVE(5)
RH_KABI_RESERVE(6)

View File

@ -14,7 +14,6 @@ struct tcf_pedit_key_ex {
struct tcf_pedit_parms {
struct tc_pedit_key *tcfp_keys;
struct tcf_pedit_key_ex *tcfp_keys_ex;
u32 tcfp_off_max_hint;
unsigned char tcfp_nkeys;
unsigned char tcfp_flags;
struct rcu_head rcu;

View File

@ -177,6 +177,28 @@ enum dpll_pin_state {
DPLL_PIN_STATE_MAX = (__DPLL_PIN_STATE_MAX - 1)
};
/**
* enum dpll_pin_operstate - defines possible operational states of a pin with
* respect to its parent DPLL device, valid values for DPLL_A_PIN_OPERSTATE
* attribute
* @DPLL_PIN_OPERSTATE_ACTIVE: pin is qualified and actively used by the DPLL
* @DPLL_PIN_OPERSTATE_STANDBY: pin is qualified but not actively used by the
* DPLL
* @DPLL_PIN_OPERSTATE_NO_SIGNAL: pin does not have a valid signal
* @DPLL_PIN_OPERSTATE_QUAL_FAILED: pin signal failed qualification (e.g.
* frequency or phase monitor)
*/
enum dpll_pin_operstate {
DPLL_PIN_OPERSTATE_ACTIVE = 1,
DPLL_PIN_OPERSTATE_STANDBY,
DPLL_PIN_OPERSTATE_NO_SIGNAL,
DPLL_PIN_OPERSTATE_QUAL_FAILED,
/* private: */
__DPLL_PIN_OPERSTATE_MAX,
DPLL_PIN_OPERSTATE_MAX = (__DPLL_PIN_OPERSTATE_MAX - 1)
};
/**
* enum dpll_pin_capabilities - defines possible capabilities of a pin, valid
* flags on DPLL_A_PIN_CAPABILITIES attribute
@ -256,6 +278,7 @@ enum dpll_a_pin {
DPLL_A_PIN_PHASE_ADJUST_GRAN,
DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
DPLL_A_PIN_MEASURED_FREQUENCY,
DPLL_A_PIN_OPERSTATE,
__DPLL_A_PIN_MAX,
DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)

View File

@ -1,3 +1,3 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
kernel.rhel,1,Red Hat,kernel-core,5.14.0-687.15.1.el9.x86_64,mailto:secalert@redhat.com
kernel.almalinux,1,AlmaLinux,kernel-core,5.14.0-687.15.1.el9.x86_64,mailto:security@almalinux.org
kernel.rhel,1,Red Hat,kernel-core,5.14.0-687.17.1.el9.x86_64,mailto:secalert@redhat.com
kernel.almalinux,1,AlmaLinux,kernel-core,5.14.0-687.17.1.el9.x86_64,mailto:security@almalinux.org

View File

@ -959,6 +959,7 @@ void __noreturn make_task_dead(int signr)
futex_exit_recursive(tsk);
tsk->exit_state = EXIT_DEAD;
refcount_inc(&tsk->rcu_users);
preempt_disable();
do_task_dead();
}

View File

@ -5418,9 +5418,11 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "");
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
return;
goto unlock;
conn->passkey_notify = __le32_to_cpu(ev->passkey);
conn->passkey_entered = 0;
@ -5429,6 +5431,9 @@ static void hci_user_passkey_notify_evt(struct hci_dev *hdev, void *data,
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
conn->dst_type, conn->passkey_notify,
conn->passkey_entered);
unlock:
hci_dev_unlock(hdev);
}
static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
@ -5439,14 +5444,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
bt_dev_dbg(hdev, "");
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
return;
goto unlock;
switch (ev->type) {
case HCI_KEYPRESS_STARTED:
conn->passkey_entered = 0;
return;
goto unlock;
case HCI_KEYPRESS_ENTERED:
conn->passkey_entered++;
@ -5461,13 +5468,16 @@ static void hci_keypress_notify_evt(struct hci_dev *hdev, void *data,
break;
case HCI_KEYPRESS_COMPLETED:
return;
goto unlock;
}
if (hci_dev_test_flag(hdev, HCI_MGMT))
mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
conn->dst_type, conn->passkey_notify,
conn->passkey_entered);
unlock:
hci_dev_unlock(hdev);
}
static void hci_simple_pair_complete_evt(struct hci_dev *hdev, void *data,

View File

@ -7126,7 +7126,8 @@ static void create_big_complete(struct hci_dev *hdev, void *data, int err)
static int hci_le_big_create_sync(struct hci_dev *hdev, void *data)
{
DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11);
DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis,
HCI_MAX_ISO_BIS);
struct hci_conn *conn = data;
struct bt_iso_qos *qos = &conn->iso_qos;
int err;

View File

@ -1229,12 +1229,6 @@ static int isotp_release(struct socket *sock)
so->ifindex = 0;
so->bound = 0;
if (so->rx.buf != so->rx.sbuf)
kfree(so->rx.buf);
if (so->tx.buf != so->tx.sbuf)
kfree(so->tx.buf);
sock_orphan(sk);
sock->sk = NULL;
@ -1602,6 +1596,21 @@ static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
return NOTIFY_DONE;
}
static void isotp_sock_destruct(struct sock *sk)
{
struct isotp_sock *so = isotp_sk(sk);
/* do the standard CAN sock destruct work */
can_sock_destruct(sk);
/* free potential extended PDU buffers */
if (so->rx.buf != so->rx.sbuf)
kfree(so->rx.buf);
if (so->tx.buf != so->tx.sbuf)
kfree(so->tx.buf);
}
static int isotp_init(struct sock *sk)
{
struct isotp_sock *so = isotp_sk(sk);
@ -1648,6 +1657,9 @@ static int isotp_init(struct sock *sk)
list_add_tail(&so->notifier, &isotp_notifier_list);
spin_unlock(&isotp_notifier_lock);
/* re-assign default can_sock_destruct() reference */
sk->sk_destruct = isotp_sock_destruct;
return 0;
}

View File

@ -8890,7 +8890,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
struct ieee80211_bss *bss = (void *)cbss->priv;
struct sta_info *new_sta = NULL;
struct ieee80211_link_data *link;
bool have_sta = false;
struct sta_info *have_sta = NULL;
bool mlo;
int err;
u16 new_links;
@ -8909,11 +8909,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
mlo = false;
}
if (assoc) {
rcu_read_lock();
if (assoc)
have_sta = sta_info_get(sdata, ap_mld_addr);
rcu_read_unlock();
}
if (mlo && !have_sta &&
WARN_ON(sdata->vif.valid_links || sdata->vif.active_links))
@ -9072,6 +9069,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
out_release_chan:
ieee80211_link_release_channel(link);
out_err:
if (mlo && have_sta)
WARN_ON(__sta_info_destroy(have_sta));
ieee80211_vif_set_links(sdata, 0, 0);
return err;
}

View File

@ -4819,7 +4819,7 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx,
struct sk_buff *skb = rx->skb;
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
static ieee80211_rx_result res;
ieee80211_rx_result res;
int orig_len = skb->len;
int hdrlen = ieee80211_hdrlen(hdr->frame_control);
int snap_offs = hdrlen;

View File

@ -3565,11 +3565,11 @@ void ieee80211_dfs_radar_detected_work(struct wiphy *wiphy,
struct ieee80211_local *local =
container_of(work, struct ieee80211_local, radar_detected_work);
struct cfg80211_chan_def chandef;
struct ieee80211_chanctx *ctx;
struct ieee80211_chanctx *ctx, *tmp;
lockdep_assert_wiphy(local->hw.wiphy);
list_for_each_entry(ctx, &local->chanctx_list, list) {
list_for_each_entry_safe(ctx, tmp, &local->chanctx_list, list) {
if (ctx->replace_state == IEEE80211_CHANCTX_REPLACES_OTHER)
continue;

View File

@ -4248,6 +4248,8 @@ int __init mptcp_proto_v6_init(void)
{
int err;
mptcp_subflow_v6_init();
mptcp_v6_prot = mptcp_prot;
strscpy(mptcp_v6_prot.name, "MPTCPv6", sizeof(mptcp_v6_prot.name));
mptcp_v6_prot.slab = NULL;

View File

@ -794,6 +794,7 @@ static inline void mptcp_subflow_tcp_fallback(struct sock *sk,
void __init mptcp_proto_init(void);
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
int __init mptcp_proto_v6_init(void);
void __init mptcp_subflow_v6_init(void);
#endif
struct sock *mptcp_sk_clone_init(const struct sock *sk,

View File

@ -2103,7 +2103,15 @@ void __init mptcp_subflow_init(void)
tcp_prot_override.release_cb = tcp_release_cb_override;
tcp_prot_override.diag_destroy = tcp_abort_override;
mptcp_diag_subflow_init(&subflow_ulp_ops);
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
panic("MPTCP: failed to register subflows to ULP\n");
}
#if IS_ENABLED(CONFIG_MPTCP_IPV6)
void __init mptcp_subflow_v6_init(void)
{
/* In struct mptcp_subflow_request_sock, we assume the TCP request sock
* structures for v4 and v6 have the same size. It should not changed in
* the future but better to make sure to be warned if it is no longer
@ -2139,10 +2147,5 @@ void __init mptcp_subflow_init(void)
tcpv6_prot_override = tcpv6_prot;
tcpv6_prot_override.release_cb = tcp_release_cb_override;
tcpv6_prot_override.diag_destroy = tcp_abort_override;
#endif
mptcp_diag_subflow_init(&subflow_ulp_ops);
if (tcp_register_ulp(&subflow_ulp_ops) != 0)
panic("MPTCP: failed to register subflows to ULP\n");
}
#endif

View File

@ -16,6 +16,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/slab.h>
#include <linux/overflow.h>
#include <net/ipv6.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
@ -24,6 +25,7 @@
#include <uapi/linux/tc_act/tc_pedit.h>
#include <net/pkt_cls.h>
#include <net/tc_wrapper.h>
#include <asm/unaligned.h>
static struct tc_action_ops act_pedit_ops;
@ -242,7 +244,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
goto out_free_ex;
}
nparms->tcfp_off_max_hint = 0;
nparms->tcfp_flags = parm->flags;
nparms->tcfp_nkeys = parm->nkeys;
@ -268,14 +269,6 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla,
BITS_PER_TYPE(int) - 1,
nparms->tcfp_keys[i].shift);
/* The AT option can read a single byte, we can bound the actual
* value with uchar max.
*/
cur += (0xff & offmask) >> nparms->tcfp_keys[i].shift;
/* Each key touches 4 bytes starting from the computed offset */
nparms->tcfp_off_max_hint =
max(nparms->tcfp_off_max_hint, cur + 4);
}
p = to_pedit(*a);
@ -318,15 +311,12 @@ static void tcf_pedit_cleanup(struct tc_action *a)
call_rcu(&parms->rcu, tcf_pedit_cleanup_rcu);
}
static bool offset_valid(struct sk_buff *skb, int offset)
static bool offset_valid(struct sk_buff *skb, int offset, int len)
{
if (offset > 0 && offset > skb->len)
if (offset < -(int)skb_headroom(skb))
return false;
if (offset < 0 && -offset > skb_headroom(skb))
return false;
return true;
return offset <= (int)skb->len - len;
}
static int pedit_l4_skb_offset(struct sk_buff *skb, int *hoffset, const int header_type)
@ -393,18 +383,10 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
struct tcf_pedit_key_ex *tkey_ex;
struct tcf_pedit_parms *parms;
struct tc_pedit_key *tkey;
u32 max_offset;
int i;
parms = rcu_dereference_bh(p->parms);
max_offset = (skb_transport_header_was_set(skb) ?
skb_transport_offset(skb) :
skb_network_offset(skb)) +
parms->tcfp_off_max_hint;
if (skb_ensure_writable(skb, min(skb->len, max_offset)))
goto done;
tcf_lastuse_update(&p->tcf_tm);
tcf_action_update_bstats(&p->common, skb);
@ -412,10 +394,11 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
tkey_ex = parms->tcfp_keys_ex;
for (i = parms->tcfp_nkeys; i > 0; i--, tkey++) {
int write_offset, write_len;
int offset = tkey->off;
int hoffset = 0;
u32 *ptr, hdata;
u32 val;
u32 cur_val, val;
u32 *ptr;
int rc;
if (tkey_ex) {
@ -433,13 +416,15 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
if (tkey->offmask) {
u8 *d, _d;
int at_offset;
if (!offset_valid(skb, hoffset + tkey->at)) {
if (check_add_overflow(hoffset, (int)tkey->at, &at_offset) ||
!offset_valid(skb, at_offset, sizeof(_d))) {
pr_info_ratelimited("tc action pedit 'at' offset %d out of bounds\n",
hoffset + tkey->at);
goto bad;
}
d = skb_header_pointer(skb, hoffset + tkey->at,
d = skb_header_pointer(skb, at_offset,
sizeof(_d), &_d);
if (!d)
goto bad;
@ -451,31 +436,51 @@ TC_INDIRECT_SCOPE int tcf_pedit_act(struct sk_buff *skb,
}
}
if (!offset_valid(skb, hoffset + offset)) {
pr_info_ratelimited("tc action pedit offset %d out of bounds\n", hoffset + offset);
if (check_add_overflow(hoffset, offset, &write_offset)) {
pr_info_ratelimited("tc action pedit offset overflow\n");
goto bad;
}
ptr = skb_header_pointer(skb, hoffset + offset,
sizeof(hdata), &hdata);
if (!ptr)
if (!offset_valid(skb, write_offset, sizeof(*ptr))) {
pr_info_ratelimited("tc action pedit offset %d out of bounds\n",
write_offset);
goto bad;
}
if (write_offset < 0) {
if (skb_cow(skb, -write_offset))
goto bad;
if (write_offset + (int)sizeof(*ptr) > 0) {
if (skb_ensure_writable(skb,
min_t(int, skb->len,
write_offset + (int)sizeof(*ptr))))
goto bad;
}
} else {
if (check_add_overflow(write_offset, (int)sizeof(*ptr),
&write_len))
goto bad;
if (skb_ensure_writable(skb, min_t(int, skb->len,
write_len)))
goto bad;
}
ptr = (u32 *)(skb->data + write_offset);
cur_val = get_unaligned(ptr);
/* just do it, baby */
switch (cmd) {
case TCA_PEDIT_KEY_EX_CMD_SET:
val = tkey->val;
break;
case TCA_PEDIT_KEY_EX_CMD_ADD:
val = (*ptr + tkey->val) & ~tkey->mask;
val = (cur_val + tkey->val) & ~tkey->mask;
break;
default:
pr_info_ratelimited("tc action pedit bad command (%d)\n", cmd);
goto bad;
}
*ptr = ((*ptr & tkey->mask) ^ val);
if (ptr == &hdata)
skb_store_bits(skb, hoffset + offset, ptr, 4);
put_unaligned((cur_val & tkey->mask) ^ val, ptr);
}
goto done;

View File

@ -275,8 +275,8 @@ static inline bool has_tx_length_quirk(struct snd_usb_audio *chip)
return chip->quirk_flags & QUIRK_FLAG_TX_LENGTH;
}
static void prepare_silent_urb(struct snd_usb_endpoint *ep,
struct snd_urb_ctx *ctx)
static int prepare_silent_urb(struct snd_usb_endpoint *ep,
struct snd_urb_ctx *ctx)
{
struct urb *urb = ctx->urb;
unsigned int offs = 0;
@ -289,28 +289,34 @@ static void prepare_silent_urb(struct snd_usb_endpoint *ep,
extra = sizeof(packet_length);
for (i = 0; i < ctx->packets; ++i) {
unsigned int offset;
unsigned int length;
int counts;
int length;
counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, 0);
length = counts * ep->stride; /* number of silent bytes */
offset = offs * ep->stride + extra * i;
urb->iso_frame_desc[i].offset = offset;
length = snd_usb_endpoint_next_packet_size(ep, ctx, i, 0);
if (length < 0)
return length;
length *= ep->stride; /* number of silent bytes */
if (offs + length + extra > ctx->buffer_size)
break;
urb->iso_frame_desc[i].offset = offs;
urb->iso_frame_desc[i].length = length + extra;
if (extra) {
packet_length = cpu_to_le32(length);
memcpy(urb->transfer_buffer + offset,
memcpy(urb->transfer_buffer + offs,
&packet_length, sizeof(packet_length));
offs += extra;
}
memset(urb->transfer_buffer + offset + extra,
memset(urb->transfer_buffer + offs,
ep->silence_value, length);
offs += counts;
offs += length;
}
urb->number_of_packets = ctx->packets;
urb->transfer_buffer_length = offs * ep->stride + ctx->packets * extra;
if (!offs)
return -EPIPE;
urb->number_of_packets = i;
urb->transfer_buffer_length = offs;
ctx->queued = 0;
return 0;
}
/*
@ -332,8 +338,7 @@ static int prepare_outbound_urb(struct snd_usb_endpoint *ep,
if (data_subs && ep->prepare_data_urb)
return ep->prepare_data_urb(data_subs, urb, in_stream_lock);
/* no data provider, so send silence */
prepare_silent_urb(ep, ctx);
break;
return prepare_silent_urb(ep, ctx);
case SND_USB_ENDPOINT_TYPE_SYNC:
if (snd_usb_get_speed(ep->chip->dev) >= USB_SPEED_HIGH) {