
This commit back ports the DPLL related commits from the upstream kernel that are identified by Intel to provide the expected SyncE/GNSS functionality. There are totally 46 back ported commits included the four commits I added are used to resolve the conflicts during back porting. The 0046 patch is cherry picked from kernel-6.9. The 0031-0045 patches are cherry picked from kernel-6.8. The 0001-0030 patches are cherry picked from kernel-6.7. We also change the in-tree ice driver version to 6.6.40-stx.2 from 6.6.40-stx.1. * To fix the conflict of 91e43ca0090b ("ice: fix linking when CONFIG_PTP_1588_CLOCK=n"), we cherry pick 12a5a28b565b ("ice: remove ICE_F_PTP_EXTTS feature flag") and 89776a6a702e ("ice: check netlist before enabling ICE_F_GNSS"). Adjust 12a5a28b565b because 0d1b22367ec2 ("ice: fix pin assignment for E810-T without SMA control") already included the part code of 12a5a28b565b. https://git.yoctoproject.org/linux-yocto/commit/?id=0d1b22367ec2 * Cherry pick 7049fd5df7 ("netlink: specs: remove redundant type keys from attributes in subsets") to fix the the conflict of c3c6ab95c397 ("dpll: spec: add support for pin-dpll signal phase offset/adjust.") * Cherry pick be16574609f1 ("ice: introduce hw->phy_model for handling PTP PHY differences") to fix the confilict of 6db5f2cd9ebb ("ice: dpll:fix output pin capabilities"). Verification: - Build kernel and out of tree modules success for rt and std. - Install success onto a All-in-One lab with rt kernel. - Boot up successfully in the lab. - interfaces are up and pass packets for rt and std. - Check dmesg to see DDP package is loaded successfully and the version is 1.3.36.0 for rt and std, that is same with the OOT ice-1.14.9 driver. - The SyncE/GNSS functionality tests were done by the network team. Story: 2011056 Task: 50797 Change-Id: I715480681c7c43d53b0a0126b34135562e9d02a0 Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
256 lines
9.0 KiB
Diff
256 lines
9.0 KiB
Diff
From 0d3ade390857fb44333de60cadc255a92011d46f Mon Sep 17 00:00:00 2001
|
|
From: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
|
Date: Fri, 19 Jan 2024 14:43:02 +0100
|
|
Subject: [PATCH 36/46] dpll: fix pin dump crash for rebound module
|
|
|
|
When a kernel module is unbound but the pin resources were not entirely
|
|
freed (other kernel module instance of the same PCI device have had kept
|
|
the reference to that pin), and kernel module is again bound, the pin
|
|
properties would not be updated (the properties are only assigned when
|
|
memory for the pin is allocated), prop pointer still points to the
|
|
kernel module memory of the kernel module which was deallocated on the
|
|
unbind.
|
|
|
|
If the pin dump is invoked in this state, the result is a kernel crash.
|
|
Prevent the crash by storing persistent pin properties in dpll subsystem,
|
|
copy the content from the kernel module when pin is allocated, instead of
|
|
using memory of the kernel module.
|
|
|
|
Fixes: 9431063ad323 ("dpll: core: Add DPLL framework base functions")
|
|
Fixes: 9d71b54b65b1 ("dpll: netlink: Add DPLL framework base functions")
|
|
Reviewed-by: Jan Glaza <jan.glaza@intel.com>
|
|
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
|
Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
|
|
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 830ead5fb0c5855ce4d70ba2ed4a673b5f1e7d9b)
|
|
Signed-off-by: Jiping Ma <jiping.ma2@windriver.com>
|
|
---
|
|
drivers/dpll/dpll_core.c | 55 +++++++++++++++++++++++++++++++++++--
|
|
drivers/dpll/dpll_core.h | 4 +--
|
|
drivers/dpll/dpll_netlink.c | 28 +++++++++----------
|
|
3 files changed, 69 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c
|
|
index c08772ee9fd6..cb62696467d1 100644
|
|
--- a/drivers/dpll/dpll_core.c
|
|
+++ b/drivers/dpll/dpll_core.c
|
|
@@ -425,6 +425,53 @@ void dpll_device_unregister(struct dpll_device *dpll,
|
|
}
|
|
EXPORT_SYMBOL_GPL(dpll_device_unregister);
|
|
|
|
+static void dpll_pin_prop_free(struct dpll_pin_properties *prop)
|
|
+{
|
|
+ kfree(prop->package_label);
|
|
+ kfree(prop->panel_label);
|
|
+ kfree(prop->board_label);
|
|
+ kfree(prop->freq_supported);
|
|
+}
|
|
+
|
|
+static int dpll_pin_prop_dup(const struct dpll_pin_properties *src,
|
|
+ struct dpll_pin_properties *dst)
|
|
+{
|
|
+ memcpy(dst, src, sizeof(*dst));
|
|
+ if (src->freq_supported && src->freq_supported_num) {
|
|
+ size_t freq_size = src->freq_supported_num *
|
|
+ sizeof(*src->freq_supported);
|
|
+ dst->freq_supported = kmemdup(src->freq_supported,
|
|
+ freq_size, GFP_KERNEL);
|
|
+ if (!src->freq_supported)
|
|
+ return -ENOMEM;
|
|
+ }
|
|
+ if (src->board_label) {
|
|
+ dst->board_label = kstrdup(src->board_label, GFP_KERNEL);
|
|
+ if (!dst->board_label)
|
|
+ goto err_board_label;
|
|
+ }
|
|
+ if (src->panel_label) {
|
|
+ dst->panel_label = kstrdup(src->panel_label, GFP_KERNEL);
|
|
+ if (!dst->panel_label)
|
|
+ goto err_panel_label;
|
|
+ }
|
|
+ if (src->package_label) {
|
|
+ dst->package_label = kstrdup(src->package_label, GFP_KERNEL);
|
|
+ if (!dst->package_label)
|
|
+ goto err_package_label;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+
|
|
+err_package_label:
|
|
+ kfree(dst->panel_label);
|
|
+err_panel_label:
|
|
+ kfree(dst->board_label);
|
|
+err_board_label:
|
|
+ kfree(dst->freq_supported);
|
|
+ return -ENOMEM;
|
|
+}
|
|
+
|
|
static struct dpll_pin *
|
|
dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
|
const struct dpll_pin_properties *prop)
|
|
@@ -443,7 +490,9 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
|
ret = -EINVAL;
|
|
goto err_pin_prop;
|
|
}
|
|
- pin->prop = prop;
|
|
+ ret = dpll_pin_prop_dup(prop, &pin->prop);
|
|
+ if (ret)
|
|
+ goto err_pin_prop;
|
|
refcount_set(&pin->refcount, 1);
|
|
xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC);
|
|
xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC);
|
|
@@ -455,6 +504,7 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
|
|
err_xa_alloc:
|
|
xa_destroy(&pin->dpll_refs);
|
|
xa_destroy(&pin->parent_refs);
|
|
+ dpll_pin_prop_free(&pin->prop);
|
|
err_pin_prop:
|
|
kfree(pin);
|
|
return ERR_PTR(ret);
|
|
@@ -515,6 +565,7 @@ void dpll_pin_put(struct dpll_pin *pin)
|
|
xa_destroy(&pin->dpll_refs);
|
|
xa_destroy(&pin->parent_refs);
|
|
xa_erase(&dpll_pin_xa, pin->id);
|
|
+ dpll_pin_prop_free(&pin->prop);
|
|
kfree(pin);
|
|
}
|
|
mutex_unlock(&dpll_lock);
|
|
@@ -637,7 +688,7 @@ int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin,
|
|
unsigned long i, stop;
|
|
int ret;
|
|
|
|
- if (WARN_ON(parent->prop->type != DPLL_PIN_TYPE_MUX))
|
|
+ if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX))
|
|
return -EINVAL;
|
|
|
|
if (WARN_ON(!ops) ||
|
|
diff --git a/drivers/dpll/dpll_core.h b/drivers/dpll/dpll_core.h
|
|
index 5585873c5c1b..717f715015c7 100644
|
|
--- a/drivers/dpll/dpll_core.h
|
|
+++ b/drivers/dpll/dpll_core.h
|
|
@@ -44,7 +44,7 @@ struct dpll_device {
|
|
* @module: module of creator
|
|
* @dpll_refs: hold referencees to dplls pin was registered with
|
|
* @parent_refs: hold references to parent pins pin was registered with
|
|
- * @prop: pointer to pin properties given by registerer
|
|
+ * @prop: pin properties copied from the registerer
|
|
* @rclk_dev_name: holds name of device when pin can recover clock from it
|
|
* @refcount: refcount
|
|
**/
|
|
@@ -55,7 +55,7 @@ struct dpll_pin {
|
|
struct module *module;
|
|
struct xarray dpll_refs;
|
|
struct xarray parent_refs;
|
|
- const struct dpll_pin_properties *prop;
|
|
+ struct dpll_pin_properties prop;
|
|
refcount_t refcount;
|
|
};
|
|
|
|
diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
|
|
index ce7cf736f020..4c64611d32ac 100644
|
|
--- a/drivers/dpll/dpll_netlink.c
|
|
+++ b/drivers/dpll/dpll_netlink.c
|
|
@@ -278,17 +278,17 @@ dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
|
|
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY, sizeof(freq), &freq,
|
|
DPLL_A_PIN_PAD))
|
|
return -EMSGSIZE;
|
|
- for (fs = 0; fs < pin->prop->freq_supported_num; fs++) {
|
|
+ for (fs = 0; fs < pin->prop.freq_supported_num; fs++) {
|
|
nest = nla_nest_start(msg, DPLL_A_PIN_FREQUENCY_SUPPORTED);
|
|
if (!nest)
|
|
return -EMSGSIZE;
|
|
- freq = pin->prop->freq_supported[fs].min;
|
|
+ freq = pin->prop.freq_supported[fs].min;
|
|
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN, sizeof(freq),
|
|
&freq, DPLL_A_PIN_PAD)) {
|
|
nla_nest_cancel(msg, nest);
|
|
return -EMSGSIZE;
|
|
}
|
|
- freq = pin->prop->freq_supported[fs].max;
|
|
+ freq = pin->prop.freq_supported[fs].max;
|
|
if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX, sizeof(freq),
|
|
&freq, DPLL_A_PIN_PAD)) {
|
|
nla_nest_cancel(msg, nest);
|
|
@@ -304,9 +304,9 @@ static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
|
|
{
|
|
int fs;
|
|
|
|
- for (fs = 0; fs < pin->prop->freq_supported_num; fs++)
|
|
- if (freq >= pin->prop->freq_supported[fs].min &&
|
|
- freq <= pin->prop->freq_supported[fs].max)
|
|
+ for (fs = 0; fs < pin->prop.freq_supported_num; fs++)
|
|
+ if (freq >= pin->prop.freq_supported[fs].min &&
|
|
+ freq <= pin->prop.freq_supported[fs].max)
|
|
return true;
|
|
return false;
|
|
}
|
|
@@ -396,7 +396,7 @@ static int
|
|
dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
|
|
struct netlink_ext_ack *extack)
|
|
{
|
|
- const struct dpll_pin_properties *prop = pin->prop;
|
|
+ const struct dpll_pin_properties *prop = &pin->prop;
|
|
struct dpll_pin_ref *ref;
|
|
int ret;
|
|
|
|
@@ -689,7 +689,7 @@ dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
|
|
int ret;
|
|
|
|
if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
|
|
- pin->prop->capabilities)) {
|
|
+ pin->prop.capabilities)) {
|
|
NL_SET_ERR_MSG(extack, "state changing is not allowed");
|
|
return -EOPNOTSUPP;
|
|
}
|
|
@@ -725,7 +725,7 @@ dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
|
|
int ret;
|
|
|
|
if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
|
|
- pin->prop->capabilities)) {
|
|
+ pin->prop.capabilities)) {
|
|
NL_SET_ERR_MSG(extack, "state changing is not allowed");
|
|
return -EOPNOTSUPP;
|
|
}
|
|
@@ -752,7 +752,7 @@ dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin,
|
|
int ret;
|
|
|
|
if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE &
|
|
- pin->prop->capabilities)) {
|
|
+ pin->prop.capabilities)) {
|
|
NL_SET_ERR_MSG(extack, "prio changing is not allowed");
|
|
return -EOPNOTSUPP;
|
|
}
|
|
@@ -780,7 +780,7 @@ dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll,
|
|
int ret;
|
|
|
|
if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE &
|
|
- pin->prop->capabilities)) {
|
|
+ pin->prop.capabilities)) {
|
|
NL_SET_ERR_MSG(extack, "direction changing is not allowed");
|
|
return -EOPNOTSUPP;
|
|
}
|
|
@@ -810,8 +810,8 @@ dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr,
|
|
int ret;
|
|
|
|
phase_adj = nla_get_s32(phase_adj_attr);
|
|
- if (phase_adj > pin->prop->phase_range.max ||
|
|
- phase_adj < pin->prop->phase_range.min) {
|
|
+ if (phase_adj > pin->prop.phase_range.max ||
|
|
+ phase_adj < pin->prop.phase_range.min) {
|
|
NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr,
|
|
"phase adjust value not supported");
|
|
return -EINVAL;
|
|
@@ -995,7 +995,7 @@ dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
|
|
unsigned long i;
|
|
|
|
xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) {
|
|
- prop = pin->prop;
|
|
+ prop = &pin->prop;
|
|
cid_match = clock_id ? pin->clock_id == clock_id : true;
|
|
mod_match = mod_name_attr && module_name(pin->module) ?
|
|
!nla_strcmp(mod_name_attr,
|
|
--
|
|
2.43.0
|
|
|