From: Franz Schnyder <franz.schnyder(a)toradex.com>
Currently, the PHY only registers the typec orientation switch when it
is built in. If the typec driver is built as a module, the switch
registration is skipped due to the preprocessor condition, causing
orientation detection to fail.
With commit
45fe729be9a6 ("usb: typec: Stub out typec_switch APIs when CONFIG_TYPEC=n")
the preprocessor condition is not needed anymore and the orientation
switch is correctly registered for both built-in and module builds.
Fixes: b58f0f86fd61 ("phy: fsl-imx8mq-usb: add tca function driver for imx95")
Cc: stable(a)vger.kernel.org
Suggested-by: Xu Yang <xu.yang_2(a)nxp.com>
Signed-off-by: Franz Schnyder <franz.schnyder(a)toradex.com>
---
v2: Drop the preprocessor condition after a better suggestion.
Reviewed-by Neil tag not added as patch is different
---
drivers/phy/freescale/phy-fsl-imx8mq-usb.c | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
index b94f242420fc..72e8aff38b92 100644
--- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
+++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c
@@ -124,8 +124,6 @@ struct imx8mq_usb_phy {
static void tca_blk_orientation_set(struct tca_blk *tca,
enum typec_orientation orientation);
-#ifdef CONFIG_TYPEC
-
static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
enum typec_orientation orientation)
{
@@ -173,18 +171,6 @@ static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
typec_switch_unregister(sw);
}
-#else
-
-static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
- struct imx8mq_usb_phy *imx_phy)
-{
- return NULL;
-}
-
-static void tca_blk_put_typec_switch(struct typec_switch_dev *sw) {}
-
-#endif /* CONFIG_TYPEC */
-
static void tca_blk_orientation_set(struct tca_blk *tca,
enum typec_orientation orientation)
{
--
2.43.0
kstack_offset was previously maintained per-cpu, but this caused a
couple of issues. So let's instead make it per-task.
Issue 1: add_random_kstack_offset() and choose_random_kstack_offset()
expected and required to be called with interrupts and preemption
disabled so that it could manipulate per-cpu state. But arm64, loongarch
and risc-v are calling them with interrupts and preemption enabled. I
don't _think_ this causes any functional issues, but it's certainly
unexpected and could lead to manipulating the wrong cpu's state, which
could cause a minor performance degradation due to bouncing the cache
lines. By maintaining the state per-task those functions can safely be
called in preemptible context.
Issue 2: add_random_kstack_offset() is called before executing the
syscall and expands the stack using a previously chosen rnadom offset.
choose_random_kstack_offset() is called after executing the syscall and
chooses and stores a new random offset for the next syscall. With
per-cpu storage for this offset, an attacker could force cpu migration
during the execution of the syscall and prevent the offset from being
updated for the original cpu such that it is predictable for the next
syscall on that cpu. By maintaining the state per-task, this problem
goes away because the per-task random offset is updated after the
syscall regardless of which cpu it is executing on.
Fixes: 39218ff4c625 ("stack: Optionally randomize kernel stack offset each syscall")
Closes: https://lore.kernel.org/all/dd8c37bc-795f-4c7a-9086-69e584d8ab24@arm.com/
Cc: stable(a)vger.kernel.org
Signed-off-by: Ryan Roberts <ryan.roberts(a)arm.com>
---
include/linux/randomize_kstack.h | 26 +++++++++++++++-----------
include/linux/sched.h | 4 ++++
init/main.c | 1 -
kernel/fork.c | 2 ++
4 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/include/linux/randomize_kstack.h b/include/linux/randomize_kstack.h
index 1d982dbdd0d0..089b1432f7e6 100644
--- a/include/linux/randomize_kstack.h
+++ b/include/linux/randomize_kstack.h
@@ -9,7 +9,6 @@
DECLARE_STATIC_KEY_MAYBE(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT,
randomize_kstack_offset);
-DECLARE_PER_CPU(u32, kstack_offset);
/*
* Do not use this anywhere else in the kernel. This is used here because
@@ -50,15 +49,14 @@ DECLARE_PER_CPU(u32, kstack_offset);
* add_random_kstack_offset - Increase stack utilization by previously
* chosen random offset
*
- * This should be used in the syscall entry path when interrupts and
- * preempt are disabled, and after user registers have been stored to
- * the stack. For testing the resulting entropy, please see:
- * tools/testing/selftests/lkdtm/stack-entropy.sh
+ * This should be used in the syscall entry path after user registers have been
+ * stored to the stack. Preemption may be enabled. For testing the resulting
+ * entropy, please see: tools/testing/selftests/lkdtm/stack-entropy.sh
*/
#define add_random_kstack_offset() do { \
if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, \
&randomize_kstack_offset)) { \
- u32 offset = raw_cpu_read(kstack_offset); \
+ u32 offset = current->kstack_offset; \
u8 *ptr = __kstack_alloca(KSTACK_OFFSET_MAX(offset)); \
/* Keep allocation even after "ptr" loses scope. */ \
asm volatile("" :: "r"(ptr) : "memory"); \
@@ -69,9 +67,9 @@ DECLARE_PER_CPU(u32, kstack_offset);
* choose_random_kstack_offset - Choose the random offset for the next
* add_random_kstack_offset()
*
- * This should only be used during syscall exit when interrupts and
- * preempt are disabled. This position in the syscall flow is done to
- * frustrate attacks from userspace attempting to learn the next offset:
+ * This should only be used during syscall exit. Preemption may be enabled. This
+ * position in the syscall flow is done to frustrate attacks from userspace
+ * attempting to learn the next offset:
* - Maximize the timing uncertainty visible from userspace: if the
* offset is chosen at syscall entry, userspace has much more control
* over the timing between choosing offsets. "How long will we be in
@@ -85,14 +83,20 @@ DECLARE_PER_CPU(u32, kstack_offset);
#define choose_random_kstack_offset(rand) do { \
if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, \
&randomize_kstack_offset)) { \
- u32 offset = raw_cpu_read(kstack_offset); \
+ u32 offset = current->kstack_offset; \
offset = ror32(offset, 5) ^ (rand); \
- raw_cpu_write(kstack_offset, offset); \
+ current->kstack_offset = offset; \
} \
} while (0)
+
+static inline void random_kstack_task_init(struct task_struct *tsk)
+{
+ current->kstack_offset = 0;
+}
#else /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
#define add_random_kstack_offset() do { } while (0)
#define choose_random_kstack_offset(rand) do { } while (0)
+#define random_kstack_task_init(tsk) do { } while (0)
#endif /* CONFIG_RANDOMIZE_KSTACK_OFFSET */
#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b469878de25c..dae227d217ef 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1613,6 +1613,10 @@ struct task_struct {
unsigned long prev_lowest_stack;
#endif
+#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
+ u32 kstack_offset;
+#endif
+
#ifdef CONFIG_X86_MCE
void __user *mce_vaddr;
__u64 mce_kflags;
diff --git a/init/main.c b/init/main.c
index 07a3116811c5..048a62538242 100644
--- a/init/main.c
+++ b/init/main.c
@@ -830,7 +830,6 @@ static inline void initcall_debug_enable(void)
#ifdef CONFIG_RANDOMIZE_KSTACK_OFFSET
DEFINE_STATIC_KEY_MAYBE_RO(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT,
randomize_kstack_offset);
-DEFINE_PER_CPU(u32, kstack_offset);
static int __init early_randomize_kstack_offset(char *buf)
{
diff --git a/kernel/fork.c b/kernel/fork.c
index 3da0f08615a9..c0dced542b8a 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -95,6 +95,7 @@
#include <linux/thread_info.h>
#include <linux/kstack_erase.h>
#include <linux/kasan.h>
+#include <linux/randomize_kstack.h>
#include <linux/scs.h>
#include <linux/io_uring.h>
#include <linux/bpf.h>
@@ -2191,6 +2192,7 @@ __latent_entropy struct task_struct *copy_process(
if (retval)
goto bad_fork_cleanup_io;
+ random_kstack_task_init(p);
stackleak_task_init(p);
if (pid != &init_struct_pid) {
--
2.43.0
The USB OTG port of the RK3308 exibits a bug when:
- configured as peripheral, and
- used in gadget mode, and
- the USB cable is connected since before booting
The symptom is: about 6 seconds after configuring gadget mode the device is
disconnected and then re-enumerated. This happens only once per boot.
Investigation showed that in this configuration the charger detection code
turns off the PHY after 6 seconds. Patch 1 avoids this when a cable is
connected (VBUS present).
After patch 1 the connection is stable but communication stops after 6
seconds. this is addressed by patch 2.
The topic had been discussed in [0]. Thanks Alan and Minas for the
discussion and Louis for having found the 1st issue, leading to patch 1.
[0] https://lore.kernel.org/lkml/20250414185458.7767aabc@booty/
Luca
Signed-off-by: Luca Ceresoli <luca.ceresoli(a)bootlin.com>
---
Changes in v2:
- Patch 1: Fixed Co-developed-by: and SoB line order
- Added missing Cc: stable(a)vger.kernel.org
- Added Théo's Reviewed-by
- Improved commit message
- Patch 2: trimmed discussion about "there is no disconnection" from
commit message to not distract from the actual issue (writes to
chg_det.opmode)
- Link to v1: https://lore.kernel.org/r/20250722-rk3308-fix-usb-gadget-phy-disconnect-v1-…
---
Louis Chauvet (1):
phy: rockchip: inno-usb2: fix disconnection in gadget mode
Luca Ceresoli (1):
phy: rockchip: inno-usb2: fix communication disruption in gadget mode
drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
---
base-commit: cabb748c4b98ef67bbb088be61a2e0c850ebf70d
change-id: 20250718-rk3308-fix-usb-gadget-phy-disconnect-d7de71fb28b4
Best regards,
--
Luca Ceresoli <luca.ceresoli(a)bootlin.com>
Set CLK_IGNORE_UNUSED flag to clock adsp audio26m to prevent disabling
this clock during early boot, as turning it off causes other modules
to fail probing and leads to boot failures in ARM SystemReady test cases
and the EFI boot process (on Linux Distributions, for example, debian,
openSuse, etc.). Without this flag, disabling unused clocks cannot
complete properly after adsp_audio26m is turned off.
Fixes: 0d2f2cefba64 ("clk: mediatek: Add MT8188 adsp clock support")
Cc: Stable(a)vger.kernel.org
Signed-off-by: Macpaul Lin <macpaul.lin(a)mediatek.com>
---
drivers/clk/mediatek/clk-mt8188-adsp_audio26m.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/mediatek/clk-mt8188-adsp_audio26m.c b/drivers/clk/mediatek/clk-mt8188-adsp_audio26m.c
index dcde2187d24a..b9fe66ef4f2e 100644
--- a/drivers/clk/mediatek/clk-mt8188-adsp_audio26m.c
+++ b/drivers/clk/mediatek/clk-mt8188-adsp_audio26m.c
@@ -20,8 +20,8 @@ static const struct mtk_gate_regs adsp_audio26m_cg_regs = {
};
#define GATE_ADSP_FLAGS(_id, _name, _parent, _shift) \
- GATE_MTK(_id, _name, _parent, &adsp_audio26m_cg_regs, _shift, \
- &mtk_clk_gate_ops_no_setclr)
+ GATE_MTK_FLAGS(_id, _name, _parent, &adsp_audio26m_cg_regs, _shift, \
+ &mtk_clk_gate_ops_no_setclr, CLK_IGNORE_UNUSED)
static const struct mtk_gate adsp_audio26m_clks[] = {
GATE_ADSP_FLAGS(CLK_AUDIODSP_AUDIO26M, "audiodsp_audio26m", "clk26m", 3),
--
2.45.2
Dzień dobry,
pomagamy przedsiębiorcom wprowadzić model wymiany walut, który minimalizuje wahania kosztów przy rozliczeniach międzynarodowych.
Kiedyv możemy umówić się na 15-minutową rozmowę, aby zaprezentować, jak taki model mógłby działać w Państwa firmie - z gwarancją indywidualnych kursów i pełnym uproszczeniem płatności? Proszę o propozycję dogodnego terminu.
Pozdrawiam
Marek Poradecki
From: Francesco Dolcini <francesco.dolcini(a)toradex.com>
This reverts commit ad5c6ecef27e ("drm: bridge: ti-sn65dsi83: Add error
recovery mechanism").
The reverted commit introduces a regression on Verdin AM62, and
potentially on more devices, not being able to generate a clock
that the TI SN65DSI83 PLL can lock to, with the display periodically
blinking.
Verdin AM62 SoM has a Toshiba TC358778 DPI to DSI bridge, that can be
connected to an LVDS display over a TI SN65DSI83 bridge. Before this
change despite the TI SN65DSI83 reporting with a debug print a PLL
locking error the display was working fine with no visible glitches.
The reasons for this issue was investigated without getting to a final
conclusion:
- the DPI clock was measure and it is stable/accurate
- the DSI clock was not possible to measure, but this setup is used
with other display/bridges with no known issues
- the DSI clock is configured in continuous mode
- the actual DSI clock generated from the TC358778 is generate with a
PLL from a 25MHz reference clock
- it's not clear why some frequencies are working and some are not, for
example 50000000, 68750000, 72750000, 75000000 frequencies are fine,
while 69750000, 71100000, 72500000 are not
Given that the safest approach is to just revert the commit, till a
proper solution for error recovery that is not introducing regression
is figured out.
Reported-by: João Paulo Gonçalves <jpaulo.silvagoncalves(a)gmail.com>
Closes: https://lore.kernel.org/all/bhkn6hley4xrol5o3ytn343h4unkwsr26p6s6ltcwexnrsj…
Fixes: ad5c6ecef27e ("drm: bridge: ti-sn65dsi83: Add error recovery mechanism")
Cc: stable(a)vger.kernel.org
Signed-off-by: Francesco Dolcini <francesco.dolcini(a)toradex.com>
---
Cc: Herve Codina <herve.codina(a)bootlin.com>
Cc: Tomi Valkeinen <tomi.valkeinen(a)ideasonboard.com>
Cc: Luca Ceresoli <luca.ceresoli(a)bootlin.com>
Cc: Maxime Ripard <mripard(a)kernel.org>
Cc: Emanuele Ghidoli <emanuele.ghidoli(a)toradex.com>
---
drivers/gpu/drm/bridge/ti-sn65dsi83.c | 136 --------------------------
1 file changed, 136 deletions(-)
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index 033c44326552..cf627aff569b 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -35,12 +35,9 @@
#include <linux/of_graph.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
-#include <linux/timer.h>
-#include <linux/workqueue.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
-#include <drm/drm_bridge_helper.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_of.h>
#include <drm/drm_print.h>
@@ -161,9 +158,6 @@ struct sn65dsi83 {
bool lvds_dual_link_even_odd_swap;
int lvds_vod_swing_conf[2];
int lvds_term_conf[2];
- int irq;
- struct delayed_work monitor_work;
- struct work_struct reset_work;
};
static const struct regmap_range sn65dsi83_readable_ranges[] = {
@@ -369,100 +363,6 @@ static u8 sn65dsi83_get_dsi_div(struct sn65dsi83 *ctx)
return dsi_div - 1;
}
-static int sn65dsi83_reset_pipe(struct sn65dsi83 *sn65dsi83)
-{
- struct drm_modeset_acquire_ctx ctx;
- int err;
-
- /*
- * Reset active outputs of the related CRTC.
- *
- * This way, drm core will reconfigure each components in the CRTC
- * outputs path. In our case, this will force the previous component to
- * go back in LP11 mode and so allow the reconfiguration of SN65DSI83
- * bridge.
- *
- * Keep the lock during the whole operation to be atomic.
- */
-
- drm_modeset_acquire_init(&ctx, 0);
-
- dev_warn(sn65dsi83->dev, "reset the pipe\n");
-
-retry:
- err = drm_bridge_helper_reset_crtc(&sn65dsi83->bridge, &ctx);
- if (err == -EDEADLK) {
- drm_modeset_backoff(&ctx);
- goto retry;
- }
-
- drm_modeset_drop_locks(&ctx);
- drm_modeset_acquire_fini(&ctx);
-
- return 0;
-}
-
-static void sn65dsi83_reset_work(struct work_struct *ws)
-{
- struct sn65dsi83 *ctx = container_of(ws, struct sn65dsi83, reset_work);
- int ret;
-
- /* Reset the pipe */
- ret = sn65dsi83_reset_pipe(ctx);
- if (ret) {
- dev_err(ctx->dev, "reset pipe failed %pe\n", ERR_PTR(ret));
- return;
- }
- if (ctx->irq)
- enable_irq(ctx->irq);
-}
-
-static void sn65dsi83_handle_errors(struct sn65dsi83 *ctx)
-{
- unsigned int irq_stat;
- int ret;
-
- /*
- * Schedule a reset in case of:
- * - the bridge doesn't answer
- * - the bridge signals an error
- */
-
- ret = regmap_read(ctx->regmap, REG_IRQ_STAT, &irq_stat);
- if (ret || irq_stat) {
- /*
- * IRQ acknowledged is not always possible (the bridge can be in
- * a state where it doesn't answer anymore). To prevent an
- * interrupt storm, disable interrupt. The interrupt will be
- * after the reset.
- */
- if (ctx->irq)
- disable_irq_nosync(ctx->irq);
-
- schedule_work(&ctx->reset_work);
- }
-}
-
-static void sn65dsi83_monitor_work(struct work_struct *work)
-{
- struct sn65dsi83 *ctx = container_of(to_delayed_work(work),
- struct sn65dsi83, monitor_work);
-
- sn65dsi83_handle_errors(ctx);
-
- schedule_delayed_work(&ctx->monitor_work, msecs_to_jiffies(1000));
-}
-
-static void sn65dsi83_monitor_start(struct sn65dsi83 *ctx)
-{
- schedule_delayed_work(&ctx->monitor_work, msecs_to_jiffies(1000));
-}
-
-static void sn65dsi83_monitor_stop(struct sn65dsi83 *ctx)
-{
- cancel_delayed_work_sync(&ctx->monitor_work);
-}
-
static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
@@ -650,15 +550,6 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
regmap_read(ctx->regmap, REG_IRQ_STAT, &pval);
if (pval)
dev_err(ctx->dev, "Unexpected link status 0x%02x\n", pval);
-
- if (ctx->irq) {
- /* Enable irq to detect errors */
- regmap_write(ctx->regmap, REG_IRQ_GLOBAL, REG_IRQ_GLOBAL_IRQ_EN);
- regmap_write(ctx->regmap, REG_IRQ_EN, 0xff);
- } else {
- /* Use the polling task */
- sn65dsi83_monitor_start(ctx);
- }
}
static void sn65dsi83_atomic_disable(struct drm_bridge *bridge,
@@ -667,15 +558,6 @@ static void sn65dsi83_atomic_disable(struct drm_bridge *bridge,
struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
int ret;
- if (ctx->irq) {
- /* Disable irq */
- regmap_write(ctx->regmap, REG_IRQ_EN, 0x0);
- regmap_write(ctx->regmap, REG_IRQ_GLOBAL, 0x0);
- } else {
- /* Stop the polling task */
- sn65dsi83_monitor_stop(ctx);
- }
-
/* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */
gpiod_set_value_cansleep(ctx->enable_gpio, 0);
usleep_range(10000, 11000);
@@ -925,14 +807,6 @@ static int sn65dsi83_host_attach(struct sn65dsi83 *ctx)
return 0;
}
-static irqreturn_t sn65dsi83_irq(int irq, void *data)
-{
- struct sn65dsi83 *ctx = data;
-
- sn65dsi83_handle_errors(ctx);
- return IRQ_HANDLED;
-}
-
static int sn65dsi83_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_client_get_device_id(client);
@@ -946,8 +820,6 @@ static int sn65dsi83_probe(struct i2c_client *client)
return PTR_ERR(ctx);
ctx->dev = dev;
- INIT_WORK(&ctx->reset_work, sn65dsi83_reset_work);
- INIT_DELAYED_WORK(&ctx->monitor_work, sn65dsi83_monitor_work);
if (dev->of_node) {
model = (enum sn65dsi83_model)(uintptr_t)
@@ -972,14 +844,6 @@ static int sn65dsi83_probe(struct i2c_client *client)
if (IS_ERR(ctx->regmap))
return dev_err_probe(dev, PTR_ERR(ctx->regmap), "failed to get regmap\n");
- if (client->irq) {
- ctx->irq = client->irq;
- ret = devm_request_threaded_irq(ctx->dev, ctx->irq, NULL, sn65dsi83_irq,
- IRQF_ONESHOT, dev_name(ctx->dev), ctx);
- if (ret)
- return dev_err_probe(dev, ret, "failed to request irq\n");
- }
-
dev_set_drvdata(dev, ctx);
i2c_set_clientdata(client, ctx);
--
2.47.3