From: Markus Probst <markus.probst@posteo.de>
To: "Ayush Singh" <ayush@beagleboard.org>,
"Johan Hovold" <johan@kernel.org>,
"Alex Elder" <elder@kernel.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <lossin@kernel.org>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Daniel Almeida" <daniel.almeida@collabora.com>,
"Tamir Duberstein" <tamird@kernel.org>,
"Alexandre Courbot" <acourbot@nvidia.com>,
"Onur Özkan" <work@onurozkan.dev>,
"Eric Biggers" <ebiggers@kernel.org>,
"Ard Biesheuvel" <ardb@kernel.org>,
"Lorenzo Stoakes" <ljs@kernel.org>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
"Uladzislau Rezki" <urezki@gmail.com>,
"Jiri Slaby" <jirislaby@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>
Cc: greybus-dev@lists.linaro.org, linux-serial@vger.kernel.org,
rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
driver-core@lists.linux.dev,
Markus Probst <markus.probst@posteo.de>
Subject: [PATCH v3 1/4] tty: serdev: Add mutex lock
Date: Wed, 30 Sep 2026 17:32:27 +0000 [thread overview]
Message-ID: <20260930-rust_serdev_probe_refactor-v3-1-d1b6e77135e0@posteo.de> (raw)
In-Reply-To: <20260930-rust_serdev_probe_refactor-v3-0-d1b6e77135e0@posteo.de>
Besides more predictable behaviour, this allows for several hardened
behaviour changes:
Return -EALREADY in `serdev_device_open` if the device is already open
instead of causing undefined behaviour.
Allow calling `serdev_device_close`, even if the device is already
closed instead of causing a null pointer dereference.
If the device is left open by the driver after remove, close it and warn
instead of leaving it in a invalid state.
Signed-off-by: Markus Probst <markus.probst@posteo.de>
---
drivers/tty/serdev/core.c | 10 +++++++---
drivers/tty/serdev/serdev-ttyport.c | 35 +++++++++++++++++++++++++++++------
include/linux/serdev.h | 2 +-
3 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 7500efcdfc21..77e8e1d4d2a6 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -142,6 +142,11 @@ void serdev_device_remove(struct serdev_device *serdev)
struct serdev_controller *ctrl = serdev->ctrl;
device_unregister(&serdev->dev);
+
+ /* Warn if driver did not close the serial device. */
+ if (ctrl->ops->close && WARN_ON(ctrl->ops->close(ctrl)))
+ pm_runtime_put(&ctrl->dev);
+
ctrl->serdev = NULL;
}
EXPORT_SYMBOL_GPL(serdev_device_remove);
@@ -181,9 +186,8 @@ void serdev_device_close(struct serdev_device *serdev)
if (!ctrl || !ctrl->ops->close)
return;
- pm_runtime_put(&ctrl->dev);
-
- ctrl->ops->close(ctrl);
+ if (ctrl->ops->close(ctrl))
+ pm_runtime_put(&ctrl->dev);
}
EXPORT_SYMBOL_GPL(serdev_device_close);
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index bab1b143b8a6..c11908f5e1ce 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -16,6 +16,7 @@ struct serport {
struct tty_driver *tty_drv;
int tty_idx;
unsigned long flags;
+ struct mutex lock; /* lock preventing modification of flags */
};
/*
@@ -29,6 +30,8 @@ static size_t ttyport_receive_buf(struct tty_port *port, const u8 *cp,
struct serport *serport = serdev_controller_get_drvdata(ctrl);
size_t ret;
+ guard(mutex)(&serport->lock);
+
if (!test_bit(SERPORT_ACTIVE, &serport->flags))
return 0;
@@ -99,14 +102,23 @@ static int ttyport_open(struct serdev_controller *ctrl)
struct ktermios ktermios;
int ret;
+ mutex_lock(&serport->lock);
+
+ if (test_bit(SERPORT_ACTIVE, &serport->flags)) {
+ ret = -EALREADY;
+ goto err_flags_unlock;
+ }
+
tty = tty_init_dev(serport->tty_drv, serport->tty_idx);
- if (IS_ERR(tty))
- return PTR_ERR(tty);
+ if (IS_ERR(tty)) {
+ ret = PTR_ERR(tty);
+ goto err_flags_unlock;
+ }
serport->tty = tty;
if (!tty->ops->open || !tty->ops->close) {
ret = -ENODEV;
- goto err_unlock;
+ goto err_tty_unlock;
}
ret = tty->ops->open(serport->tty, NULL);
@@ -130,23 +142,30 @@ static int ttyport_open(struct serdev_controller *ctrl)
set_bit(SERPORT_ACTIVE, &serport->flags);
+ mutex_unlock(&serport->lock);
+
return 0;
err_close:
tty->ops->close(tty, NULL);
-err_unlock:
+err_tty_unlock:
tty_unlock(tty);
tty_release_struct(tty, serport->tty_idx);
+err_flags_unlock:
+ mutex_unlock(&serport->lock);
return ret;
}
-static void ttyport_close(struct serdev_controller *ctrl)
+static bool ttyport_close(struct serdev_controller *ctrl)
{
struct serport *serport = serdev_controller_get_drvdata(ctrl);
struct tty_struct *tty = serport->tty;
- clear_bit(SERPORT_ACTIVE, &serport->flags);
+ guard(mutex)(&serport->lock);
+
+ if (!__test_and_clear_bit(SERPORT_ACTIVE, &serport->flags))
+ return false;
tty_lock(tty);
if (tty->ops->close)
@@ -154,6 +173,8 @@ static void ttyport_close(struct serdev_controller *ctrl)
tty_unlock(tty);
tty_release_struct(tty, serport->tty_idx);
+
+ return true;
}
static unsigned int ttyport_set_baudrate(struct serdev_controller *ctrl, unsigned int speed)
@@ -288,6 +309,8 @@ struct device *serdev_tty_port_register(struct tty_port *port,
port->client_ops = &client_ops;
port->client_data = ctrl;
+ mutex_init(&serport->lock);
+
ret = serdev_controller_add(ctrl);
if (ret)
goto err_reset_data;
diff --git a/include/linux/serdev.h b/include/linux/serdev.h
index b6c3d957ec15..0f4e81c0950d 100644
--- a/include/linux/serdev.h
+++ b/include/linux/serdev.h
@@ -81,7 +81,7 @@ struct serdev_controller_ops {
ssize_t (*write_buf)(struct serdev_controller *, const u8 *, size_t);
void (*write_flush)(struct serdev_controller *);
int (*open)(struct serdev_controller *);
- void (*close)(struct serdev_controller *);
+ bool (*close)(struct serdev_controller *);
void (*set_flow_control)(struct serdev_controller *, bool);
int (*set_parity)(struct serdev_controller *, enum serdev_parity);
unsigned int (*set_baudrate)(struct serdev_controller *, unsigned int);
--
2.55.0
next prev parent reply other threads:[~2026-09-30 17:32 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-30 17:32 [PATCH v3 0/4] rust: serdev: Refactor Markus Probst
2026-09-30 17:32 ` Markus Probst [this message]
2026-09-30 17:50 ` [PATCH v3 1/4] tty: serdev: Add mutex lock sashiko-bot
2026-09-30 17:32 ` [PATCH v3 2/4] tty: serdev: Export functions to pause receive_buf callback calls Markus Probst
2026-09-30 17:41 ` Markus Probst
2026-09-30 17:43 ` sashiko-bot
2026-09-30 17:48 ` Markus Probst
2026-09-30 17:32 ` [PATCH v3 3/4] rust: serdev: Replace `active` mutex with receive pause Markus Probst
2026-09-30 17:42 ` sashiko-bot
2026-09-30 17:32 ` [PATCH v3 4/4] rust: serdev: Simplify callbacks Markus Probst
2026-09-30 17:53 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260930-rust_serdev_probe_refactor-v3-1-d1b6e77135e0@posteo.de \
--to=markus.probst@posteo.de \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=ardb@kernel.org \
--cc=ayush@beagleboard.org \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=driver-core@lists.linux.dev \
--cc=ebiggers@kernel.org \
--cc=elder@kernel.org \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=greybus-dev@lists.linaro.org \
--cc=jirislaby@kernel.org \
--cc=johan@kernel.org \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=urezki@gmail.com \
--cc=vbabka@kernel.org \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.