Link: https://patch.msgid.link/20250125-posix-clock-compat_ioctl-v2-1-11c865c500eb@weissschuh.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- drivers/ptp/ptp_chardev.c | 4 ++++
+ drivers/ptp/ptp_chardev.c | 4 ++++
1 file changed, 4 insertions(+)
-diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
-index 4fcd24e179f20..9662858cf8538 100644
--- a/drivers/ptp/ptp_chardev.c
+++ b/drivers/ptp/ptp_chardev.c
@@ -4,6 +4,7 @@
#include <linux/module.h>
#include <linux/posix-clock.h>
#include <linux/poll.h>
-@@ -159,6 +160,9 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+@@ -126,6 +127,9 @@ long ptp_ioctl(struct posix_clock_contex
struct timespec64 ts;
int enable, err = 0;
+ if (in_compat_syscall() && cmd != PTP_ENABLE_PPS && cmd != PTP_ENABLE_PPS2)
+ arg = (unsigned long)compat_ptr(arg);
+
- tsevq = pccontext->private_clkdata;
-
switch (cmd) {
---
-2.39.5
-
+
+ case PTP_CLOCK_GETCAPS:
+++ /dev/null
-From 661051dcda1235052bd1091ffc69ab64a0668e6a Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Oct 2023 00:39:54 +0200
-Subject: ptp: Replace timestamp event queue with linked list
-
-From: Xabier Marquiegui <reibax@gmail.com>
-
-[ Upstream commit d26ab5a35ad9920940a9e07665130d501b2ae1a3 ]
-
-Introduce linked lists to access the timestamp event queue.
-
-Signed-off-by: Xabier Marquiegui <reibax@gmail.com>
-Suggested-by: Richard Cochran <richardcochran@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Stable-dep-of: 19ae40f572a9 ("ptp: Properly handle compat ioctls")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/ptp/ptp_chardev.c | 12 ++++++++++--
- drivers/ptp/ptp_clock.c | 26 ++++++++++++++++++++++++--
- drivers/ptp/ptp_private.h | 4 +++-
- drivers/ptp/ptp_sysfs.c | 6 +++++-
- 4 files changed, 42 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
-index 666ea6653b04a..56b52dd52d977 100644
---- a/drivers/ptp/ptp_chardev.c
-+++ b/drivers/ptp/ptp_chardev.c
-@@ -440,10 +440,14 @@ __poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
- {
- struct ptp_clock *ptp =
- container_of(pccontext->clk, struct ptp_clock, clock);
-+ struct timestamp_event_queue *queue;
-
- poll_wait(fp, &ptp->tsev_wq, wait);
-
-- return queue_cnt(&ptp->tsevq) ? EPOLLIN : 0;
-+ /* Extract only the first element in the queue list */
-+ queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, qlist);
-+
-+ return queue_cnt(queue) ? EPOLLIN : 0;
- }
-
- #define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
-@@ -453,12 +457,16 @@ ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
- {
- struct ptp_clock *ptp =
- container_of(pccontext->clk, struct ptp_clock, clock);
-- struct timestamp_event_queue *queue = &ptp->tsevq;
-+ struct timestamp_event_queue *queue;
- struct ptp_extts_event *event;
- unsigned long flags;
- size_t qcnt, i;
- int result;
-
-+ /* Extract only the first element in the queue list */
-+ queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
-+ qlist);
-+
- if (cnt % sizeof(struct ptp_extts_event) != 0)
- return -EINVAL;
-
-diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
-index b586da2e30023..5850cb185ead3 100644
---- a/drivers/ptp/ptp_clock.c
-+++ b/drivers/ptp/ptp_clock.c
-@@ -171,12 +171,21 @@ static struct posix_clock_operations ptp_clock_ops = {
- static void ptp_clock_release(struct device *dev)
- {
- struct ptp_clock *ptp = container_of(dev, struct ptp_clock, dev);
-+ struct timestamp_event_queue *tsevq;
-+ unsigned long flags;
-
- ptp_cleanup_pin_groups(ptp);
- kfree(ptp->vclock_index);
- mutex_destroy(&ptp->tsevq_mux);
- mutex_destroy(&ptp->pincfg_mux);
- mutex_destroy(&ptp->n_vclocks_mux);
-+ /* Delete first entry */
-+ tsevq = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
-+ qlist);
-+ spin_lock_irqsave(&tsevq->lock, flags);
-+ list_del(&tsevq->qlist);
-+ spin_unlock_irqrestore(&tsevq->lock, flags);
-+ kfree(tsevq);
- ida_free(&ptp_clocks_map, ptp->index);
- kfree(ptp);
- }
-@@ -208,6 +217,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
- struct device *parent)
- {
- struct ptp_clock *ptp;
-+ struct timestamp_event_queue *queue = NULL;
- int err = 0, index, major = MAJOR(ptp_devt);
- size_t size;
-
-@@ -230,7 +240,12 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
- ptp->info = info;
- ptp->devid = MKDEV(major, index);
- ptp->index = index;
-- spin_lock_init(&ptp->tsevq.lock);
-+ INIT_LIST_HEAD(&ptp->tsevqs);
-+ queue = kzalloc(sizeof(*queue), GFP_KERNEL);
-+ if (!queue)
-+ goto no_memory_queue;
-+ spin_lock_init(&queue->lock);
-+ list_add_tail(&queue->qlist, &ptp->tsevqs);
- mutex_init(&ptp->tsevq_mux);
- mutex_init(&ptp->pincfg_mux);
- mutex_init(&ptp->n_vclocks_mux);
-@@ -335,6 +350,9 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
- mutex_destroy(&ptp->tsevq_mux);
- mutex_destroy(&ptp->pincfg_mux);
- mutex_destroy(&ptp->n_vclocks_mux);
-+ list_del(&queue->qlist);
-+ kfree(queue);
-+no_memory_queue:
- ida_free(&ptp_clocks_map, index);
- no_slot:
- kfree(ptp);
-@@ -377,6 +395,7 @@ EXPORT_SYMBOL(ptp_clock_unregister);
-
- void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
- {
-+ struct timestamp_event_queue *tsevq;
- struct pps_event_time evt;
-
- switch (event->type) {
-@@ -385,7 +404,10 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
- break;
-
- case PTP_CLOCK_EXTTS:
-- enqueue_external_timestamp(&ptp->tsevq, event);
-+ /* Enqueue timestamp on all queues */
-+ list_for_each_entry(tsevq, &ptp->tsevqs, qlist) {
-+ enqueue_external_timestamp(tsevq, event);
-+ }
- wake_up_interruptible(&ptp->tsev_wq);
- break;
-
-diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
-index f92b0181b6463..2ef0126f2869f 100644
---- a/drivers/ptp/ptp_private.h
-+++ b/drivers/ptp/ptp_private.h
-@@ -15,6 +15,7 @@
- #include <linux/ptp_clock.h>
- #include <linux/ptp_clock_kernel.h>
- #include <linux/time.h>
-+#include <linux/list.h>
-
- #define PTP_MAX_TIMESTAMPS 128
- #define PTP_BUF_TIMESTAMPS 30
-@@ -25,6 +26,7 @@ struct timestamp_event_queue {
- int head;
- int tail;
- spinlock_t lock;
-+ struct list_head qlist;
- };
-
- struct ptp_clock {
-@@ -35,7 +37,7 @@ struct ptp_clock {
- int index; /* index into clocks.map */
- struct pps_device *pps_source;
- long dialed_frequency; /* remembers the frequency adjustment */
-- struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
-+ struct list_head tsevqs; /* timestamp fifo list */
- struct mutex tsevq_mux; /* one process at a time reading the fifo */
- struct mutex pincfg_mux; /* protect concurrent info->pin_config access */
- wait_queue_head_t tsev_wq;
-diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c
-index aefc06ae5d099..952d3e968bdf9 100644
---- a/drivers/ptp/ptp_sysfs.c
-+++ b/drivers/ptp/ptp_sysfs.c
-@@ -75,12 +75,16 @@ static ssize_t extts_fifo_show(struct device *dev,
- struct device_attribute *attr, char *page)
- {
- struct ptp_clock *ptp = dev_get_drvdata(dev);
-- struct timestamp_event_queue *queue = &ptp->tsevq;
-+ struct timestamp_event_queue *queue;
- struct ptp_extts_event event;
- unsigned long flags;
- size_t qcnt;
- int cnt = 0;
-
-+ /* The sysfs fifo will always draw from the fist queue */
-+ queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
-+ qlist);
-+
- memset(&event, 0, sizeof(event));
-
- if (mutex_lock_interruptible(&ptp->tsevq_mux))
---
-2.39.5
-
+++ /dev/null
-From 74c52fbd3d7fbd105892c1060c1527ebc26bec23 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Oct 2023 00:39:56 +0200
-Subject: ptp: support event queue reader channel masks
-
-From: Xabier Marquiegui <reibax@gmail.com>
-
-[ Upstream commit c5a445b1e9347b14752b01f1a304bd7a2f260acc ]
-
-On systems with multiple timestamp event channels, some readers might
-want to receive only a subset of those channels.
-
-Add the necessary modifications to support timestamp event channel
-filtering, including two IOCTL operations:
-
-- Clear all channels
-- Enable one channel
-
-The mask modification operations will be applied exclusively on the
-event queue assigned to the file descriptor used on the IOCTL operation,
-so the typical procedure to have a reader receiving only a subset of the
-enabled channels would be:
-
-- Open device file
-- ioctl: clear all channels
-- ioctl: enable one channel
-- start reading
-
-Calling the enable one channel ioctl more than once will result in
-multiple enabled channels.
-
-Signed-off-by: Xabier Marquiegui <reibax@gmail.com>
-Suggested-by: Richard Cochran <richardcochran@gmail.com>
-Suggested-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Stable-dep-of: 19ae40f572a9 ("ptp: Properly handle compat ioctls")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/ptp/ptp_chardev.c | 26 ++++++++++++++++++++++++++
- drivers/ptp/ptp_clock.c | 12 ++++++++++--
- drivers/ptp/ptp_private.h | 3 +++
- include/uapi/linux/ptp_clock.h | 2 ++
- 4 files changed, 41 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
-index 32661889f6df1..4fcd24e179f20 100644
---- a/drivers/ptp/ptp_chardev.c
-+++ b/drivers/ptp/ptp_chardev.c
-@@ -111,6 +111,12 @@ int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
- queue = kzalloc(sizeof(*queue), GFP_KERNEL);
- if (!queue)
- return -EINVAL;
-+ queue->mask = bitmap_alloc(PTP_MAX_CHANNELS, GFP_KERNEL);
-+ if (!queue->mask) {
-+ kfree(queue);
-+ return -EINVAL;
-+ }
-+ bitmap_set(queue->mask, 0, PTP_MAX_CHANNELS);
- spin_lock_init(&queue->lock);
- list_add_tail(&queue->qlist, &ptp->tsevqs);
- pccontext->private_clkdata = queue;
-@@ -127,6 +133,7 @@ int ptp_release(struct posix_clock_context *pccontext)
- spin_lock_irqsave(&queue->lock, flags);
- list_del(&queue->qlist);
- spin_unlock_irqrestore(&queue->lock, flags);
-+ bitmap_free(queue->mask);
- kfree(queue);
- }
- return 0;
-@@ -142,6 +149,7 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
- struct system_device_crosststamp xtstamp;
- struct ptp_clock_info *ops = ptp->info;
- struct ptp_sys_offset *sysoff = NULL;
-+ struct timestamp_event_queue *tsevq;
- struct ptp_system_timestamp sts;
- struct ptp_clock_request req;
- struct ptp_clock_caps caps;
-@@ -151,6 +159,8 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
- struct timespec64 ts;
- int enable, err = 0;
-
-+ tsevq = pccontext->private_clkdata;
-+
- switch (cmd) {
-
- case PTP_CLOCK_GETCAPS:
-@@ -449,6 +459,22 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
- mutex_unlock(&ptp->pincfg_mux);
- break;
-
-+ case PTP_MASK_CLEAR_ALL:
-+ bitmap_clear(tsevq->mask, 0, PTP_MAX_CHANNELS);
-+ break;
-+
-+ case PTP_MASK_EN_SINGLE:
-+ if (copy_from_user(&i, (void __user *)arg, sizeof(i))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ if (i >= PTP_MAX_CHANNELS) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ set_bit(i, tsevq->mask);
-+ break;
-+
- default:
- err = -ENOTTY;
- break;
-diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
-index 06b9ca8f4e1ab..28eb1026fcd95 100644
---- a/drivers/ptp/ptp_clock.c
-+++ b/drivers/ptp/ptp_clock.c
-@@ -185,6 +185,7 @@ static void ptp_clock_release(struct device *dev)
- spin_lock_irqsave(&tsevq->lock, flags);
- list_del(&tsevq->qlist);
- spin_unlock_irqrestore(&tsevq->lock, flags);
-+ bitmap_free(tsevq->mask);
- kfree(tsevq);
- ida_free(&ptp_clocks_map, ptp->index);
- kfree(ptp);
-@@ -245,6 +246,10 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
- if (!queue)
- goto no_memory_queue;
- list_add_tail(&queue->qlist, &ptp->tsevqs);
-+ queue->mask = bitmap_alloc(PTP_MAX_CHANNELS, GFP_KERNEL);
-+ if (!queue->mask)
-+ goto no_memory_bitmap;
-+ bitmap_set(queue->mask, 0, PTP_MAX_CHANNELS);
- spin_lock_init(&queue->lock);
- mutex_init(&ptp->pincfg_mux);
- mutex_init(&ptp->n_vclocks_mux);
-@@ -348,6 +353,8 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
- kworker_err:
- mutex_destroy(&ptp->pincfg_mux);
- mutex_destroy(&ptp->n_vclocks_mux);
-+ bitmap_free(queue->mask);
-+no_memory_bitmap:
- list_del(&queue->qlist);
- kfree(queue);
- no_memory_queue:
-@@ -402,9 +409,10 @@ void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
- break;
-
- case PTP_CLOCK_EXTTS:
-- /* Enqueue timestamp on all queues */
-+ /* Enqueue timestamp on selected queues */
- list_for_each_entry(tsevq, &ptp->tsevqs, qlist) {
-- enqueue_external_timestamp(tsevq, event);
-+ if (test_bit((unsigned int)event->index, tsevq->mask))
-+ enqueue_external_timestamp(tsevq, event);
- }
- wake_up_interruptible(&ptp->tsev_wq);
- break;
-diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
-index 6565f5a9e7755..c6ccfeb211ada 100644
---- a/drivers/ptp/ptp_private.h
-+++ b/drivers/ptp/ptp_private.h
-@@ -16,10 +16,12 @@
- #include <linux/ptp_clock_kernel.h>
- #include <linux/time.h>
- #include <linux/list.h>
-+#include <linux/bitmap.h>
-
- #define PTP_MAX_TIMESTAMPS 128
- #define PTP_BUF_TIMESTAMPS 30
- #define PTP_DEFAULT_MAX_VCLOCKS 20
-+#define PTP_MAX_CHANNELS 2048
-
- struct timestamp_event_queue {
- struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS];
-@@ -27,6 +29,7 @@ struct timestamp_event_queue {
- int tail;
- spinlock_t lock;
- struct list_head qlist;
-+ unsigned long *mask;
- };
-
- struct ptp_clock {
-diff --git a/include/uapi/linux/ptp_clock.h b/include/uapi/linux/ptp_clock.h
-index 05cc35fc94acf..da700999cad4a 100644
---- a/include/uapi/linux/ptp_clock.h
-+++ b/include/uapi/linux/ptp_clock.h
-@@ -224,6 +224,8 @@ struct ptp_pin_desc {
- _IOWR(PTP_CLK_MAGIC, 17, struct ptp_sys_offset_precise)
- #define PTP_SYS_OFFSET_EXTENDED2 \
- _IOWR(PTP_CLK_MAGIC, 18, struct ptp_sys_offset_extended)
-+#define PTP_MASK_CLEAR_ALL _IO(PTP_CLK_MAGIC, 19)
-+#define PTP_MASK_EN_SINGLE _IOW(PTP_CLK_MAGIC, 20, unsigned int)
-
- struct ptp_extts_event {
- struct ptp_clock_time t; /* Time event occured. */
---
-2.39.5
-
+++ /dev/null
-From ac1580f66edb681eb08f9b0d82c7c13a1adb7f76 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Oct 2023 00:39:55 +0200
-Subject: ptp: support multiple timestamp event readers
-
-From: Xabier Marquiegui <reibax@gmail.com>
-
-[ Upstream commit 8f5de6fb245326704f37d91780b9a10253a8a100 ]
-
-Use linked lists to create one event queue per open file. This enables
-simultaneous readers for timestamp event queues.
-
-Signed-off-by: Xabier Marquiegui <reibax@gmail.com>
-Suggested-by: Richard Cochran <richardcochran@gmail.com>
-Signed-off-by: David S. Miller <davem@davemloft.net>
-Stable-dep-of: 19ae40f572a9 ("ptp: Properly handle compat ioctls")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/ptp/ptp_chardev.c | 68 ++++++++++++++++++++++++++++-----------
- drivers/ptp/ptp_clock.c | 6 ++--
- drivers/ptp/ptp_private.h | 1 -
- drivers/ptp/ptp_sysfs.c | 9 +++---
- 4 files changed, 55 insertions(+), 29 deletions(-)
-
-diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
-index 56b52dd52d977..32661889f6df1 100644
---- a/drivers/ptp/ptp_chardev.c
-+++ b/drivers/ptp/ptp_chardev.c
-@@ -104,6 +104,31 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
-
- int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
- {
-+ struct ptp_clock *ptp =
-+ container_of(pccontext->clk, struct ptp_clock, clock);
-+ struct timestamp_event_queue *queue;
-+
-+ queue = kzalloc(sizeof(*queue), GFP_KERNEL);
-+ if (!queue)
-+ return -EINVAL;
-+ spin_lock_init(&queue->lock);
-+ list_add_tail(&queue->qlist, &ptp->tsevqs);
-+ pccontext->private_clkdata = queue;
-+ return 0;
-+}
-+
-+int ptp_release(struct posix_clock_context *pccontext)
-+{
-+ struct timestamp_event_queue *queue = pccontext->private_clkdata;
-+ unsigned long flags;
-+
-+ if (queue) {
-+ pccontext->private_clkdata = NULL;
-+ spin_lock_irqsave(&queue->lock, flags);
-+ list_del(&queue->qlist);
-+ spin_unlock_irqrestore(&queue->lock, flags);
-+ kfree(queue);
-+ }
- return 0;
- }
-
-@@ -442,10 +467,11 @@ __poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
- container_of(pccontext->clk, struct ptp_clock, clock);
- struct timestamp_event_queue *queue;
-
-- poll_wait(fp, &ptp->tsev_wq, wait);
-+ queue = pccontext->private_clkdata;
-+ if (!queue)
-+ return EPOLLERR;
-
-- /* Extract only the first element in the queue list */
-- queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue, qlist);
-+ poll_wait(fp, &ptp->tsev_wq, wait);
-
- return queue_cnt(queue) ? EPOLLIN : 0;
- }
-@@ -463,36 +489,36 @@ ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
- size_t qcnt, i;
- int result;
-
-- /* Extract only the first element in the queue list */
-- queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
-- qlist);
-+ queue = pccontext->private_clkdata;
-+ if (!queue) {
-+ result = -EINVAL;
-+ goto exit;
-+ }
-
-- if (cnt % sizeof(struct ptp_extts_event) != 0)
-- return -EINVAL;
-+ if (cnt % sizeof(struct ptp_extts_event) != 0) {
-+ result = -EINVAL;
-+ goto exit;
-+ }
-
- if (cnt > EXTTS_BUFSIZE)
- cnt = EXTTS_BUFSIZE;
-
- cnt = cnt / sizeof(struct ptp_extts_event);
-
-- if (mutex_lock_interruptible(&ptp->tsevq_mux))
-- return -ERESTARTSYS;
--
- if (wait_event_interruptible(ptp->tsev_wq,
- ptp->defunct || queue_cnt(queue))) {
-- mutex_unlock(&ptp->tsevq_mux);
- return -ERESTARTSYS;
- }
-
- if (ptp->defunct) {
-- mutex_unlock(&ptp->tsevq_mux);
-- return -ENODEV;
-+ result = -ENODEV;
-+ goto exit;
- }
-
- event = kmalloc(EXTTS_BUFSIZE, GFP_KERNEL);
- if (!event) {
-- mutex_unlock(&ptp->tsevq_mux);
-- return -ENOMEM;
-+ result = -ENOMEM;
-+ goto exit;
- }
-
- spin_lock_irqsave(&queue->lock, flags);
-@@ -512,12 +538,16 @@ ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
-
- cnt = cnt * sizeof(struct ptp_extts_event);
-
-- mutex_unlock(&ptp->tsevq_mux);
--
- result = cnt;
-- if (copy_to_user(buf, event, cnt))
-+ if (copy_to_user(buf, event, cnt)) {
- result = -EFAULT;
-+ goto free_event;
-+ }
-
-+free_event:
- kfree(event);
-+exit:
-+ if (result < 0)
-+ ptp_release(pccontext);
- return result;
- }
-diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
-index 5850cb185ead3..06b9ca8f4e1ab 100644
---- a/drivers/ptp/ptp_clock.c
-+++ b/drivers/ptp/ptp_clock.c
-@@ -164,6 +164,7 @@ static struct posix_clock_operations ptp_clock_ops = {
- .clock_settime = ptp_clock_settime,
- .ioctl = ptp_ioctl,
- .open = ptp_open,
-+ .release = ptp_release,
- .poll = ptp_poll,
- .read = ptp_read,
- };
-@@ -176,7 +177,6 @@ static void ptp_clock_release(struct device *dev)
-
- ptp_cleanup_pin_groups(ptp);
- kfree(ptp->vclock_index);
-- mutex_destroy(&ptp->tsevq_mux);
- mutex_destroy(&ptp->pincfg_mux);
- mutex_destroy(&ptp->n_vclocks_mux);
- /* Delete first entry */
-@@ -244,9 +244,8 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
- queue = kzalloc(sizeof(*queue), GFP_KERNEL);
- if (!queue)
- goto no_memory_queue;
-- spin_lock_init(&queue->lock);
- list_add_tail(&queue->qlist, &ptp->tsevqs);
-- mutex_init(&ptp->tsevq_mux);
-+ spin_lock_init(&queue->lock);
- mutex_init(&ptp->pincfg_mux);
- mutex_init(&ptp->n_vclocks_mux);
- init_waitqueue_head(&ptp->tsev_wq);
-@@ -347,7 +346,6 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info,
- if (ptp->kworker)
- kthread_destroy_worker(ptp->kworker);
- kworker_err:
-- mutex_destroy(&ptp->tsevq_mux);
- mutex_destroy(&ptp->pincfg_mux);
- mutex_destroy(&ptp->n_vclocks_mux);
- list_del(&queue->qlist);
-diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
-index 2ef0126f2869f..6565f5a9e7755 100644
---- a/drivers/ptp/ptp_private.h
-+++ b/drivers/ptp/ptp_private.h
-@@ -38,7 +38,6 @@ struct ptp_clock {
- struct pps_device *pps_source;
- long dialed_frequency; /* remembers the frequency adjustment */
- struct list_head tsevqs; /* timestamp fifo list */
-- struct mutex tsevq_mux; /* one process at a time reading the fifo */
- struct mutex pincfg_mux; /* protect concurrent info->pin_config access */
- wait_queue_head_t tsev_wq;
- int defunct; /* tells readers to go away when clock is being removed */
-diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c
-index 952d3e968bdf9..2cdac19b5402d 100644
---- a/drivers/ptp/ptp_sysfs.c
-+++ b/drivers/ptp/ptp_sysfs.c
-@@ -81,15 +81,15 @@ static ssize_t extts_fifo_show(struct device *dev,
- size_t qcnt;
- int cnt = 0;
-
-+ cnt = list_count_nodes(&ptp->tsevqs);
-+ if (cnt <= 0)
-+ goto out;
-+
- /* The sysfs fifo will always draw from the fist queue */
- queue = list_first_entry(&ptp->tsevqs, struct timestamp_event_queue,
- qlist);
-
- memset(&event, 0, sizeof(event));
--
-- if (mutex_lock_interruptible(&ptp->tsevq_mux))
-- return -ERESTARTSYS;
--
- spin_lock_irqsave(&queue->lock, flags);
- qcnt = queue_cnt(queue);
- if (qcnt) {
-@@ -105,7 +105,6 @@ static ssize_t extts_fifo_show(struct device *dev,
- cnt = snprintf(page, PAGE_SIZE, "%u %lld %u\n",
- event.index, event.t.sec, event.t.nsec);
- out:
-- mutex_unlock(&ptp->tsevq_mux);
- return cnt;
- }
- static DEVICE_ATTR(fifo, 0444, extts_fifo_show, NULL);
---
-2.39.5
-
vxlan-fix-uninit-value-in-vxlan_vnifilter_dump.patch
net-davicom-fix-uaf-in-dm9000_drv_remove.patch
posix-clock-introduce-posix_clock_context-concept.patch
-ptp-replace-timestamp-event-queue-with-linked-list.patch
-ptp-support-multiple-timestamp-event-readers.patch
-ptp-support-event-queue-reader-channel-masks.patch
ptp-properly-handle-compat-ioctls.patch
net-stmmac-limit-the-number-of-mtl-queues-to-hardwar.patch
net-stmmac-limit-fifo-size-by-hardware-capability.patch