--- /dev/null
+From 3d93c309f1e30eb1d8bca51c88d6cc8ace4c8074 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 14:59:48 -0700
+Subject: Fix memory leak in posix_clock_open()
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit 5b4cdd9c5676559b8a7c944ac5269b914b8c0bb8 ]
+
+If the clk ops.open() function returns an error, we don't release the
+pccontext we allocated for this clock.
+
+Re-organize the code slightly to make it all more obvious.
+
+Reported-by: Rohit Keshri <rkeshri@redhat.com>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Fixes: 60c6946675fc ("posix-clock: introduce posix_clock_context concept")
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds@linuxfoundation.org>
+Stable-dep-of: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/posix-clock.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 706559ed75793..a6487a9d60853 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,15 +129,17 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
+- fp->private_data = pccontext;
+- if (clk->ops.open)
++ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+- else
+- err = 0;
+-
+- if (!err) {
+- get_device(clk->dev);
++ if (err) {
++ kfree(pccontext);
++ goto out;
++ }
+ }
++
++ fp->private_data = pccontext;
++ get_device(clk->dev);
++ err = 0;
+ out:
+ up_read(&clk->rwsem);
+ return err;
+--
+2.51.0
+
--- /dev/null
+From 1203ce227c50256b6bc28b661366043bc3526e54 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 00:39:53 +0200
+Subject: posix-clock: introduce posix_clock_context concept
+
+From: Xabier Marquiegui <reibax@gmail.com>
+
+[ Upstream commit 60c6946675fc06dd2fd2b7a4b6fd1c1f046f1056 ]
+
+Add the necessary structure to support custom private-data per
+posix-clock user.
+
+The previous implementation of posix-clock assumed all file open
+instances need access to the same clock structure on private_data.
+
+The need for individual data structures per file open instance has been
+identified when developing support for multiple timestamp event queue
+users for ptp_clock.
+
+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: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 21 +++++++++++++--------
+ drivers/ptp/ptp_private.h | 16 +++++++++-------
+ include/linux/posix-clock.h | 35 +++++++++++++++++++++++++++--------
+ kernel/time/posix-clock.c | 36 +++++++++++++++++++++++++++---------
+ 4 files changed, 76 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index 8eb902fe73a98..2776f37713123 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -102,14 +102,16 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ return 0;
+ }
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode)
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
+ {
+ return 0;
+ }
+
+-long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct ptp_sys_offset_extended *extoff = NULL;
+ struct ptp_sys_offset_precise precise_offset;
+ struct system_device_crosststamp xtstamp;
+@@ -430,9 +432,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
+ return err;
+ }
+
+-__poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+
+ poll_wait(fp, &ptp->tsev_wq, wait);
+
+@@ -441,10 +445,11 @@ __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
+
+ #define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint rdflags, char __user *buf, size_t cnt)
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
++ char __user *buf, size_t cnt)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct timestamp_event_queue *queue = &ptp->tsevq;
+ struct ptp_extts_event *event;
+ unsigned long flags;
+diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
+index d2cb956706763..ba3a1a29a288a 100644
+--- a/drivers/ptp/ptp_private.h
++++ b/drivers/ptp/ptp_private.h
+@@ -73,16 +73,18 @@ static inline int queue_cnt(const struct timestamp_event_queue *q)
+ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ enum ptp_pin_function func, unsigned int chan);
+
+-long ptp_ioctl(struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode);
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode);
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++int ptp_release(struct posix_clock_context *pccontext);
+
+-__poll_t ptp_poll(struct posix_clock *pc,
+- struct file *fp, poll_table *wait);
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf,
++ size_t cnt);
++
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait);
+
+ /*
+ * see ptp_sysfs.c
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index 468328b1e1dd5..ef8619f489203 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -14,6 +14,7 @@
+ #include <linux/rwsem.h>
+
+ struct posix_clock;
++struct posix_clock_context;
+
+ /**
+ * struct posix_clock_operations - functional interface to the clock
+@@ -50,18 +51,18 @@ struct posix_clock_operations {
+ /*
+ * Optional character device methods:
+ */
+- long (*ioctl) (struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++ long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+- int (*open) (struct posix_clock *pc, fmode_t f_mode);
++ int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode);
+
+- __poll_t (*poll) (struct posix_clock *pc,
+- struct file *file, poll_table *wait);
++ __poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file,
++ poll_table *wait);
+
+- int (*release) (struct posix_clock *pc);
++ int (*release)(struct posix_clock_context *pccontext);
+
+- ssize_t (*read) (struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++ ssize_t (*read)(struct posix_clock_context *pccontext, uint flags,
++ char __user *buf, size_t cnt);
+ };
+
+ /**
+@@ -90,6 +91,24 @@ struct posix_clock {
+ bool zombie;
+ };
+
++/**
++ * struct posix_clock_context - represents clock file operations context
++ *
++ * @clk: Pointer to the clock
++ * @private_clkdata: Pointer to user data
++ *
++ * Drivers should use struct posix_clock_context during specific character
++ * device file operation methods to access the posix clock.
++ *
++ * Drivers can store a private data structure during the open operation
++ * if they have specific information that is required in other file
++ * operations.
++ */
++struct posix_clock_context {
++ struct posix_clock *clk;
++ void *private_clkdata;
++};
++
+ /**
+ * posix_clock_register() - register a new clock
+ * @clk: Pointer to the clock. Caller must provide 'ops' field
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 05e73d209aa87..706559ed75793 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -19,7 +19,8 @@
+ */
+ static struct posix_clock *get_posix_clock(struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk = pccontext->clk;
+
+ down_read(&clk->rwsem);
+
+@@ -39,6 +40,7 @@ static void put_posix_clock(struct posix_clock *clk)
+ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ size_t count, loff_t *ppos)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -EINVAL;
+
+@@ -46,7 +48,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ return -ENODEV;
+
+ if (clk->ops.read)
+- err = clk->ops.read(clk, fp->f_flags, buf, count);
++ err = clk->ops.read(pccontext, fp->f_flags, buf, count);
+
+ put_posix_clock(clk);
+
+@@ -55,6 +57,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+
+ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ __poll_t result = 0;
+
+@@ -62,7 +65,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ return EPOLLERR;
+
+ if (clk->ops.poll)
+- result = clk->ops.poll(clk, fp, wait);
++ result = clk->ops.poll(pccontext, fp, wait);
+
+ put_posix_clock(clk);
+
+@@ -72,6 +75,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ static long posix_clock_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -79,7 +83,7 @@ static long posix_clock_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -90,6 +94,7 @@ static long posix_clock_ioctl(struct file *fp,
+ static long posix_clock_compat_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -97,7 +102,7 @@ static long posix_clock_compat_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -110,6 +115,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ int err;
+ struct posix_clock *clk =
+ container_of(inode->i_cdev, struct posix_clock, cdev);
++ struct posix_clock_context *pccontext;
+
+ down_read(&clk->rwsem);
+
+@@ -117,14 +123,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ err = -ENODEV;
+ goto out;
+ }
++ pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL);
++ if (!pccontext) {
++ err = -ENOMEM;
++ goto out;
++ }
++ pccontext->clk = clk;
++ fp->private_data = pccontext;
+ if (clk->ops.open)
+- err = clk->ops.open(clk, fp->f_mode);
++ err = clk->ops.open(pccontext, fp->f_mode);
+ else
+ err = 0;
+
+ if (!err) {
+ get_device(clk->dev);
+- fp->private_data = clk;
+ }
+ out:
+ up_read(&clk->rwsem);
+@@ -133,14 +145,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+
+ static int posix_clock_release(struct inode *inode, struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk;
+ int err = 0;
+
++ if (!pccontext)
++ return -ENODEV;
++ clk = pccontext->clk;
++
+ if (clk->ops.release)
+- err = clk->ops.release(clk);
++ err = clk->ops.release(pccontext);
+
+ put_device(clk->dev);
+
++ kfree(pccontext);
+ fp->private_data = NULL;
+
+ return err;
+--
+2.51.0
+
--- /dev/null
+From 87ad56721d6d242c1f170f855a7cf5c9cb9fe9cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:43 +0200
+Subject: posix-clock: Store file pointer in struct posix_clock_context
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit e859d375d1694488015e6804bfeea527a0b25b9f ]
+
+File descriptor based pc_clock_*() operations of dynamic posix clocks
+have access to the file pointer and implement permission checks in the
+generic code before invoking the relevant dynamic clock callback.
+
+Character device operations (open, read, poll, ioctl) do not implement a
+generic permission control and the dynamic clock callbacks have no
+access to the file pointer to implement them.
+
+Extend struct posix_clock_context with a struct file pointer and
+initialize it in posix_clock_open(), so that all dynamic clock callbacks
+can access it.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/posix-clock.h | 6 +++++-
+ kernel/time/posix-clock.c | 1 +
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index ef8619f489203..a500d3160fe8c 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -95,10 +95,13 @@ struct posix_clock {
+ * struct posix_clock_context - represents clock file operations context
+ *
+ * @clk: Pointer to the clock
++ * @fp: Pointer to the file used to open the clock
+ * @private_clkdata: Pointer to user data
+ *
+ * Drivers should use struct posix_clock_context during specific character
+- * device file operation methods to access the posix clock.
++ * device file operation methods to access the posix clock. In particular,
++ * the file pointer can be used to verify correct access mode for ioctl()
++ * calls.
+ *
+ * Drivers can store a private data structure during the open operation
+ * if they have specific information that is required in other file
+@@ -106,6 +109,7 @@ struct posix_clock {
+ */
+ struct posix_clock_context {
+ struct posix_clock *clk;
++ struct file *fp;
+ void *private_clkdata;
+ };
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index a6487a9d60853..b130bb56cc4e0 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,6 +129,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
++ pccontext->fp = fp;
+ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+ if (err) {
+--
+2.51.0
+
--- /dev/null
+From 9a5c34cb4726a847b6da1a012303a777fbe7f2c3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:44 +0200
+Subject: ptp: Add PHC file mode checks. Allow RO adjtime() without
+ FMODE_WRITE.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit b4e53b15c04e3852949003752f48f7a14ae39e86 ]
+
+Many devices implement highly accurate clocks, which the kernel manages
+as PTP Hardware Clocks (PHCs). Userspace applications rely on these
+clocks to timestamp events, trace workload execution, correlate
+timescales across devices, and keep various clocks in sync.
+
+The kernel’s current implementation of PTP clocks does not enforce file
+permissions checks for most device operations except for POSIX clock
+operations, where file mode is verified in the POSIX layer before
+forwarding the call to the PTP subsystem. Consequently, it is common
+practice to not give unprivileged userspace applications any access to
+PTP clocks whatsoever by giving the PTP chardevs 600 permissions. An
+example of users running into this limitation is documented in [1].
+Additionally, POSIX layer requires WRITE permission even for readonly
+adjtime() calls which are used in PTP layer to return current frequency
+offset applied to the PHC.
+
+Add permission checks for functions that modify the state of a PTP
+device. Continue enforcing permission checks for POSIX clock operations
+(settime, adjtime) in the POSIX layer. Only require WRITE access for
+dynamic clocks adjtime() if any flags are set in the modes field.
+
+[1] https://lists.nwtime.org/sympa/arc/linuxptp-users/2024-01/msg00036.html
+
+Changes in v4:
+- Require FMODE_WRITE in ajtime() only for calls modifying the clock in
+ any way.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 16 ++++++++++++++++
+ kernel/time/posix-clock.c | 2 +-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index 2776f37713123..1d6ce1c6c877b 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -146,6 +146,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_EXTTS_REQUEST:
+ case PTP_EXTTS_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.extts, (void __user *)arg,
+@@ -187,6 +191,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PEROUT_REQUEST:
+ case PTP_PEROUT_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.perout, (void __user *)arg,
+@@ -255,6 +263,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_ENABLE_PPS:
+ case PTP_ENABLE_PPS2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (!capable(CAP_SYS_TIME))
+@@ -393,6 +405,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PIN_SETFUNC:
+ case PTP_PIN_SETFUNC2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
+ err = -EFAULT;
+ break;
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index b130bb56cc4e0..827abede72745 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -253,7 +253,7 @@ static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx)
+ if (err)
+ return err;
+
+- if ((cd.fp->f_mode & FMODE_WRITE) == 0) {
++ if (tx->modes && (cd.fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ goto out;
+ }
+--
+2.51.0
+
dmaengine-ti-k3-udma-fix-device-leak-on-udma-lookup.patch
btrfs-fix-deadlock-in-wait_current_trans-due-to-ignored-transaction-type.patch
macvlan-fix-leaking-skb-in-source-mode-with-nodst-option.patch
+posix-clock-introduce-posix_clock_context-concept.patch
+fix-memory-leak-in-posix_clock_open.patch
+posix-clock-store-file-pointer-in-struct-posix_clock.patch
+ptp-add-phc-file-mode-checks.-allow-ro-adjtime-witho.patch
--- /dev/null
+From 735f74d50b76cd0f36ff4ea03e3d4177a2237510 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 14:59:48 -0700
+Subject: Fix memory leak in posix_clock_open()
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit 5b4cdd9c5676559b8a7c944ac5269b914b8c0bb8 ]
+
+If the clk ops.open() function returns an error, we don't release the
+pccontext we allocated for this clock.
+
+Re-organize the code slightly to make it all more obvious.
+
+Reported-by: Rohit Keshri <rkeshri@redhat.com>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Fixes: 60c6946675fc ("posix-clock: introduce posix_clock_context concept")
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds@linuxfoundation.org>
+Stable-dep-of: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/posix-clock.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 706559ed75793..a6487a9d60853 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,15 +129,17 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
+- fp->private_data = pccontext;
+- if (clk->ops.open)
++ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+- else
+- err = 0;
+-
+- if (!err) {
+- get_device(clk->dev);
++ if (err) {
++ kfree(pccontext);
++ goto out;
++ }
+ }
++
++ fp->private_data = pccontext;
++ get_device(clk->dev);
++ err = 0;
+ out:
+ up_read(&clk->rwsem);
+ return err;
+--
+2.51.0
+
--- /dev/null
+From cb6a747e4b65df0d8b2b4eacc57d983042473175 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 00:39:53 +0200
+Subject: posix-clock: introduce posix_clock_context concept
+
+From: Xabier Marquiegui <reibax@gmail.com>
+
+[ Upstream commit 60c6946675fc06dd2fd2b7a4b6fd1c1f046f1056 ]
+
+Add the necessary structure to support custom private-data per
+posix-clock user.
+
+The previous implementation of posix-clock assumed all file open
+instances need access to the same clock structure on private_data.
+
+The need for individual data structures per file open instance has been
+identified when developing support for multiple timestamp event queue
+users for ptp_clock.
+
+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: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 21 +++++++++++++--------
+ drivers/ptp/ptp_private.h | 16 +++++++++-------
+ include/linux/posix-clock.h | 35 +++++++++++++++++++++++++++--------
+ kernel/time/posix-clock.c | 36 +++++++++++++++++++++++++++---------
+ 4 files changed, 76 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index 6b36003567975..fcee202f4484c 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -103,14 +103,16 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ return 0;
+ }
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode)
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
+ {
+ return 0;
+ }
+
+-long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct ptp_sys_offset_extended *extoff = NULL;
+ struct ptp_sys_offset_precise precise_offset;
+ struct system_device_crosststamp xtstamp;
+@@ -434,9 +436,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
+ return err;
+ }
+
+-__poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+
+ poll_wait(fp, &ptp->tsev_wq, wait);
+
+@@ -445,10 +449,11 @@ __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
+
+ #define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint rdflags, char __user *buf, size_t cnt)
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
++ char __user *buf, size_t cnt)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct timestamp_event_queue *queue = &ptp->tsevq;
+ struct ptp_extts_event *event;
+ unsigned long flags;
+diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
+index bf823b8c3c8fd..1787fb7a9e1db 100644
+--- a/drivers/ptp/ptp_private.h
++++ b/drivers/ptp/ptp_private.h
+@@ -125,16 +125,18 @@ extern struct class *ptp_class;
+ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ enum ptp_pin_function func, unsigned int chan);
+
+-long ptp_ioctl(struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode);
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode);
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++int ptp_release(struct posix_clock_context *pccontext);
+
+-__poll_t ptp_poll(struct posix_clock *pc,
+- struct file *fp, poll_table *wait);
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf,
++ size_t cnt);
++
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait);
+
+ /*
+ * see ptp_sysfs.c
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index 468328b1e1dd5..ef8619f489203 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -14,6 +14,7 @@
+ #include <linux/rwsem.h>
+
+ struct posix_clock;
++struct posix_clock_context;
+
+ /**
+ * struct posix_clock_operations - functional interface to the clock
+@@ -50,18 +51,18 @@ struct posix_clock_operations {
+ /*
+ * Optional character device methods:
+ */
+- long (*ioctl) (struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++ long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+- int (*open) (struct posix_clock *pc, fmode_t f_mode);
++ int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode);
+
+- __poll_t (*poll) (struct posix_clock *pc,
+- struct file *file, poll_table *wait);
++ __poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file,
++ poll_table *wait);
+
+- int (*release) (struct posix_clock *pc);
++ int (*release)(struct posix_clock_context *pccontext);
+
+- ssize_t (*read) (struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++ ssize_t (*read)(struct posix_clock_context *pccontext, uint flags,
++ char __user *buf, size_t cnt);
+ };
+
+ /**
+@@ -90,6 +91,24 @@ struct posix_clock {
+ bool zombie;
+ };
+
++/**
++ * struct posix_clock_context - represents clock file operations context
++ *
++ * @clk: Pointer to the clock
++ * @private_clkdata: Pointer to user data
++ *
++ * Drivers should use struct posix_clock_context during specific character
++ * device file operation methods to access the posix clock.
++ *
++ * Drivers can store a private data structure during the open operation
++ * if they have specific information that is required in other file
++ * operations.
++ */
++struct posix_clock_context {
++ struct posix_clock *clk;
++ void *private_clkdata;
++};
++
+ /**
+ * posix_clock_register() - register a new clock
+ * @clk: Pointer to the clock. Caller must provide 'ops' field
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 05e73d209aa87..706559ed75793 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -19,7 +19,8 @@
+ */
+ static struct posix_clock *get_posix_clock(struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk = pccontext->clk;
+
+ down_read(&clk->rwsem);
+
+@@ -39,6 +40,7 @@ static void put_posix_clock(struct posix_clock *clk)
+ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ size_t count, loff_t *ppos)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -EINVAL;
+
+@@ -46,7 +48,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ return -ENODEV;
+
+ if (clk->ops.read)
+- err = clk->ops.read(clk, fp->f_flags, buf, count);
++ err = clk->ops.read(pccontext, fp->f_flags, buf, count);
+
+ put_posix_clock(clk);
+
+@@ -55,6 +57,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+
+ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ __poll_t result = 0;
+
+@@ -62,7 +65,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ return EPOLLERR;
+
+ if (clk->ops.poll)
+- result = clk->ops.poll(clk, fp, wait);
++ result = clk->ops.poll(pccontext, fp, wait);
+
+ put_posix_clock(clk);
+
+@@ -72,6 +75,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ static long posix_clock_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -79,7 +83,7 @@ static long posix_clock_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -90,6 +94,7 @@ static long posix_clock_ioctl(struct file *fp,
+ static long posix_clock_compat_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -97,7 +102,7 @@ static long posix_clock_compat_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -110,6 +115,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ int err;
+ struct posix_clock *clk =
+ container_of(inode->i_cdev, struct posix_clock, cdev);
++ struct posix_clock_context *pccontext;
+
+ down_read(&clk->rwsem);
+
+@@ -117,14 +123,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ err = -ENODEV;
+ goto out;
+ }
++ pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL);
++ if (!pccontext) {
++ err = -ENOMEM;
++ goto out;
++ }
++ pccontext->clk = clk;
++ fp->private_data = pccontext;
+ if (clk->ops.open)
+- err = clk->ops.open(clk, fp->f_mode);
++ err = clk->ops.open(pccontext, fp->f_mode);
+ else
+ err = 0;
+
+ if (!err) {
+ get_device(clk->dev);
+- fp->private_data = clk;
+ }
+ out:
+ up_read(&clk->rwsem);
+@@ -133,14 +145,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+
+ static int posix_clock_release(struct inode *inode, struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk;
+ int err = 0;
+
++ if (!pccontext)
++ return -ENODEV;
++ clk = pccontext->clk;
++
+ if (clk->ops.release)
+- err = clk->ops.release(clk);
++ err = clk->ops.release(pccontext);
+
+ put_device(clk->dev);
+
++ kfree(pccontext);
+ fp->private_data = NULL;
+
+ return err;
+--
+2.51.0
+
--- /dev/null
+From f3647ecd3e51de2fbdd677fc4528ae22df3f4ba4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:43 +0200
+Subject: posix-clock: Store file pointer in struct posix_clock_context
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit e859d375d1694488015e6804bfeea527a0b25b9f ]
+
+File descriptor based pc_clock_*() operations of dynamic posix clocks
+have access to the file pointer and implement permission checks in the
+generic code before invoking the relevant dynamic clock callback.
+
+Character device operations (open, read, poll, ioctl) do not implement a
+generic permission control and the dynamic clock callbacks have no
+access to the file pointer to implement them.
+
+Extend struct posix_clock_context with a struct file pointer and
+initialize it in posix_clock_open(), so that all dynamic clock callbacks
+can access it.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/posix-clock.h | 6 +++++-
+ kernel/time/posix-clock.c | 1 +
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index ef8619f489203..a500d3160fe8c 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -95,10 +95,13 @@ struct posix_clock {
+ * struct posix_clock_context - represents clock file operations context
+ *
+ * @clk: Pointer to the clock
++ * @fp: Pointer to the file used to open the clock
+ * @private_clkdata: Pointer to user data
+ *
+ * Drivers should use struct posix_clock_context during specific character
+- * device file operation methods to access the posix clock.
++ * device file operation methods to access the posix clock. In particular,
++ * the file pointer can be used to verify correct access mode for ioctl()
++ * calls.
+ *
+ * Drivers can store a private data structure during the open operation
+ * if they have specific information that is required in other file
+@@ -106,6 +109,7 @@ struct posix_clock {
+ */
+ struct posix_clock_context {
+ struct posix_clock *clk;
++ struct file *fp;
+ void *private_clkdata;
+ };
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index a6487a9d60853..b130bb56cc4e0 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,6 +129,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
++ pccontext->fp = fp;
+ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+ if (err) {
+--
+2.51.0
+
--- /dev/null
+From e1ab86a8826eefe9a9f149a991836bd12e9e6b27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:44 +0200
+Subject: ptp: Add PHC file mode checks. Allow RO adjtime() without
+ FMODE_WRITE.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit b4e53b15c04e3852949003752f48f7a14ae39e86 ]
+
+Many devices implement highly accurate clocks, which the kernel manages
+as PTP Hardware Clocks (PHCs). Userspace applications rely on these
+clocks to timestamp events, trace workload execution, correlate
+timescales across devices, and keep various clocks in sync.
+
+The kernel’s current implementation of PTP clocks does not enforce file
+permissions checks for most device operations except for POSIX clock
+operations, where file mode is verified in the POSIX layer before
+forwarding the call to the PTP subsystem. Consequently, it is common
+practice to not give unprivileged userspace applications any access to
+PTP clocks whatsoever by giving the PTP chardevs 600 permissions. An
+example of users running into this limitation is documented in [1].
+Additionally, POSIX layer requires WRITE permission even for readonly
+adjtime() calls which are used in PTP layer to return current frequency
+offset applied to the PHC.
+
+Add permission checks for functions that modify the state of a PTP
+device. Continue enforcing permission checks for POSIX clock operations
+(settime, adjtime) in the POSIX layer. Only require WRITE access for
+dynamic clocks adjtime() if any flags are set in the modes field.
+
+[1] https://lists.nwtime.org/sympa/arc/linuxptp-users/2024-01/msg00036.html
+
+Changes in v4:
+- Require FMODE_WRITE in ajtime() only for calls modifying the clock in
+ any way.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 16 ++++++++++++++++
+ kernel/time/posix-clock.c | 2 +-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index fcee202f4484c..aa38a518e3d7b 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -150,6 +150,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_EXTTS_REQUEST:
+ case PTP_EXTTS_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.extts, (void __user *)arg,
+@@ -191,6 +195,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PEROUT_REQUEST:
+ case PTP_PEROUT_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.perout, (void __user *)arg,
+@@ -259,6 +267,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_ENABLE_PPS:
+ case PTP_ENABLE_PPS2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (!capable(CAP_SYS_TIME))
+@@ -397,6 +409,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PIN_SETFUNC:
+ case PTP_PIN_SETFUNC2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
+ err = -EFAULT;
+ break;
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index b130bb56cc4e0..827abede72745 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -253,7 +253,7 @@ static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx)
+ if (err)
+ return err;
+
+- if ((cd.fp->f_mode & FMODE_WRITE) == 0) {
++ if (tx->modes && (cd.fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ goto out;
+ }
+--
+2.51.0
+
--- /dev/null
+From be97c722d540e7d38f703bc3ee26afbe6b428ae8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 00:39:58 +0200
+Subject: ptp: add testptp mask test
+
+From: Xabier Marquiegui <reibax@gmail.com>
+
+[ Upstream commit 26285e689c6cd2cf3849568c83b2ebe53f467143 ]
+
+Add option to test timestamp event queue mask manipulation in testptp.
+
+Option -F allows the user to specify a single channel that will be
+applied on the mask filter via IOCTL.
+
+The test program will maintain the file open until user input is
+received.
+
+This allows checking the effect of the IOCTL in debugfs.
+
+eg:
+
+Console 1:
+```
+Channel 12 exclusively enabled. Check on debugfs.
+Press any key to continue
+```
+
+Console 2:
+```
+0x00000000 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000
+```
+
+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: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index faec606707de6..994ac7988426b 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -121,6 +121,7 @@ static void usage(char *progname)
+ " -d name device to open\n"
+ " -e val read 'val' external time stamp events\n"
+ " -f val adjust the ptp clock frequency by 'val' ppb\n"
++ " -F chan Enable single channel mask and keep device open for debugfs verification.\n"
+ " -g get the ptp clock time\n"
+ " -h prints this message\n"
+ " -i val index for event/trigger\n"
+@@ -187,6 +188,7 @@ int main(int argc, char *argv[])
+ int pps = -1;
+ int seconds = 0;
+ int settime = 0;
++ int channel = -1;
+
+ int64_t t1, t2, tp;
+ int64_t interval, offset;
+@@ -196,7 +198,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -210,6 +212,9 @@ int main(int argc, char *argv[])
+ case 'f':
+ adjfreq = atoi(optarg);
+ break;
++ case 'F':
++ channel = atoi(optarg);
++ break;
+ case 'g':
+ gettime = 1;
+ break;
+@@ -602,6 +607,18 @@ int main(int argc, char *argv[])
+ free(xts);
+ }
+
++ if (channel >= 0) {
++ if (ioctl(fd, PTP_MASK_CLEAR_ALL)) {
++ perror("PTP_MASK_CLEAR_ALL");
++ } else if (ioctl(fd, PTP_MASK_EN_SINGLE, (unsigned int *)&channel)) {
++ perror("PTP_MASK_EN_SINGLE");
++ } else {
++ printf("Channel %d exclusively enabled. Check on debugfs.\n", channel);
++ printf("Press any key to continue\n.");
++ getchar();
++ }
++ }
++
+ close(fd);
+ return 0;
+ }
+--
+2.51.0
+
--- /dev/null
+From 9020a69d47e5f22d1440d9ea2618a5a28332782c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 03:15:06 -0700
+Subject: selftest/ptp: update ptp selftest to exercise the gettimex options
+
+From: Mahesh Bandewar <maheshb@google.com>
+
+[ Upstream commit 3d07b691ee707c00afaf365440975e81bb96cd9b ]
+
+With the inclusion of commit c259acab839e ("ptp/ioctl: support
+MONOTONIC{,_RAW} timestamps for PTP_SYS_OFFSET_EXTENDED") clock_gettime()
+now allows retrieval of pre/post timestamps for CLOCK_MONOTONIC and
+CLOCK_MONOTONIC_RAW timebases along with the previously supported
+CLOCK_REALTIME.
+
+This patch adds a command line option 'y' to the testptp program to
+choose one of the allowed timebases [realtime aka system, monotonic,
+and monotonic-raw).
+
+Signed-off-by: Mahesh Bandewar <maheshb@google.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://patch.msgid.link/20241003101506.769418-1-maheshb@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 62 ++++++++++++++++++++++++---
+ 1 file changed, 57 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 994ac7988426b..d3922e3c437f1 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -146,6 +146,7 @@ static void usage(char *progname)
+ " -T val set the ptp clock time to 'val' seconds\n"
+ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
+ " -X get a ptp clock cross timestamp\n"
++ " -y val pre/post tstamp timebase to use {realtime|monotonic|monotonic-raw}\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+ progname, PTP_MAX_SAMPLES);
+ }
+@@ -189,6 +190,7 @@ int main(int argc, char *argv[])
+ int seconds = 0;
+ int settime = 0;
+ int channel = -1;
++ clockid_t ext_clockid = CLOCK_REALTIME;
+
+ int64_t t1, t2, tp;
+ int64_t interval, offset;
+@@ -198,7 +200,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -278,6 +280,21 @@ int main(int argc, char *argv[])
+ case 'X':
+ getcross = 1;
+ break;
++ case 'y':
++ if (!strcasecmp(optarg, "realtime"))
++ ext_clockid = CLOCK_REALTIME;
++ else if (!strcasecmp(optarg, "monotonic"))
++ ext_clockid = CLOCK_MONOTONIC;
++ else if (!strcasecmp(optarg, "monotonic-raw"))
++ ext_clockid = CLOCK_MONOTONIC_RAW;
++ else {
++ fprintf(stderr,
++ "type needs to be realtime, monotonic or monotonic-raw; was given %s\n",
++ optarg);
++ return -1;
++ }
++ break;
++
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -564,6 +581,7 @@ int main(int argc, char *argv[])
+ }
+
+ soe->n_samples = getextended;
++ soe->clockid = ext_clockid;
+
+ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) {
+ perror("PTP_SYS_OFFSET_EXTENDED");
+@@ -572,12 +590,46 @@ int main(int argc, char *argv[])
+ getextended);
+
+ for (i = 0; i < getextended; i++) {
+- printf("sample #%2d: system time before: %lld.%09u\n",
+- i, soe->ts[i][0].sec, soe->ts[i][0].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf("sample #%2d: real time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf("sample #%2d: monotonic time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf("sample #%2d: monotonic-raw time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ default:
++ break;
++ }
+ printf(" phc time: %lld.%09u\n",
+ soe->ts[i][1].sec, soe->ts[i][1].nsec);
+- printf(" system time after: %lld.%09u\n",
+- soe->ts[i][2].sec, soe->ts[i][2].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf(" real time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf(" monotonic time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf(" monotonic-raw time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ default:
++ break;
++ }
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From ea4ff99a0465ab6c667ec3c47b6512ab8ae02164 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 22:53:33 +0100
+Subject: selftests/ptp: Add -x option for testing PTP_SYS_OFFSET_EXTENDED
+
+From: Alex Maftei <alex.maftei@amd.com>
+
+[ Upstream commit c8ba75c4eb846888f8f2730690b99cb5bf7b337c ]
+
+The -x option (where 'x' stands for eXtended) takes an argument which
+represents the number of samples to request from the PTP device.
+The help message will display the maximum number of samples allowed.
+Providing an invalid argument will also display the maximum number of
+samples allowed.
+
+Signed-off-by: Alex Maftei <alex.maftei@amd.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 44 +++++++++++++++++++++++++--
+ 1 file changed, 42 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index eec05f659950a..d3cbd254a196d 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -143,8 +143,9 @@ static void usage(char *progname)
+ " -S set the system time from the ptp clock time\n"
+ " -t val shift the ptp clock time by 'val' seconds\n"
+ " -T val set the ptp clock time to 'val' seconds\n"
++ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+- progname);
++ progname, PTP_MAX_SAMPLES);
+ }
+
+ int main(int argc, char *argv[])
+@@ -158,6 +159,7 @@ int main(int argc, char *argv[])
+ struct timex tx;
+ struct ptp_clock_time *pct;
+ struct ptp_sys_offset *sysoff;
++ struct ptp_sys_offset_extended *soe;
+
+ char *progname;
+ unsigned int i;
+@@ -176,6 +178,7 @@ int main(int argc, char *argv[])
+ int index = 0;
+ int list_pins = 0;
+ int pct_offset = 0;
++ int getextended = 0;
+ int n_samples = 0;
+ int pin_index = -1, pin_func;
+ int pps = -1;
+@@ -190,7 +193,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -255,6 +258,15 @@ int main(int argc, char *argv[])
+ case 'w':
+ pulsewidth = atoi(optarg);
+ break;
++ case 'x':
++ getextended = atoi(optarg);
++ if (getextended < 1 || getextended > PTP_MAX_SAMPLES) {
++ fprintf(stderr,
++ "number of extended timestamp samples must be between 1 and %d; was asked for %d\n",
++ PTP_MAX_SAMPLES, getextended);
++ return -1;
++ }
++ break;
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -533,6 +545,34 @@ int main(int argc, char *argv[])
+ free(sysoff);
+ }
+
++ if (getextended) {
++ soe = calloc(1, sizeof(*soe));
++ if (!soe) {
++ perror("calloc");
++ return -1;
++ }
++
++ soe->n_samples = getextended;
++
++ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) {
++ perror("PTP_SYS_OFFSET_EXTENDED");
++ } else {
++ printf("extended timestamp request returned %d samples\n",
++ getextended);
++
++ for (i = 0; i < getextended; i++) {
++ printf("sample #%2d: system time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec, soe->ts[i][0].nsec);
++ printf(" phc time: %lld.%09u\n",
++ soe->ts[i][1].sec, soe->ts[i][1].nsec);
++ printf(" system time after: %lld.%09u\n",
++ soe->ts[i][2].sec, soe->ts[i][2].nsec);
++ }
++ }
++
++ free(soe);
++ }
++
+ close(fd);
+ return 0;
+ }
+--
+2.51.0
+
--- /dev/null
+From 90684923fc89f1a36192e36ae287972aeff61a59 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 22:53:34 +0100
+Subject: selftests/ptp: Add -X option for testing PTP_SYS_OFFSET_PRECISE
+
+From: Alex Maftei <alex.maftei@amd.com>
+
+[ Upstream commit 3cf119ad5dc2b5c11385106d6d0ba86fbb47324c ]
+
+The -X option was chosen because X looks like a cross, and the underlying
+callback is 'get cross timestamp'.
+
+Signed-off-by: Alex Maftei <alex.maftei@amd.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 31 ++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index d3cbd254a196d..faec606707de6 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -144,6 +144,7 @@ static void usage(char *progname)
+ " -t val shift the ptp clock time by 'val' seconds\n"
+ " -T val set the ptp clock time to 'val' seconds\n"
+ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
++ " -X get a ptp clock cross timestamp\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+ progname, PTP_MAX_SAMPLES);
+ }
+@@ -160,6 +161,7 @@ int main(int argc, char *argv[])
+ struct ptp_clock_time *pct;
+ struct ptp_sys_offset *sysoff;
+ struct ptp_sys_offset_extended *soe;
++ struct ptp_sys_offset_precise *xts;
+
+ char *progname;
+ unsigned int i;
+@@ -179,6 +181,7 @@ int main(int argc, char *argv[])
+ int list_pins = 0;
+ int pct_offset = 0;
+ int getextended = 0;
++ int getcross = 0;
+ int n_samples = 0;
+ int pin_index = -1, pin_func;
+ int pps = -1;
+@@ -193,7 +196,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -267,6 +270,9 @@ int main(int argc, char *argv[])
+ return -1;
+ }
+ break;
++ case 'X':
++ getcross = 1;
++ break;
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -573,6 +579,29 @@ int main(int argc, char *argv[])
+ free(soe);
+ }
+
++ if (getcross) {
++ xts = calloc(1, sizeof(*xts));
++ if (!xts) {
++ perror("calloc");
++ return -1;
++ }
++
++ if (ioctl(fd, PTP_SYS_OFFSET_PRECISE, xts)) {
++ perror("PTP_SYS_OFFSET_PRECISE");
++ } else {
++ puts("system and phc crosstimestamping request okay");
++
++ printf("device time: %lld.%09u\n",
++ xts->device.sec, xts->device.nsec);
++ printf("system time: %lld.%09u\n",
++ xts->sys_realtime.sec, xts->sys_realtime.nsec);
++ printf("monoraw time: %lld.%09u\n",
++ xts->sys_monoraw.sec, xts->sys_monoraw.nsec);
++ }
++
++ free(xts);
++ }
++
+ close(fd);
+ return 0;
+ }
+--
+2.51.0
+
dmaengine-ti-dma-crossbar-fix-device-leak-on-am335x-route-allocation.patch
dmaengine-ti-k3-udma-fix-device-leak-on-udma-lookup.patch
btrfs-fix-deadlock-in-wait_current_trans-due-to-ignored-transaction-type.patch
+posix-clock-introduce-posix_clock_context-concept.patch
+fix-memory-leak-in-posix_clock_open.patch
+posix-clock-store-file-pointer-in-struct-posix_clock.patch
+ptp-add-phc-file-mode-checks.-allow-ro-adjtime-witho.patch
+testptp-add-option-to-shift-clock-by-nanoseconds.patch
+testptp-add-support-for-testing-ptp_clock_info-.adjp.patch
+selftests-ptp-add-x-option-for-testing-ptp_sys_offse.patch
+selftests-ptp-add-x-option-for-testing-ptp_sys_offse.patch-2439
+ptp-add-testptp-mask-test.patch
+selftest-ptp-update-ptp-selftest-to-exercise-the-get.patch
+testptp-add-option-to-open-phc-in-readonly-mode.patch
--- /dev/null
+From f6273ba7722a0c361261edefc0b21a55bfc3cd99 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:45 +0200
+Subject: testptp: Add option to open PHC in readonly mode
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit 76868642e42795353106197abf9c607ad80f4c9e ]
+
+PTP Hardware Clocks no longer require WRITE permission to perform
+readonly operations, such as listing device capabilities or listening to
+EXTTS events once they have been enabled by a process with WRITE
+permissions.
+
+Add '-r' option to testptp to open the PHC in readonly mode instead of
+the default read-write mode. Skip enabling EXTTS if readonly mode is
+requested.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 37 +++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 14 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index d3922e3c437f1..89b4f43a7ba45 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -140,6 +140,7 @@ static void usage(char *progname)
+ " -H val set output phase to 'val' nanoseconds (requires -p)\n"
+ " -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
+ " -P val enable or disable (val=1|0) the system clock PPS\n"
++ " -r open the ptp clock in readonly mode\n"
+ " -s set the ptp clock time from the system time\n"
+ " -S set the system time from the ptp clock time\n"
+ " -t val shift the ptp clock time by 'val' seconds\n"
+@@ -188,6 +189,7 @@ int main(int argc, char *argv[])
+ int pin_index = -1, pin_func;
+ int pps = -1;
+ int seconds = 0;
++ int readonly = 0;
+ int settime = 0;
+ int channel = -1;
+ clockid_t ext_clockid = CLOCK_REALTIME;
+@@ -200,7 +202,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -252,6 +254,9 @@ int main(int argc, char *argv[])
+ case 'P':
+ pps = atoi(optarg);
+ break;
++ case 'r':
++ readonly = 1;
++ break;
+ case 's':
+ settime = 1;
+ break;
+@@ -308,7 +313,7 @@ int main(int argc, char *argv[])
+ }
+ }
+
+- fd = open(device, O_RDWR);
++ fd = open(device, readonly ? O_RDONLY : O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
+ return -1;
+@@ -422,14 +427,16 @@ int main(int argc, char *argv[])
+ }
+
+ if (extts) {
+- memset(&extts_request, 0, sizeof(extts_request));
+- extts_request.index = index;
+- extts_request.flags = PTP_ENABLE_FEATURE;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
+- extts = 0;
+- } else {
+- puts("external time stamp request okay");
++ if (!readonly) {
++ memset(&extts_request, 0, sizeof(extts_request));
++ extts_request.index = index;
++ extts_request.flags = PTP_ENABLE_FEATURE;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ extts = 0;
++ } else {
++ puts("external time stamp request okay");
++ }
+ }
+ for (; extts; extts--) {
+ cnt = read(fd, &event, sizeof(event));
+@@ -441,10 +448,12 @@ int main(int argc, char *argv[])
+ event.t.sec, event.t.nsec);
+ fflush(stdout);
+ }
+- /* Disable the feature again. */
+- extts_request.flags = 0;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
++ if (!readonly) {
++ /* Disable the feature again. */
++ extts_request.flags = 0;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ }
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 12f8514d8f8b8d2d37450a25e5bd1dd6e1ecafd4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 21 Feb 2022 21:06:37 +0100
+Subject: testptp: add option to shift clock by nanoseconds
+
+From: Maciek Machnikowski <maciek@machnikowski.net>
+
+[ Upstream commit f64ae40de5efaa33c36f4e2226b33824ba1b42a7 ]
+
+Add option to shift the clock by a specified number of nanoseconds.
+
+The new argument -n will specify the number of nanoseconds to add to the
+ptp clock. Since the API doesn't support negative shifts those needs to
+be calculated by subtracting full seconds and adding a nanosecond offset.
+
+Signed-off-by: Maciek Machnikowski <maciek@machnikowski.net>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://lore.kernel.org/r/20220221200637.125595-1-maciek@machnikowski.net
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index aa474febb4712..b943a594ea733 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -133,6 +133,7 @@ static void usage(char *progname)
+ " 0 - none\n"
+ " 1 - external time stamp\n"
+ " 2 - periodic output\n"
++ " -n val shift the ptp clock time by 'val' nanoseconds\n"
+ " -p val enable output with a period of 'val' nanoseconds\n"
+ " -H val set output phase to 'val' nanoseconds (requires -p)\n"
+ " -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
+@@ -165,6 +166,7 @@ int main(int argc, char *argv[])
+ clockid_t clkid;
+ int adjfreq = 0x7fffffff;
+ int adjtime = 0;
++ int adjns = 0;
+ int capabilities = 0;
+ int extts = 0;
+ int flagtest = 0;
+@@ -186,7 +188,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:p:P:sSt:T:w:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:p:P:sSt:T:w:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -223,6 +225,9 @@ int main(int argc, char *argv[])
+ return -1;
+ }
+ break;
++ case 'n':
++ adjns = atoi(optarg);
++ break;
+ case 'p':
+ perout = atoll(optarg);
+ break;
+@@ -305,11 +310,16 @@ int main(int argc, char *argv[])
+ }
+ }
+
+- if (adjtime) {
++ if (adjtime || adjns) {
+ memset(&tx, 0, sizeof(tx));
+- tx.modes = ADJ_SETOFFSET;
++ tx.modes = ADJ_SETOFFSET | ADJ_NANO;
+ tx.time.tv_sec = adjtime;
+- tx.time.tv_usec = 0;
++ tx.time.tv_usec = adjns;
++ while (tx.time.tv_usec < 0) {
++ tx.time.tv_sec -= 1;
++ tx.time.tv_usec += 1000000000;
++ }
++
+ if (clock_adjtime(clkid, &tx) < 0) {
+ perror("clock_adjtime");
+ } else {
+--
+2.51.0
+
--- /dev/null
+From 8edc3dae0327bb8452b6b640bc3da04594cb9b47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 14:14:55 -0700
+Subject: testptp: Add support for testing ptp_clock_info .adjphase callback
+
+From: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+
+[ Upstream commit 3a9a9a6139286584d1199f555fa4f96f592a3217 ]
+
+Invoke clock_adjtime syscall with tx.modes set with ADJ_OFFSET when testptp
+is invoked with a phase adjustment offset value. Support seconds and
+nanoseconds for the offset value.
+
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Richard Cochran <richardcochran@gmail.com>
+Cc: Maciek Machnikowski <maciek@machnikowski.net>
+Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index b943a594ea733..eec05f659950a 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -134,6 +134,7 @@ static void usage(char *progname)
+ " 1 - external time stamp\n"
+ " 2 - periodic output\n"
+ " -n val shift the ptp clock time by 'val' nanoseconds\n"
++ " -o val phase offset (in nanoseconds) to be provided to the PHC servo\n"
+ " -p val enable output with a period of 'val' nanoseconds\n"
+ " -H val set output phase to 'val' nanoseconds (requires -p)\n"
+ " -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
+@@ -167,6 +168,7 @@ int main(int argc, char *argv[])
+ int adjfreq = 0x7fffffff;
+ int adjtime = 0;
+ int adjns = 0;
++ int adjphase = 0;
+ int capabilities = 0;
+ int extts = 0;
+ int flagtest = 0;
+@@ -188,7 +190,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:p:P:sSt:T:w:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -228,6 +230,9 @@ int main(int argc, char *argv[])
+ case 'n':
+ adjns = atoi(optarg);
+ break;
++ case 'o':
++ adjphase = atoi(optarg);
++ break;
+ case 'p':
+ perout = atoll(optarg);
+ break;
+@@ -327,6 +332,18 @@ int main(int argc, char *argv[])
+ }
+ }
+
++ if (adjphase) {
++ memset(&tx, 0, sizeof(tx));
++ tx.modes = ADJ_OFFSET | ADJ_NANO;
++ tx.offset = adjphase;
++
++ if (clock_adjtime(clkid, &tx) < 0) {
++ perror("clock_adjtime");
++ } else {
++ puts("phase adjustment okay");
++ }
++ }
++
+ if (gettime) {
+ if (clock_gettime(clkid, &ts)) {
+ perror("clock_gettime");
+--
+2.51.0
+
--- /dev/null
+From b2f4ecbf763e27f7d8d24d628ef653780dd007ae Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:36:22 +0100
+Subject: arm64: dts: qcom: sc8280xp: Add missing VDD_MXC links
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 868b979c5328b867c95a6d5a93ba13ad0d3cd2f1 ]
+
+To make sure that power rail is voted for, wire it up to its consumers.
+
+Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-3-46cdf47a829e@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 6b0d4bc6c5419..e502360de601d 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -1819,8 +1819,12 @@ remoteproc_nsp0: remoteproc@1b300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp0_mem>;
+
+@@ -1950,8 +1954,12 @@ remoteproc_nsp1: remoteproc@21300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp1_mem>;
+
+--
+2.51.0
+
--- /dev/null
+From 54b7e5d3b5e7f1263e94377a0e8a61b5cb1c3d05 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 18:37:56 +0000
+Subject: btrfs: fix missing fields in superblock backup with BLOCK_GROUP_TREE
+
+From: Mark Harmstone <mark@harmstone.com>
+
+[ Upstream commit 1d8f69f453c2e8a2d99b158e58e02ed65031fa6d ]
+
+When the BLOCK_GROUP_TREE compat_ro flag is set, the extent root and
+csum root fields are getting missed.
+
+This is because EXTENT_TREE_V2 treated these differently, and when
+they were split off this special-casing was mistakenly assigned to
+BGT rather than the rump EXTENT_TREE_V2. There's no reason why the
+existence of the block group tree should mean that we don't record the
+details of the last commit's extent root and csum root.
+
+Fix the code in backup_super_roots() so that the correct check gets
+made.
+
+Fixes: 1c56ab991903 ("btrfs: separate BLOCK_GROUP_TREE compat RO flag from EXTENT_TREE_V2")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Mark Harmstone <mark@harmstone.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/disk-io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 8576ba4aa0b7d..52e083b63070d 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -1993,7 +1993,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
+ btrfs_set_backup_chunk_root_level(root_backup,
+ btrfs_header_level(info->chunk_root->node));
+
+- if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
++ if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+ struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+ struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+
+--
+2.51.0
+
--- /dev/null
+From 7ec2bcb576af685c4f7e43d8bc8a988b31a4dbfc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 14:59:48 -0700
+Subject: Fix memory leak in posix_clock_open()
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit 5b4cdd9c5676559b8a7c944ac5269b914b8c0bb8 ]
+
+If the clk ops.open() function returns an error, we don't release the
+pccontext we allocated for this clock.
+
+Re-organize the code slightly to make it all more obvious.
+
+Reported-by: Rohit Keshri <rkeshri@redhat.com>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Fixes: 60c6946675fc ("posix-clock: introduce posix_clock_context concept")
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds@linuxfoundation.org>
+Stable-dep-of: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/posix-clock.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 706559ed75793..a6487a9d60853 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,15 +129,17 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
+- fp->private_data = pccontext;
+- if (clk->ops.open)
++ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+- else
+- err = 0;
+-
+- if (!err) {
+- get_device(clk->dev);
++ if (err) {
++ kfree(pccontext);
++ goto out;
++ }
+ }
++
++ fp->private_data = pccontext;
++ get_device(clk->dev);
++ err = 0;
+ out:
+ up_read(&clk->rwsem);
+ return err;
+--
+2.51.0
+
--- /dev/null
+From befc333b99ca02c290a59a6bef3c364d0ef56f63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 00:39:53 +0200
+Subject: posix-clock: introduce posix_clock_context concept
+
+From: Xabier Marquiegui <reibax@gmail.com>
+
+[ Upstream commit 60c6946675fc06dd2fd2b7a4b6fd1c1f046f1056 ]
+
+Add the necessary structure to support custom private-data per
+posix-clock user.
+
+The previous implementation of posix-clock assumed all file open
+instances need access to the same clock structure on private_data.
+
+The need for individual data structures per file open instance has been
+identified when developing support for multiple timestamp event queue
+users for ptp_clock.
+
+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: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 21 +++++++++++++--------
+ drivers/ptp/ptp_private.h | 16 +++++++++-------
+ include/linux/posix-clock.h | 35 +++++++++++++++++++++++++++--------
+ kernel/time/posix-clock.c | 36 +++++++++++++++++++++++++++---------
+ 4 files changed, 76 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index 6b36003567975..fcee202f4484c 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -103,14 +103,16 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ return 0;
+ }
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode)
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
+ {
+ return 0;
+ }
+
+-long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct ptp_sys_offset_extended *extoff = NULL;
+ struct ptp_sys_offset_precise precise_offset;
+ struct system_device_crosststamp xtstamp;
+@@ -434,9 +436,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
+ return err;
+ }
+
+-__poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+
+ poll_wait(fp, &ptp->tsev_wq, wait);
+
+@@ -445,10 +449,11 @@ __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
+
+ #define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint rdflags, char __user *buf, size_t cnt)
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
++ char __user *buf, size_t cnt)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct timestamp_event_queue *queue = &ptp->tsevq;
+ struct ptp_extts_event *event;
+ unsigned long flags;
+diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
+index a54124269c2f4..a431eb79fe77d 100644
+--- a/drivers/ptp/ptp_private.h
++++ b/drivers/ptp/ptp_private.h
+@@ -131,16 +131,18 @@ extern struct class *ptp_class;
+ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ enum ptp_pin_function func, unsigned int chan);
+
+-long ptp_ioctl(struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode);
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode);
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++int ptp_release(struct posix_clock_context *pccontext);
+
+-__poll_t ptp_poll(struct posix_clock *pc,
+- struct file *fp, poll_table *wait);
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf,
++ size_t cnt);
++
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait);
+
+ /*
+ * see ptp_sysfs.c
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index 468328b1e1dd5..ef8619f489203 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -14,6 +14,7 @@
+ #include <linux/rwsem.h>
+
+ struct posix_clock;
++struct posix_clock_context;
+
+ /**
+ * struct posix_clock_operations - functional interface to the clock
+@@ -50,18 +51,18 @@ struct posix_clock_operations {
+ /*
+ * Optional character device methods:
+ */
+- long (*ioctl) (struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++ long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+- int (*open) (struct posix_clock *pc, fmode_t f_mode);
++ int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode);
+
+- __poll_t (*poll) (struct posix_clock *pc,
+- struct file *file, poll_table *wait);
++ __poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file,
++ poll_table *wait);
+
+- int (*release) (struct posix_clock *pc);
++ int (*release)(struct posix_clock_context *pccontext);
+
+- ssize_t (*read) (struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++ ssize_t (*read)(struct posix_clock_context *pccontext, uint flags,
++ char __user *buf, size_t cnt);
+ };
+
+ /**
+@@ -90,6 +91,24 @@ struct posix_clock {
+ bool zombie;
+ };
+
++/**
++ * struct posix_clock_context - represents clock file operations context
++ *
++ * @clk: Pointer to the clock
++ * @private_clkdata: Pointer to user data
++ *
++ * Drivers should use struct posix_clock_context during specific character
++ * device file operation methods to access the posix clock.
++ *
++ * Drivers can store a private data structure during the open operation
++ * if they have specific information that is required in other file
++ * operations.
++ */
++struct posix_clock_context {
++ struct posix_clock *clk;
++ void *private_clkdata;
++};
++
+ /**
+ * posix_clock_register() - register a new clock
+ * @clk: Pointer to the clock. Caller must provide 'ops' field
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 05e73d209aa87..706559ed75793 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -19,7 +19,8 @@
+ */
+ static struct posix_clock *get_posix_clock(struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk = pccontext->clk;
+
+ down_read(&clk->rwsem);
+
+@@ -39,6 +40,7 @@ static void put_posix_clock(struct posix_clock *clk)
+ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ size_t count, loff_t *ppos)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -EINVAL;
+
+@@ -46,7 +48,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ return -ENODEV;
+
+ if (clk->ops.read)
+- err = clk->ops.read(clk, fp->f_flags, buf, count);
++ err = clk->ops.read(pccontext, fp->f_flags, buf, count);
+
+ put_posix_clock(clk);
+
+@@ -55,6 +57,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+
+ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ __poll_t result = 0;
+
+@@ -62,7 +65,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ return EPOLLERR;
+
+ if (clk->ops.poll)
+- result = clk->ops.poll(clk, fp, wait);
++ result = clk->ops.poll(pccontext, fp, wait);
+
+ put_posix_clock(clk);
+
+@@ -72,6 +75,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ static long posix_clock_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -79,7 +83,7 @@ static long posix_clock_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -90,6 +94,7 @@ static long posix_clock_ioctl(struct file *fp,
+ static long posix_clock_compat_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -97,7 +102,7 @@ static long posix_clock_compat_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -110,6 +115,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ int err;
+ struct posix_clock *clk =
+ container_of(inode->i_cdev, struct posix_clock, cdev);
++ struct posix_clock_context *pccontext;
+
+ down_read(&clk->rwsem);
+
+@@ -117,14 +123,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ err = -ENODEV;
+ goto out;
+ }
++ pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL);
++ if (!pccontext) {
++ err = -ENOMEM;
++ goto out;
++ }
++ pccontext->clk = clk;
++ fp->private_data = pccontext;
+ if (clk->ops.open)
+- err = clk->ops.open(clk, fp->f_mode);
++ err = clk->ops.open(pccontext, fp->f_mode);
+ else
+ err = 0;
+
+ if (!err) {
+ get_device(clk->dev);
+- fp->private_data = clk;
+ }
+ out:
+ up_read(&clk->rwsem);
+@@ -133,14 +145,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+
+ static int posix_clock_release(struct inode *inode, struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk;
+ int err = 0;
+
++ if (!pccontext)
++ return -ENODEV;
++ clk = pccontext->clk;
++
+ if (clk->ops.release)
+- err = clk->ops.release(clk);
++ err = clk->ops.release(pccontext);
+
+ put_device(clk->dev);
+
++ kfree(pccontext);
+ fp->private_data = NULL;
+
+ return err;
+--
+2.51.0
+
--- /dev/null
+From a5d727ad95e5d5801b133be8eb745e7c3b6d4ce5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:43 +0200
+Subject: posix-clock: Store file pointer in struct posix_clock_context
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit e859d375d1694488015e6804bfeea527a0b25b9f ]
+
+File descriptor based pc_clock_*() operations of dynamic posix clocks
+have access to the file pointer and implement permission checks in the
+generic code before invoking the relevant dynamic clock callback.
+
+Character device operations (open, read, poll, ioctl) do not implement a
+generic permission control and the dynamic clock callbacks have no
+access to the file pointer to implement them.
+
+Extend struct posix_clock_context with a struct file pointer and
+initialize it in posix_clock_open(), so that all dynamic clock callbacks
+can access it.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/posix-clock.h | 6 +++++-
+ kernel/time/posix-clock.c | 1 +
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index ef8619f489203..a500d3160fe8c 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -95,10 +95,13 @@ struct posix_clock {
+ * struct posix_clock_context - represents clock file operations context
+ *
+ * @clk: Pointer to the clock
++ * @fp: Pointer to the file used to open the clock
+ * @private_clkdata: Pointer to user data
+ *
+ * Drivers should use struct posix_clock_context during specific character
+- * device file operation methods to access the posix clock.
++ * device file operation methods to access the posix clock. In particular,
++ * the file pointer can be used to verify correct access mode for ioctl()
++ * calls.
+ *
+ * Drivers can store a private data structure during the open operation
+ * if they have specific information that is required in other file
+@@ -106,6 +109,7 @@ struct posix_clock {
+ */
+ struct posix_clock_context {
+ struct posix_clock *clk;
++ struct file *fp;
+ void *private_clkdata;
+ };
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index a6487a9d60853..b130bb56cc4e0 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,6 +129,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
++ pccontext->fp = fp;
+ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+ if (err) {
+--
+2.51.0
+
--- /dev/null
+From 9ad1ae274f0695842c19db5c8fe866712c276551 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:44 +0200
+Subject: ptp: Add PHC file mode checks. Allow RO adjtime() without
+ FMODE_WRITE.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit b4e53b15c04e3852949003752f48f7a14ae39e86 ]
+
+Many devices implement highly accurate clocks, which the kernel manages
+as PTP Hardware Clocks (PHCs). Userspace applications rely on these
+clocks to timestamp events, trace workload execution, correlate
+timescales across devices, and keep various clocks in sync.
+
+The kernel’s current implementation of PTP clocks does not enforce file
+permissions checks for most device operations except for POSIX clock
+operations, where file mode is verified in the POSIX layer before
+forwarding the call to the PTP subsystem. Consequently, it is common
+practice to not give unprivileged userspace applications any access to
+PTP clocks whatsoever by giving the PTP chardevs 600 permissions. An
+example of users running into this limitation is documented in [1].
+Additionally, POSIX layer requires WRITE permission even for readonly
+adjtime() calls which are used in PTP layer to return current frequency
+offset applied to the PHC.
+
+Add permission checks for functions that modify the state of a PTP
+device. Continue enforcing permission checks for POSIX clock operations
+(settime, adjtime) in the POSIX layer. Only require WRITE access for
+dynamic clocks adjtime() if any flags are set in the modes field.
+
+[1] https://lists.nwtime.org/sympa/arc/linuxptp-users/2024-01/msg00036.html
+
+Changes in v4:
+- Require FMODE_WRITE in ajtime() only for calls modifying the clock in
+ any way.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 16 ++++++++++++++++
+ kernel/time/posix-clock.c | 2 +-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index fcee202f4484c..aa38a518e3d7b 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -150,6 +150,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_EXTTS_REQUEST:
+ case PTP_EXTTS_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.extts, (void __user *)arg,
+@@ -191,6 +195,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PEROUT_REQUEST:
+ case PTP_PEROUT_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.perout, (void __user *)arg,
+@@ -259,6 +267,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_ENABLE_PPS:
+ case PTP_ENABLE_PPS2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (!capable(CAP_SYS_TIME))
+@@ -397,6 +409,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PIN_SETFUNC:
+ case PTP_PIN_SETFUNC2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
+ err = -EFAULT;
+ break;
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index b130bb56cc4e0..827abede72745 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -253,7 +253,7 @@ static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx)
+ if (err)
+ return err;
+
+- if ((cd.fp->f_mode & FMODE_WRITE) == 0) {
++ if (tx->modes && (cd.fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ goto out;
+ }
+--
+2.51.0
+
--- /dev/null
+From 0ddcf773beba631f1c7d2c5083198b49a63cfbf1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 00:39:58 +0200
+Subject: ptp: add testptp mask test
+
+From: Xabier Marquiegui <reibax@gmail.com>
+
+[ Upstream commit 26285e689c6cd2cf3849568c83b2ebe53f467143 ]
+
+Add option to test timestamp event queue mask manipulation in testptp.
+
+Option -F allows the user to specify a single channel that will be
+applied on the mask filter via IOCTL.
+
+The test program will maintain the file open until user input is
+received.
+
+This allows checking the effect of the IOCTL in debugfs.
+
+eg:
+
+Console 1:
+```
+Channel 12 exclusively enabled. Check on debugfs.
+Press any key to continue
+```
+
+Console 2:
+```
+0x00000000 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000
+```
+
+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: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 863699434296a..b609efbdea55d 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -121,6 +121,7 @@ static void usage(char *progname)
+ " -d name device to open\n"
+ " -e val read 'val' external time stamp events\n"
+ " -f val adjust the ptp clock frequency by 'val' ppb\n"
++ " -F chan Enable single channel mask and keep device open for debugfs verification.\n"
+ " -g get the ptp clock time\n"
+ " -h prints this message\n"
+ " -i val index for event/trigger\n"
+@@ -187,6 +188,7 @@ int main(int argc, char *argv[])
+ int pps = -1;
+ int seconds = 0;
+ int settime = 0;
++ int channel = -1;
+
+ int64_t t1, t2, tp;
+ int64_t interval, offset;
+@@ -196,7 +198,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -210,6 +212,9 @@ int main(int argc, char *argv[])
+ case 'f':
+ adjfreq = atoi(optarg);
+ break;
++ case 'F':
++ channel = atoi(optarg);
++ break;
+ case 'g':
+ gettime = 1;
+ break;
+@@ -602,6 +607,18 @@ int main(int argc, char *argv[])
+ free(xts);
+ }
+
++ if (channel >= 0) {
++ if (ioctl(fd, PTP_MASK_CLEAR_ALL)) {
++ perror("PTP_MASK_CLEAR_ALL");
++ } else if (ioctl(fd, PTP_MASK_EN_SINGLE, (unsigned int *)&channel)) {
++ perror("PTP_MASK_EN_SINGLE");
++ } else {
++ printf("Channel %d exclusively enabled. Check on debugfs.\n", channel);
++ printf("Press any key to continue\n.");
++ getchar();
++ }
++ }
++
+ close(fd);
+ return 0;
+ }
+--
+2.51.0
+
--- /dev/null
+From a15786dadc5fe1d6e40d1830f1ccd1bc31ac0969 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 03:15:06 -0700
+Subject: selftest/ptp: update ptp selftest to exercise the gettimex options
+
+From: Mahesh Bandewar <maheshb@google.com>
+
+[ Upstream commit 3d07b691ee707c00afaf365440975e81bb96cd9b ]
+
+With the inclusion of commit c259acab839e ("ptp/ioctl: support
+MONOTONIC{,_RAW} timestamps for PTP_SYS_OFFSET_EXTENDED") clock_gettime()
+now allows retrieval of pre/post timestamps for CLOCK_MONOTONIC and
+CLOCK_MONOTONIC_RAW timebases along with the previously supported
+CLOCK_REALTIME.
+
+This patch adds a command line option 'y' to the testptp program to
+choose one of the allowed timebases [realtime aka system, monotonic,
+and monotonic-raw).
+
+Signed-off-by: Mahesh Bandewar <maheshb@google.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://patch.msgid.link/20241003101506.769418-1-maheshb@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 62 ++++++++++++++++++++++++---
+ 1 file changed, 57 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index b609efbdea55d..2323a3329b298 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -146,6 +146,7 @@ static void usage(char *progname)
+ " -T val set the ptp clock time to 'val' seconds\n"
+ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
+ " -X get a ptp clock cross timestamp\n"
++ " -y val pre/post tstamp timebase to use {realtime|monotonic|monotonic-raw}\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+ progname, PTP_MAX_SAMPLES);
+ }
+@@ -189,6 +190,7 @@ int main(int argc, char *argv[])
+ int seconds = 0;
+ int settime = 0;
+ int channel = -1;
++ clockid_t ext_clockid = CLOCK_REALTIME;
+
+ int64_t t1, t2, tp;
+ int64_t interval, offset;
+@@ -198,7 +200,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -278,6 +280,21 @@ int main(int argc, char *argv[])
+ case 'X':
+ getcross = 1;
+ break;
++ case 'y':
++ if (!strcasecmp(optarg, "realtime"))
++ ext_clockid = CLOCK_REALTIME;
++ else if (!strcasecmp(optarg, "monotonic"))
++ ext_clockid = CLOCK_MONOTONIC;
++ else if (!strcasecmp(optarg, "monotonic-raw"))
++ ext_clockid = CLOCK_MONOTONIC_RAW;
++ else {
++ fprintf(stderr,
++ "type needs to be realtime, monotonic or monotonic-raw; was given %s\n",
++ optarg);
++ return -1;
++ }
++ break;
++
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -564,6 +581,7 @@ int main(int argc, char *argv[])
+ }
+
+ soe->n_samples = getextended;
++ soe->clockid = ext_clockid;
+
+ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) {
+ perror("PTP_SYS_OFFSET_EXTENDED");
+@@ -572,12 +590,46 @@ int main(int argc, char *argv[])
+ getextended);
+
+ for (i = 0; i < getextended; i++) {
+- printf("sample #%2d: system time before: %lld.%09u\n",
+- i, soe->ts[i][0].sec, soe->ts[i][0].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf("sample #%2d: real time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf("sample #%2d: monotonic time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf("sample #%2d: monotonic-raw time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ default:
++ break;
++ }
+ printf(" phc time: %lld.%09u\n",
+ soe->ts[i][1].sec, soe->ts[i][1].nsec);
+- printf(" system time after: %lld.%09u\n",
+- soe->ts[i][2].sec, soe->ts[i][2].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf(" real time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf(" monotonic time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf(" monotonic-raw time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ default:
++ break;
++ }
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From e234cc4bed4909206e79a03aaebb855879c9c554 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 22:53:33 +0100
+Subject: selftests/ptp: Add -x option for testing PTP_SYS_OFFSET_EXTENDED
+
+From: Alex Maftei <alex.maftei@amd.com>
+
+[ Upstream commit c8ba75c4eb846888f8f2730690b99cb5bf7b337c ]
+
+The -x option (where 'x' stands for eXtended) takes an argument which
+represents the number of samples to request from the PTP device.
+The help message will display the maximum number of samples allowed.
+Providing an invalid argument will also display the maximum number of
+samples allowed.
+
+Signed-off-by: Alex Maftei <alex.maftei@amd.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 44 +++++++++++++++++++++++++--
+ 1 file changed, 42 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 9c3d36a40309b..2db6ff0316e7a 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -143,8 +143,9 @@ static void usage(char *progname)
+ " -S set the system time from the ptp clock time\n"
+ " -t val shift the ptp clock time by 'val' seconds\n"
+ " -T val set the ptp clock time to 'val' seconds\n"
++ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+- progname);
++ progname, PTP_MAX_SAMPLES);
+ }
+
+ int main(int argc, char *argv[])
+@@ -158,6 +159,7 @@ int main(int argc, char *argv[])
+ struct timex tx;
+ struct ptp_clock_time *pct;
+ struct ptp_sys_offset *sysoff;
++ struct ptp_sys_offset_extended *soe;
+
+ char *progname;
+ unsigned int i;
+@@ -176,6 +178,7 @@ int main(int argc, char *argv[])
+ int index = 0;
+ int list_pins = 0;
+ int pct_offset = 0;
++ int getextended = 0;
+ int n_samples = 0;
+ int pin_index = -1, pin_func;
+ int pps = -1;
+@@ -190,7 +193,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -255,6 +258,15 @@ int main(int argc, char *argv[])
+ case 'w':
+ pulsewidth = atoi(optarg);
+ break;
++ case 'x':
++ getextended = atoi(optarg);
++ if (getextended < 1 || getextended > PTP_MAX_SAMPLES) {
++ fprintf(stderr,
++ "number of extended timestamp samples must be between 1 and %d; was asked for %d\n",
++ PTP_MAX_SAMPLES, getextended);
++ return -1;
++ }
++ break;
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -533,6 +545,34 @@ int main(int argc, char *argv[])
+ free(sysoff);
+ }
+
++ if (getextended) {
++ soe = calloc(1, sizeof(*soe));
++ if (!soe) {
++ perror("calloc");
++ return -1;
++ }
++
++ soe->n_samples = getextended;
++
++ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) {
++ perror("PTP_SYS_OFFSET_EXTENDED");
++ } else {
++ printf("extended timestamp request returned %d samples\n",
++ getextended);
++
++ for (i = 0; i < getextended; i++) {
++ printf("sample #%2d: system time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec, soe->ts[i][0].nsec);
++ printf(" phc time: %lld.%09u\n",
++ soe->ts[i][1].sec, soe->ts[i][1].nsec);
++ printf(" system time after: %lld.%09u\n",
++ soe->ts[i][2].sec, soe->ts[i][2].nsec);
++ }
++ }
++
++ free(soe);
++ }
++
+ close(fd);
+ return 0;
+ }
+--
+2.51.0
+
--- /dev/null
+From a6dd52ee83d499e3f0cbf575180ba6d89c593be0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jul 2023 22:53:34 +0100
+Subject: selftests/ptp: Add -X option for testing PTP_SYS_OFFSET_PRECISE
+
+From: Alex Maftei <alex.maftei@amd.com>
+
+[ Upstream commit 3cf119ad5dc2b5c11385106d6d0ba86fbb47324c ]
+
+The -X option was chosen because X looks like a cross, and the underlying
+callback is 'get cross timestamp'.
+
+Signed-off-by: Alex Maftei <alex.maftei@amd.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 31 ++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 2db6ff0316e7a..863699434296a 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -144,6 +144,7 @@ static void usage(char *progname)
+ " -t val shift the ptp clock time by 'val' seconds\n"
+ " -T val set the ptp clock time to 'val' seconds\n"
+ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
++ " -X get a ptp clock cross timestamp\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+ progname, PTP_MAX_SAMPLES);
+ }
+@@ -160,6 +161,7 @@ int main(int argc, char *argv[])
+ struct ptp_clock_time *pct;
+ struct ptp_sys_offset *sysoff;
+ struct ptp_sys_offset_extended *soe;
++ struct ptp_sys_offset_precise *xts;
+
+ char *progname;
+ unsigned int i;
+@@ -179,6 +181,7 @@ int main(int argc, char *argv[])
+ int list_pins = 0;
+ int pct_offset = 0;
+ int getextended = 0;
++ int getcross = 0;
+ int n_samples = 0;
+ int pin_index = -1, pin_func;
+ int pps = -1;
+@@ -193,7 +196,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -267,6 +270,9 @@ int main(int argc, char *argv[])
+ return -1;
+ }
+ break;
++ case 'X':
++ getcross = 1;
++ break;
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -573,6 +579,29 @@ int main(int argc, char *argv[])
+ free(soe);
+ }
+
++ if (getcross) {
++ xts = calloc(1, sizeof(*xts));
++ if (!xts) {
++ perror("calloc");
++ return -1;
++ }
++
++ if (ioctl(fd, PTP_SYS_OFFSET_PRECISE, xts)) {
++ perror("PTP_SYS_OFFSET_PRECISE");
++ } else {
++ puts("system and phc crosstimestamping request okay");
++
++ printf("device time: %lld.%09u\n",
++ xts->device.sec, xts->device.nsec);
++ printf("system time: %lld.%09u\n",
++ xts->sys_realtime.sec, xts->sys_realtime.nsec);
++ printf("monoraw time: %lld.%09u\n",
++ xts->sys_monoraw.sec, xts->sys_monoraw.nsec);
++ }
++
++ free(xts);
++ }
++
+ close(fd);
+ return 0;
+ }
+--
+2.51.0
+
dmaengine-ti-k3-udma-fix-device-leak-on-udma-lookup.patch
btrfs-fix-deadlock-in-wait_current_trans-due-to-ignored-transaction-type.patch
io_uring-move-local-task_work-in-exit-cancel-loop.patch
+posix-clock-introduce-posix_clock_context-concept.patch
+fix-memory-leak-in-posix_clock_open.patch
+posix-clock-store-file-pointer-in-struct-posix_clock.patch
+ptp-add-phc-file-mode-checks.-allow-ro-adjtime-witho.patch
+testptp-add-support-for-testing-ptp_clock_info-.adjp.patch
+selftests-ptp-add-x-option-for-testing-ptp_sys_offse.patch
+selftests-ptp-add-x-option-for-testing-ptp_sys_offse.patch-21448
+ptp-add-testptp-mask-test.patch
+selftest-ptp-update-ptp-selftest-to-exercise-the-get.patch
+testptp-add-option-to-open-phc-in-readonly-mode.patch
+arm64-dts-qcom-sc8280xp-add-missing-vdd_mxc-links.patch
+btrfs-fix-missing-fields-in-superblock-backup-with-b.patch
--- /dev/null
+From 33c44494e4b5c24149e2dfbad9096b79345041a4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:45 +0200
+Subject: testptp: Add option to open PHC in readonly mode
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit 76868642e42795353106197abf9c607ad80f4c9e ]
+
+PTP Hardware Clocks no longer require WRITE permission to perform
+readonly operations, such as listing device capabilities or listening to
+EXTTS events once they have been enabled by a process with WRITE
+permissions.
+
+Add '-r' option to testptp to open the PHC in readonly mode instead of
+the default read-write mode. Skip enabling EXTTS if readonly mode is
+requested.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 37 +++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 14 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 2323a3329b298..532fb6a5d0591 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -140,6 +140,7 @@ static void usage(char *progname)
+ " -H val set output phase to 'val' nanoseconds (requires -p)\n"
+ " -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
+ " -P val enable or disable (val=1|0) the system clock PPS\n"
++ " -r open the ptp clock in readonly mode\n"
+ " -s set the ptp clock time from the system time\n"
+ " -S set the system time from the ptp clock time\n"
+ " -t val shift the ptp clock time by 'val' seconds\n"
+@@ -188,6 +189,7 @@ int main(int argc, char *argv[])
+ int pin_index = -1, pin_func;
+ int pps = -1;
+ int seconds = 0;
++ int readonly = 0;
+ int settime = 0;
+ int channel = -1;
+ clockid_t ext_clockid = CLOCK_REALTIME;
+@@ -200,7 +202,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -252,6 +254,9 @@ int main(int argc, char *argv[])
+ case 'P':
+ pps = atoi(optarg);
+ break;
++ case 'r':
++ readonly = 1;
++ break;
+ case 's':
+ settime = 1;
+ break;
+@@ -308,7 +313,7 @@ int main(int argc, char *argv[])
+ }
+ }
+
+- fd = open(device, O_RDWR);
++ fd = open(device, readonly ? O_RDONLY : O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
+ return -1;
+@@ -434,14 +439,16 @@ int main(int argc, char *argv[])
+ }
+
+ if (extts) {
+- memset(&extts_request, 0, sizeof(extts_request));
+- extts_request.index = index;
+- extts_request.flags = PTP_ENABLE_FEATURE;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
+- extts = 0;
+- } else {
+- puts("external time stamp request okay");
++ if (!readonly) {
++ memset(&extts_request, 0, sizeof(extts_request));
++ extts_request.index = index;
++ extts_request.flags = PTP_ENABLE_FEATURE;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ extts = 0;
++ } else {
++ puts("external time stamp request okay");
++ }
+ }
+ for (; extts; extts--) {
+ cnt = read(fd, &event, sizeof(event));
+@@ -453,10 +460,12 @@ int main(int argc, char *argv[])
+ event.t.sec, event.t.nsec);
+ fflush(stdout);
+ }
+- /* Disable the feature again. */
+- extts_request.flags = 0;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
++ if (!readonly) {
++ /* Disable the feature again. */
++ extts_request.flags = 0;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ }
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From 6b4826de6a1da728b0778927f745addf49420e5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Jun 2023 14:14:55 -0700
+Subject: testptp: Add support for testing ptp_clock_info .adjphase callback
+
+From: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+
+[ Upstream commit 3a9a9a6139286584d1199f555fa4f96f592a3217 ]
+
+Invoke clock_adjtime syscall with tx.modes set with ADJ_OFFSET when testptp
+is invoked with a phase adjustment offset value. Support seconds and
+nanoseconds for the offset value.
+
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Richard Cochran <richardcochran@gmail.com>
+Cc: Maciek Machnikowski <maciek@machnikowski.net>
+Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index cfa9562f3cd83..9c3d36a40309b 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -134,6 +134,7 @@ static void usage(char *progname)
+ " 1 - external time stamp\n"
+ " 2 - periodic output\n"
+ " -n val shift the ptp clock time by 'val' nanoseconds\n"
++ " -o val phase offset (in nanoseconds) to be provided to the PHC servo\n"
+ " -p val enable output with a period of 'val' nanoseconds\n"
+ " -H val set output phase to 'val' nanoseconds (requires -p)\n"
+ " -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
+@@ -167,6 +168,7 @@ int main(int argc, char *argv[])
+ int adjfreq = 0x7fffffff;
+ int adjtime = 0;
+ int adjns = 0;
++ int adjphase = 0;
+ int capabilities = 0;
+ int extts = 0;
+ int flagtest = 0;
+@@ -188,7 +190,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:p:P:sSt:T:w:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -228,6 +230,9 @@ int main(int argc, char *argv[])
+ case 'n':
+ adjns = atoi(optarg);
+ break;
++ case 'o':
++ adjphase = atoi(optarg);
++ break;
+ case 'p':
+ perout = atoll(optarg);
+ break;
+@@ -327,6 +332,18 @@ int main(int argc, char *argv[])
+ }
+ }
+
++ if (adjphase) {
++ memset(&tx, 0, sizeof(tx));
++ tx.modes = ADJ_OFFSET | ADJ_NANO;
++ tx.offset = adjphase;
++
++ if (clock_adjtime(clkid, &tx) < 0) {
++ perror("clock_adjtime");
++ } else {
++ puts("phase adjustment okay");
++ }
++ }
++
+ if (gettime) {
+ if (clock_gettime(clkid, &ts)) {
+ perror("clock_gettime");
+--
+2.51.0
+
--- /dev/null
+From 10dedf083193658514c6f8a9125a610181cf5c24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:36:22 +0100
+Subject: arm64: dts: qcom: sc8280xp: Add missing VDD_MXC links
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 868b979c5328b867c95a6d5a93ba13ad0d3cd2f1 ]
+
+To make sure that power rail is voted for, wire it up to its consumers.
+
+Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-3-46cdf47a829e@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index b1e0e51a55829..c10ee18cb611a 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -5218,8 +5218,12 @@ remoteproc_nsp0: remoteproc@1b300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp0_mem>;
+
+@@ -5349,8 +5353,12 @@ remoteproc_nsp1: remoteproc@21300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp1_mem>;
+
+--
+2.51.0
+
--- /dev/null
+From 4262526299d9c7a9f7f5cfd46e7b6de6ac12b0a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 18:37:56 +0000
+Subject: btrfs: fix missing fields in superblock backup with BLOCK_GROUP_TREE
+
+From: Mark Harmstone <mark@harmstone.com>
+
+[ Upstream commit 1d8f69f453c2e8a2d99b158e58e02ed65031fa6d ]
+
+When the BLOCK_GROUP_TREE compat_ro flag is set, the extent root and
+csum root fields are getting missed.
+
+This is because EXTENT_TREE_V2 treated these differently, and when
+they were split off this special-casing was mistakenly assigned to
+BGT rather than the rump EXTENT_TREE_V2. There's no reason why the
+existence of the block group tree should mean that we don't record the
+details of the last commit's extent root and csum root.
+
+Fix the code in backup_super_roots() so that the correct check gets
+made.
+
+Fixes: 1c56ab991903 ("btrfs: separate BLOCK_GROUP_TREE compat RO flag from EXTENT_TREE_V2")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Mark Harmstone <mark@harmstone.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/disk-io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 39fe4385ed361..93300c3fe0cab 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -1676,7 +1676,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
+ btrfs_set_backup_chunk_root_level(root_backup,
+ btrfs_header_level(info->chunk_root->node));
+
+- if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
++ if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+ struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+ struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+
+--
+2.51.0
+
--- /dev/null
+From b997d4096d5fdf2dfe3d76258f3b314cea7a5393 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Dec 2025 12:14:47 -0800
+Subject: Drivers: hv: Always do Hyper-V panic notification in hv_kmsg_dump()
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+[ Upstream commit 49f49d47af67f8a7b221db1d758fc634242dc91a ]
+
+hv_kmsg_dump() currently skips the panic notification entirely if it
+doesn't get any message bytes to pass to Hyper-V due to an error from
+kmsg_dump_get_buffer(). Skipping the notification is undesirable because
+it leaves the Hyper-V host uncertain about the state of a panic'ed guest.
+
+Fix this by always doing the panic notification, even if bytes_written
+is zero. Also ensure that bytes_written is initialized, which fixes a
+kernel test robot warning. The warning is actually bogus because
+kmsg_dump_get_buffer() happens to set bytes_written even if it fails, and
+in the kernel test robot's CONFIG_PRINTK not set case, hv_kmsg_dump() is
+never called. But do the initialization for robustness and to quiet the
+static checker.
+
+Fixes: 9c318a1d9b50 ("Drivers: hv: move panic report code from vmbus to hv early init code")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/all/202512172103.OcUspn1Z-lkp@intel.com/
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Roman Kisel <vdso@mailbox.org>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/hv_common.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
+index 7a35c82976e0f..f69dd08475114 100644
+--- a/drivers/hv/hv_common.c
++++ b/drivers/hv/hv_common.c
+@@ -218,13 +218,15 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+
+ /*
+ * Write dump contents to the page. No need to synchronize; panic should
+- * be single-threaded.
++ * be single-threaded. Ignore failures from kmsg_dump_get_buffer() since
++ * panic notification should be done even if there is no message data.
++ * Don't assume bytes_written is set in case of failure, so initialize it.
+ */
+ kmsg_dump_rewind(&iter);
+- kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
++ bytes_written = 0;
++ (void)kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
+ &bytes_written);
+- if (!bytes_written)
+- return;
++
+ /*
+ * P3 to contain the physical address of the panic page & P4 to
+ * contain the size of the panic data in that page. Rest of the
+@@ -233,7 +235,7 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+ hv_set_msr(HV_MSR_CRASH_P0, 0);
+ hv_set_msr(HV_MSR_CRASH_P1, 0);
+ hv_set_msr(HV_MSR_CRASH_P2, 0);
+- hv_set_msr(HV_MSR_CRASH_P3, virt_to_phys(hv_panic_page));
++ hv_set_msr(HV_MSR_CRASH_P3, bytes_written ? virt_to_phys(hv_panic_page) : 0);
+ hv_set_msr(HV_MSR_CRASH_P4, bytes_written);
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 32083be4635863999a838cab1c17bcda67fce8f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:36:20 +0100
+Subject: dt-bindings: power: qcom,rpmpd: Add SC8280XP_MXC_AO
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 45e1be5ddec98db71e7481fa7a3005673200d85c ]
+
+Not sure how useful it's gonna be in practice, but the definition is
+missing (unlike the previously-unused SC8280XP_MXC-non-_AO), so add it
+to allow the driver to create the corresponding pmdomain.
+
+Fixes: dbfb5f94e084 ("dt-bindings: power: rpmpd: Add sc8280xp RPMh power-domains")
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-1-46cdf47a829e@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Stable-dep-of: 5bc3e720e725 ("pmdomain: qcom: rpmhpd: Add MXC to SC8280XP")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/power/qcom,rpmhpd.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h
+index 73cceb88953f7..269b73ff866a8 100644
+--- a/include/dt-bindings/power/qcom,rpmhpd.h
++++ b/include/dt-bindings/power/qcom,rpmhpd.h
+@@ -261,5 +261,6 @@
+ #define SC8280XP_NSP 13
+ #define SC8280XP_QPHY 14
+ #define SC8280XP_XO 15
++#define SC8280XP_MXC_AO 16
+
+ #endif
+--
+2.51.0
+
--- /dev/null
+From 2aa686a4313c7774cea4e8de26f642f5307420e0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Jul 2025 21:50:45 +0530
+Subject: dt-bindings: power: qcom,rpmpd: add Turbo L5 corner
+
+From: Akhil P Oommen <akhilpo@oss.qualcomm.com>
+
+[ Upstream commit 1c402295c10891988fb2a6fc658e6e95d4852a20 ]
+
+Update the RPMH level definitions to include TURBO_L5 corner.
+
+Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Akhil P Oommen <akhilpo@oss.qualcomm.com>
+Patchwork: https://patchwork.freedesktop.org/patch/661840/
+Signed-off-by: Rob Clark <robin.clark@oss.qualcomm.com>
+Stable-dep-of: 5bc3e720e725 ("pmdomain: qcom: rpmhpd: Add MXC to SC8280XP")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/power/qcom-rpmpd.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
+index df599bf462207..5bc4735fb3e6e 100644
+--- a/include/dt-bindings/power/qcom-rpmpd.h
++++ b/include/dt-bindings/power/qcom-rpmpd.h
+@@ -240,6 +240,7 @@
+ #define RPMH_REGULATOR_LEVEL_TURBO_L2 432
+ #define RPMH_REGULATOR_LEVEL_TURBO_L3 448
+ #define RPMH_REGULATOR_LEVEL_TURBO_L4 452
++#define RPMH_REGULATOR_LEVEL_TURBO_L5 456
+ #define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
+ #define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
+
+--
+2.51.0
+
--- /dev/null
+From 4cc34a931143c94d2fac250f99b3345a144d554e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Nov 2024 16:24:43 -0800
+Subject: dt-bindings: power: qcom,rpmpd: document the SM8750 RPMh Power
+ Domains
+
+From: Taniya Das <quic_tdas@quicinc.com>
+
+[ Upstream commit 134e9d035d830aabd1121bcda89f7ee9a476d3a3 ]
+
+Document the RPMh Power Domains on the SM8750 Platform.
+
+Signed-off-by: Taniya Das <quic_tdas@quicinc.com>
+Signed-off-by: Jishnu Prakash <quic_jprakash@quicinc.com>
+Signed-off-by: Melody Olvera <quic_molvera@quicinc.com>
+Message-ID: <20241112002444.2802092-2-quic_molvera@quicinc.com>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 5bc3e720e725 ("pmdomain: qcom: rpmhpd: Add MXC to SC8280XP")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/power/qcom,rpmpd.yaml | 1 +
+ include/dt-bindings/power/qcom-rpmpd.h | 2 ++
+ 2 files changed, 3 insertions(+)
+
+diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+index 929b7ef9c1bcd..d55758a759717 100644
+--- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
++++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
+@@ -58,6 +58,7 @@ properties:
+ - qcom,sm8450-rpmhpd
+ - qcom,sm8550-rpmhpd
+ - qcom,sm8650-rpmhpd
++ - qcom,sm8750-rpmhpd
+ - qcom,x1e80100-rpmhpd
+ - items:
+ - enum:
+diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
+index 608087fb9a3d9..df599bf462207 100644
+--- a/include/dt-bindings/power/qcom-rpmpd.h
++++ b/include/dt-bindings/power/qcom-rpmpd.h
+@@ -218,6 +218,7 @@
+ /* SDM845 Power Domain performance levels */
+ #define RPMH_REGULATOR_LEVEL_RETENTION 16
+ #define RPMH_REGULATOR_LEVEL_MIN_SVS 48
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
+ #define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
+ #define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
+ #define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
+@@ -238,6 +239,7 @@
+ #define RPMH_REGULATOR_LEVEL_TURBO_L1 416
+ #define RPMH_REGULATOR_LEVEL_TURBO_L2 432
+ #define RPMH_REGULATOR_LEVEL_TURBO_L3 448
++#define RPMH_REGULATOR_LEVEL_TURBO_L4 452
+ #define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
+ #define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
+
+--
+2.51.0
+
--- /dev/null
+From 509be6ced941d79e576d52992a07f26cfe184821 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Jul 2025 19:13:39 +0300
+Subject: dt-bindings: power: qcom-rpmpd: split RPMh domains definitions
+
+From: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+
+[ Upstream commit dcb8d01b65fb5a891ddbbedcbe6eff0b8ec37867 ]
+
+Historically both RPM and RPMh domain definitions were a part of the
+same, qcom-rpmpd.h header. Now as we have a separate header for RPMh
+definitions, qcom,rpmhpd.h, move all RPMh power domain definitions to
+that header.
+
+Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Acked-by: Rob Herring (Arm) <robh@kernel.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Bjorn Andersson <andersson@kernel.org>
+Link: https://lore.kernel.org/r/20250718-rework-rpmhpd-rpmpd-v1-1-eedca108e540@oss.qualcomm.com
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Stable-dep-of: 5bc3e720e725 ("pmdomain: qcom: rpmhpd: Add MXC to SC8280XP")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/dt-bindings/power/qcom,rpmhpd.h | 233 ++++++++++++++++++++++++
+ include/dt-bindings/power/qcom-rpmpd.h | 228 +----------------------
+ 2 files changed, 234 insertions(+), 227 deletions(-)
+
+diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h
+index e54ffa3614515..73cceb88953f7 100644
+--- a/include/dt-bindings/power/qcom,rpmhpd.h
++++ b/include/dt-bindings/power/qcom,rpmhpd.h
+@@ -29,4 +29,237 @@
+ #define RPMHPD_NSP2 19
+ #define RPMHPD_GMXC 20
+
++/* RPMh Power Domain performance levels */
++#define RPMH_REGULATOR_LEVEL_RETENTION 16
++#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
++#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
++#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96
++#define RPMH_REGULATOR_LEVEL_SVS 128
++#define RPMH_REGULATOR_LEVEL_SVS_L0 144
++#define RPMH_REGULATOR_LEVEL_SVS_L1 192
++#define RPMH_REGULATOR_LEVEL_SVS_L2 224
++#define RPMH_REGULATOR_LEVEL_NOM 256
++#define RPMH_REGULATOR_LEVEL_NOM_L0 288
++#define RPMH_REGULATOR_LEVEL_NOM_L1 320
++#define RPMH_REGULATOR_LEVEL_NOM_L2 336
++#define RPMH_REGULATOR_LEVEL_TURBO 384
++#define RPMH_REGULATOR_LEVEL_TURBO_L0 400
++#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
++#define RPMH_REGULATOR_LEVEL_TURBO_L2 432
++#define RPMH_REGULATOR_LEVEL_TURBO_L3 448
++#define RPMH_REGULATOR_LEVEL_TURBO_L4 452
++#define RPMH_REGULATOR_LEVEL_TURBO_L5 456
++#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
++#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
++
++/*
++ * Platform-specific power domain bindings. Don't add new entries here, use
++ * RPMHPD_* above.
++ */
++
++/* SA8775P Power Domain Indexes */
++#define SA8775P_CX 0
++#define SA8775P_CX_AO 1
++#define SA8775P_DDR 2
++#define SA8775P_EBI 3
++#define SA8775P_GFX 4
++#define SA8775P_LCX 5
++#define SA8775P_LMX 6
++#define SA8775P_MMCX 7
++#define SA8775P_MMCX_AO 8
++#define SA8775P_MSS 9
++#define SA8775P_MX 10
++#define SA8775P_MX_AO 11
++#define SA8775P_MXC 12
++#define SA8775P_MXC_AO 13
++#define SA8775P_NSP0 14
++#define SA8775P_NSP1 15
++#define SA8775P_XO 16
++
++/* SDM670 Power Domain Indexes */
++#define SDM670_MX 0
++#define SDM670_MX_AO 1
++#define SDM670_CX 2
++#define SDM670_CX_AO 3
++#define SDM670_LMX 4
++#define SDM670_LCX 5
++#define SDM670_GFX 6
++#define SDM670_MSS 7
++
++/* SDM845 Power Domain Indexes */
++#define SDM845_EBI 0
++#define SDM845_MX 1
++#define SDM845_MX_AO 2
++#define SDM845_CX 3
++#define SDM845_CX_AO 4
++#define SDM845_LMX 5
++#define SDM845_LCX 6
++#define SDM845_GFX 7
++#define SDM845_MSS 8
++
++/* SDX55 Power Domain Indexes */
++#define SDX55_MSS 0
++#define SDX55_MX 1
++#define SDX55_CX 2
++
++/* SDX65 Power Domain Indexes */
++#define SDX65_MSS 0
++#define SDX65_MX 1
++#define SDX65_MX_AO 2
++#define SDX65_CX 3
++#define SDX65_CX_AO 4
++#define SDX65_MXC 5
++
++/* SM6350 Power Domain Indexes */
++#define SM6350_CX 0
++#define SM6350_GFX 1
++#define SM6350_LCX 2
++#define SM6350_LMX 3
++#define SM6350_MSS 4
++#define SM6350_MX 5
++
++/* SM8150 Power Domain Indexes */
++#define SM8150_MSS 0
++#define SM8150_EBI 1
++#define SM8150_LMX 2
++#define SM8150_LCX 3
++#define SM8150_GFX 4
++#define SM8150_MX 5
++#define SM8150_MX_AO 6
++#define SM8150_CX 7
++#define SM8150_CX_AO 8
++#define SM8150_MMCX 9
++#define SM8150_MMCX_AO 10
++
++/* SA8155P is a special case, kept for backwards compatibility */
++#define SA8155P_CX SM8150_CX
++#define SA8155P_CX_AO SM8150_CX_AO
++#define SA8155P_EBI SM8150_EBI
++#define SA8155P_GFX SM8150_GFX
++#define SA8155P_MSS SM8150_MSS
++#define SA8155P_MX SM8150_MX
++#define SA8155P_MX_AO SM8150_MX_AO
++
++/* SM8250 Power Domain Indexes */
++#define SM8250_CX 0
++#define SM8250_CX_AO 1
++#define SM8250_EBI 2
++#define SM8250_GFX 3
++#define SM8250_LCX 4
++#define SM8250_LMX 5
++#define SM8250_MMCX 6
++#define SM8250_MMCX_AO 7
++#define SM8250_MX 8
++#define SM8250_MX_AO 9
++
++/* SM8350 Power Domain Indexes */
++#define SM8350_CX 0
++#define SM8350_CX_AO 1
++#define SM8350_EBI 2
++#define SM8350_GFX 3
++#define SM8350_LCX 4
++#define SM8350_LMX 5
++#define SM8350_MMCX 6
++#define SM8350_MMCX_AO 7
++#define SM8350_MX 8
++#define SM8350_MX_AO 9
++#define SM8350_MXC 10
++#define SM8350_MXC_AO 11
++#define SM8350_MSS 12
++
++/* SM8450 Power Domain Indexes */
++#define SM8450_CX 0
++#define SM8450_CX_AO 1
++#define SM8450_EBI 2
++#define SM8450_GFX 3
++#define SM8450_LCX 4
++#define SM8450_LMX 5
++#define SM8450_MMCX 6
++#define SM8450_MMCX_AO 7
++#define SM8450_MX 8
++#define SM8450_MX_AO 9
++#define SM8450_MXC 10
++#define SM8450_MXC_AO 11
++#define SM8450_MSS 12
++
++/* SM8550 Power Domain Indexes */
++#define SM8550_CX 0
++#define SM8550_CX_AO 1
++#define SM8550_EBI 2
++#define SM8550_GFX 3
++#define SM8550_LCX 4
++#define SM8550_LMX 5
++#define SM8550_MMCX 6
++#define SM8550_MMCX_AO 7
++#define SM8550_MX 8
++#define SM8550_MX_AO 9
++#define SM8550_MXC 10
++#define SM8550_MXC_AO 11
++#define SM8550_MSS 12
++#define SM8550_NSP 13
++
++/* QDU1000/QRU1000 Power Domain Indexes */
++#define QDU1000_EBI 0
++#define QDU1000_MSS 1
++#define QDU1000_CX 2
++#define QDU1000_MX 3
++
++/* SC7180 Power Domain Indexes */
++#define SC7180_CX 0
++#define SC7180_CX_AO 1
++#define SC7180_GFX 2
++#define SC7180_MX 3
++#define SC7180_MX_AO 4
++#define SC7180_LMX 5
++#define SC7180_LCX 6
++#define SC7180_MSS 7
++
++/* SC7280 Power Domain Indexes */
++#define SC7280_CX 0
++#define SC7280_CX_AO 1
++#define SC7280_EBI 2
++#define SC7280_GFX 3
++#define SC7280_MX 4
++#define SC7280_MX_AO 5
++#define SC7280_LMX 6
++#define SC7280_LCX 7
++#define SC7280_MSS 8
++
++/* SC8180X Power Domain Indexes */
++#define SC8180X_CX 0
++#define SC8180X_CX_AO 1
++#define SC8180X_EBI 2
++#define SC8180X_GFX 3
++#define SC8180X_LCX 4
++#define SC8180X_LMX 5
++#define SC8180X_MMCX 6
++#define SC8180X_MMCX_AO 7
++#define SC8180X_MSS 8
++#define SC8180X_MX 9
++#define SC8180X_MX_AO 10
++
++/* SC8280XP Power Domain Indexes */
++#define SC8280XP_CX 0
++#define SC8280XP_CX_AO 1
++#define SC8280XP_DDR 2
++#define SC8280XP_EBI 3
++#define SC8280XP_GFX 4
++#define SC8280XP_LCX 5
++#define SC8280XP_LMX 6
++#define SC8280XP_MMCX 7
++#define SC8280XP_MMCX_AO 8
++#define SC8280XP_MSS 9
++#define SC8280XP_MX 10
++#define SC8280XP_MXC 12
++#define SC8280XP_MX_AO 11
++#define SC8280XP_NSP 13
++#define SC8280XP_QPHY 14
++#define SC8280XP_XO 15
++
+ #endif
+diff --git a/include/dt-bindings/power/qcom-rpmpd.h b/include/dt-bindings/power/qcom-rpmpd.h
+index 5bc4735fb3e6e..109d450978f3d 100644
+--- a/include/dt-bindings/power/qcom-rpmpd.h
++++ b/include/dt-bindings/power/qcom-rpmpd.h
+@@ -4,66 +4,7 @@
+ #ifndef _DT_BINDINGS_POWER_QCOM_RPMPD_H
+ #define _DT_BINDINGS_POWER_QCOM_RPMPD_H
+
+-/* SA8775P Power Domain Indexes */
+-#define SA8775P_CX 0
+-#define SA8775P_CX_AO 1
+-#define SA8775P_DDR 2
+-#define SA8775P_EBI 3
+-#define SA8775P_GFX 4
+-#define SA8775P_LCX 5
+-#define SA8775P_LMX 6
+-#define SA8775P_MMCX 7
+-#define SA8775P_MMCX_AO 8
+-#define SA8775P_MSS 9
+-#define SA8775P_MX 10
+-#define SA8775P_MX_AO 11
+-#define SA8775P_MXC 12
+-#define SA8775P_MXC_AO 13
+-#define SA8775P_NSP0 14
+-#define SA8775P_NSP1 15
+-#define SA8775P_XO 16
+-
+-/* SDM670 Power Domain Indexes */
+-#define SDM670_MX 0
+-#define SDM670_MX_AO 1
+-#define SDM670_CX 2
+-#define SDM670_CX_AO 3
+-#define SDM670_LMX 4
+-#define SDM670_LCX 5
+-#define SDM670_GFX 6
+-#define SDM670_MSS 7
+-
+-/* SDM845 Power Domain Indexes */
+-#define SDM845_EBI 0
+-#define SDM845_MX 1
+-#define SDM845_MX_AO 2
+-#define SDM845_CX 3
+-#define SDM845_CX_AO 4
+-#define SDM845_LMX 5
+-#define SDM845_LCX 6
+-#define SDM845_GFX 7
+-#define SDM845_MSS 8
+-
+-/* SDX55 Power Domain Indexes */
+-#define SDX55_MSS 0
+-#define SDX55_MX 1
+-#define SDX55_CX 2
+-
+-/* SDX65 Power Domain Indexes */
+-#define SDX65_MSS 0
+-#define SDX65_MX 1
+-#define SDX65_MX_AO 2
+-#define SDX65_CX 3
+-#define SDX65_CX_AO 4
+-#define SDX65_MXC 5
+-
+-/* SM6350 Power Domain Indexes */
+-#define SM6350_CX 0
+-#define SM6350_GFX 1
+-#define SM6350_LCX 2
+-#define SM6350_LMX 3
+-#define SM6350_MSS 4
+-#define SM6350_MX 5
++#include <dt-bindings/power/qcom,rpmhpd.h>
+
+ /* SM6350 Power Domain Indexes */
+ #define SM6375_VDDCX 0
+@@ -77,173 +18,6 @@
+ #define SM6375_VDD_LPI_CX 8
+ #define SM6375_VDD_LPI_MX 9
+
+-/* SM8150 Power Domain Indexes */
+-#define SM8150_MSS 0
+-#define SM8150_EBI 1
+-#define SM8150_LMX 2
+-#define SM8150_LCX 3
+-#define SM8150_GFX 4
+-#define SM8150_MX 5
+-#define SM8150_MX_AO 6
+-#define SM8150_CX 7
+-#define SM8150_CX_AO 8
+-#define SM8150_MMCX 9
+-#define SM8150_MMCX_AO 10
+-
+-/* SA8155P is a special case, kept for backwards compatibility */
+-#define SA8155P_CX SM8150_CX
+-#define SA8155P_CX_AO SM8150_CX_AO
+-#define SA8155P_EBI SM8150_EBI
+-#define SA8155P_GFX SM8150_GFX
+-#define SA8155P_MSS SM8150_MSS
+-#define SA8155P_MX SM8150_MX
+-#define SA8155P_MX_AO SM8150_MX_AO
+-
+-/* SM8250 Power Domain Indexes */
+-#define SM8250_CX 0
+-#define SM8250_CX_AO 1
+-#define SM8250_EBI 2
+-#define SM8250_GFX 3
+-#define SM8250_LCX 4
+-#define SM8250_LMX 5
+-#define SM8250_MMCX 6
+-#define SM8250_MMCX_AO 7
+-#define SM8250_MX 8
+-#define SM8250_MX_AO 9
+-
+-/* SM8350 Power Domain Indexes */
+-#define SM8350_CX 0
+-#define SM8350_CX_AO 1
+-#define SM8350_EBI 2
+-#define SM8350_GFX 3
+-#define SM8350_LCX 4
+-#define SM8350_LMX 5
+-#define SM8350_MMCX 6
+-#define SM8350_MMCX_AO 7
+-#define SM8350_MX 8
+-#define SM8350_MX_AO 9
+-#define SM8350_MXC 10
+-#define SM8350_MXC_AO 11
+-#define SM8350_MSS 12
+-
+-/* SM8450 Power Domain Indexes */
+-#define SM8450_CX 0
+-#define SM8450_CX_AO 1
+-#define SM8450_EBI 2
+-#define SM8450_GFX 3
+-#define SM8450_LCX 4
+-#define SM8450_LMX 5
+-#define SM8450_MMCX 6
+-#define SM8450_MMCX_AO 7
+-#define SM8450_MX 8
+-#define SM8450_MX_AO 9
+-#define SM8450_MXC 10
+-#define SM8450_MXC_AO 11
+-#define SM8450_MSS 12
+-
+-/* SM8550 Power Domain Indexes */
+-#define SM8550_CX 0
+-#define SM8550_CX_AO 1
+-#define SM8550_EBI 2
+-#define SM8550_GFX 3
+-#define SM8550_LCX 4
+-#define SM8550_LMX 5
+-#define SM8550_MMCX 6
+-#define SM8550_MMCX_AO 7
+-#define SM8550_MX 8
+-#define SM8550_MX_AO 9
+-#define SM8550_MXC 10
+-#define SM8550_MXC_AO 11
+-#define SM8550_MSS 12
+-#define SM8550_NSP 13
+-
+-/* QDU1000/QRU1000 Power Domain Indexes */
+-#define QDU1000_EBI 0
+-#define QDU1000_MSS 1
+-#define QDU1000_CX 2
+-#define QDU1000_MX 3
+-
+-/* SC7180 Power Domain Indexes */
+-#define SC7180_CX 0
+-#define SC7180_CX_AO 1
+-#define SC7180_GFX 2
+-#define SC7180_MX 3
+-#define SC7180_MX_AO 4
+-#define SC7180_LMX 5
+-#define SC7180_LCX 6
+-#define SC7180_MSS 7
+-
+-/* SC7280 Power Domain Indexes */
+-#define SC7280_CX 0
+-#define SC7280_CX_AO 1
+-#define SC7280_EBI 2
+-#define SC7280_GFX 3
+-#define SC7280_MX 4
+-#define SC7280_MX_AO 5
+-#define SC7280_LMX 6
+-#define SC7280_LCX 7
+-#define SC7280_MSS 8
+-
+-/* SC8180X Power Domain Indexes */
+-#define SC8180X_CX 0
+-#define SC8180X_CX_AO 1
+-#define SC8180X_EBI 2
+-#define SC8180X_GFX 3
+-#define SC8180X_LCX 4
+-#define SC8180X_LMX 5
+-#define SC8180X_MMCX 6
+-#define SC8180X_MMCX_AO 7
+-#define SC8180X_MSS 8
+-#define SC8180X_MX 9
+-#define SC8180X_MX_AO 10
+-
+-/* SC8280XP Power Domain Indexes */
+-#define SC8280XP_CX 0
+-#define SC8280XP_CX_AO 1
+-#define SC8280XP_DDR 2
+-#define SC8280XP_EBI 3
+-#define SC8280XP_GFX 4
+-#define SC8280XP_LCX 5
+-#define SC8280XP_LMX 6
+-#define SC8280XP_MMCX 7
+-#define SC8280XP_MMCX_AO 8
+-#define SC8280XP_MSS 9
+-#define SC8280XP_MX 10
+-#define SC8280XP_MXC 12
+-#define SC8280XP_MX_AO 11
+-#define SC8280XP_NSP 13
+-#define SC8280XP_QPHY 14
+-#define SC8280XP_XO 15
+-
+-/* SDM845 Power Domain performance levels */
+-#define RPMH_REGULATOR_LEVEL_RETENTION 16
+-#define RPMH_REGULATOR_LEVEL_MIN_SVS 48
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS_D3 50
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS_D2 52
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS_D1 56
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS_D0 60
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS 64
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS_P1 72
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS_L1 80
+-#define RPMH_REGULATOR_LEVEL_LOW_SVS_L2 96
+-#define RPMH_REGULATOR_LEVEL_SVS 128
+-#define RPMH_REGULATOR_LEVEL_SVS_L0 144
+-#define RPMH_REGULATOR_LEVEL_SVS_L1 192
+-#define RPMH_REGULATOR_LEVEL_SVS_L2 224
+-#define RPMH_REGULATOR_LEVEL_NOM 256
+-#define RPMH_REGULATOR_LEVEL_NOM_L0 288
+-#define RPMH_REGULATOR_LEVEL_NOM_L1 320
+-#define RPMH_REGULATOR_LEVEL_NOM_L2 336
+-#define RPMH_REGULATOR_LEVEL_TURBO 384
+-#define RPMH_REGULATOR_LEVEL_TURBO_L0 400
+-#define RPMH_REGULATOR_LEVEL_TURBO_L1 416
+-#define RPMH_REGULATOR_LEVEL_TURBO_L2 432
+-#define RPMH_REGULATOR_LEVEL_TURBO_L3 448
+-#define RPMH_REGULATOR_LEVEL_TURBO_L4 452
+-#define RPMH_REGULATOR_LEVEL_TURBO_L5 456
+-#define RPMH_REGULATOR_LEVEL_SUPER_TURBO 464
+-#define RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR 480
+-
+ /* MDM9607 Power Domains */
+ #define MDM9607_VDDCX 0
+ #define MDM9607_VDDCX_AO 1
+--
+2.51.0
+
--- /dev/null
+From 3debc3b8eef2354d64f1934c372fa8442cd7decf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:36:21 +0100
+Subject: pmdomain: qcom: rpmhpd: Add MXC to SC8280XP
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 5bc3e720e725cd5fa34875fa1e5434d565858067 ]
+
+This was apparently accounted for in dt-bindings, but never made its
+way into the driver.
+
+Fix it for SC8280XP and its VDD_GFX-less cousin, SA8540P.
+
+Fixes: f68f1cb3437d ("soc: qcom: rpmhpd: add sc8280xp & sa8540p rpmh power-domains")
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-2-46cdf47a829e@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pmdomain/qcom/rpmhpd.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c
+index 65505e1e22198..88cb836e6f67a 100644
+--- a/drivers/pmdomain/qcom/rpmhpd.c
++++ b/drivers/pmdomain/qcom/rpmhpd.c
+@@ -228,6 +228,8 @@ static struct rpmhpd *sa8540p_rpmhpds[] = {
+ [SC8280XP_MMCX_AO] = &mmcx_ao,
+ [SC8280XP_MX] = &mx,
+ [SC8280XP_MX_AO] = &mx_ao,
++ [SC8280XP_MXC] = &mxc,
++ [SC8280XP_MXC_AO] = &mxc_ao,
+ [SC8280XP_NSP] = &nsp,
+ };
+
+@@ -593,6 +595,8 @@ static struct rpmhpd *sc8280xp_rpmhpds[] = {
+ [SC8280XP_MMCX_AO] = &mmcx_ao,
+ [SC8280XP_MX] = &mx,
+ [SC8280XP_MX_AO] = &mx_ao,
++ [SC8280XP_MXC] = &mxc,
++ [SC8280XP_MXC_AO] = &mxc_ao,
+ [SC8280XP_NSP] = &nsp,
+ [SC8280XP_QPHY] = &qphy,
+ };
+--
+2.51.0
+
--- /dev/null
+From d1d9024dd2cc024bc636afdf9d44d773a4be348b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:43 +0200
+Subject: posix-clock: Store file pointer in struct posix_clock_context
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit e859d375d1694488015e6804bfeea527a0b25b9f ]
+
+File descriptor based pc_clock_*() operations of dynamic posix clocks
+have access to the file pointer and implement permission checks in the
+generic code before invoking the relevant dynamic clock callback.
+
+Character device operations (open, read, poll, ioctl) do not implement a
+generic permission control and the dynamic clock callbacks have no
+access to the file pointer to implement them.
+
+Extend struct posix_clock_context with a struct file pointer and
+initialize it in posix_clock_open(), so that all dynamic clock callbacks
+can access it.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/posix-clock.h | 6 +++++-
+ kernel/time/posix-clock.c | 1 +
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index ef8619f489203..a500d3160fe8c 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -95,10 +95,13 @@ struct posix_clock {
+ * struct posix_clock_context - represents clock file operations context
+ *
+ * @clk: Pointer to the clock
++ * @fp: Pointer to the file used to open the clock
+ * @private_clkdata: Pointer to user data
+ *
+ * Drivers should use struct posix_clock_context during specific character
+- * device file operation methods to access the posix clock.
++ * device file operation methods to access the posix clock. In particular,
++ * the file pointer can be used to verify correct access mode for ioctl()
++ * calls.
+ *
+ * Drivers can store a private data structure during the open operation
+ * if they have specific information that is required in other file
+@@ -106,6 +109,7 @@ struct posix_clock {
+ */
+ struct posix_clock_context {
+ struct posix_clock *clk;
++ struct file *fp;
+ void *private_clkdata;
+ };
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 1af0bb2cc45c0..4e114e34a6e0a 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,6 +129,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
++ pccontext->fp = fp;
+ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+ if (err) {
+--
+2.51.0
+
--- /dev/null
+From 103632c1eacc5834245305b398f3f994be426fff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:44 +0200
+Subject: ptp: Add PHC file mode checks. Allow RO adjtime() without
+ FMODE_WRITE.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit b4e53b15c04e3852949003752f48f7a14ae39e86 ]
+
+Many devices implement highly accurate clocks, which the kernel manages
+as PTP Hardware Clocks (PHCs). Userspace applications rely on these
+clocks to timestamp events, trace workload execution, correlate
+timescales across devices, and keep various clocks in sync.
+
+The kernel’s current implementation of PTP clocks does not enforce file
+permissions checks for most device operations except for POSIX clock
+operations, where file mode is verified in the POSIX layer before
+forwarding the call to the PTP subsystem. Consequently, it is common
+practice to not give unprivileged userspace applications any access to
+PTP clocks whatsoever by giving the PTP chardevs 600 permissions. An
+example of users running into this limitation is documented in [1].
+Additionally, POSIX layer requires WRITE permission even for readonly
+adjtime() calls which are used in PTP layer to return current frequency
+offset applied to the PHC.
+
+Add permission checks for functions that modify the state of a PTP
+device. Continue enforcing permission checks for POSIX clock operations
+(settime, adjtime) in the POSIX layer. Only require WRITE access for
+dynamic clocks adjtime() if any flags are set in the modes field.
+
+[1] https://lists.nwtime.org/sympa/arc/linuxptp-users/2024-01/msg00036.html
+
+Changes in v4:
+- Require FMODE_WRITE in ajtime() only for calls modifying the clock in
+ any way.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 16 ++++++++++++++++
+ kernel/time/posix-clock.c | 2 +-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index bf6468c56419c..4380e6ddb8495 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -205,6 +205,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_EXTTS_REQUEST:
+ case PTP_EXTTS_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.extts, (void __user *)arg,
+@@ -246,6 +250,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PEROUT_REQUEST:
+ case PTP_PEROUT_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.perout, (void __user *)arg,
+@@ -314,6 +322,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_ENABLE_PPS:
+ case PTP_ENABLE_PPS2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (!capable(CAP_SYS_TIME))
+@@ -456,6 +468,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PIN_SETFUNC:
+ case PTP_PIN_SETFUNC2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
+ err = -EFAULT;
+ break;
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 4e114e34a6e0a..fe963384d5c2a 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -252,7 +252,7 @@ static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx)
+ if (err)
+ return err;
+
+- if ((cd.fp->f_mode & FMODE_WRITE) == 0) {
++ if (tx->modes && (cd.fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ goto out;
+ }
+--
+2.51.0
+
--- /dev/null
+From fac67861c32fd7dd620cc6a23109ecc82abde750 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 03:15:06 -0700
+Subject: selftest/ptp: update ptp selftest to exercise the gettimex options
+
+From: Mahesh Bandewar <maheshb@google.com>
+
+[ Upstream commit 3d07b691ee707c00afaf365440975e81bb96cd9b ]
+
+With the inclusion of commit c259acab839e ("ptp/ioctl: support
+MONOTONIC{,_RAW} timestamps for PTP_SYS_OFFSET_EXTENDED") clock_gettime()
+now allows retrieval of pre/post timestamps for CLOCK_MONOTONIC and
+CLOCK_MONOTONIC_RAW timebases along with the previously supported
+CLOCK_REALTIME.
+
+This patch adds a command line option 'y' to the testptp program to
+choose one of the allowed timebases [realtime aka system, monotonic,
+and monotonic-raw).
+
+Signed-off-by: Mahesh Bandewar <maheshb@google.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://patch.msgid.link/20241003101506.769418-1-maheshb@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 62 ++++++++++++++++++++++++---
+ 1 file changed, 57 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 011252fe238c8..58064151f2c89 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -146,6 +146,7 @@ static void usage(char *progname)
+ " -T val set the ptp clock time to 'val' seconds\n"
+ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
+ " -X get a ptp clock cross timestamp\n"
++ " -y val pre/post tstamp timebase to use {realtime|monotonic|monotonic-raw}\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+ progname, PTP_MAX_SAMPLES);
+ }
+@@ -189,6 +190,7 @@ int main(int argc, char *argv[])
+ int seconds = 0;
+ int settime = 0;
+ int channel = -1;
++ clockid_t ext_clockid = CLOCK_REALTIME;
+
+ int64_t t1, t2, tp;
+ int64_t interval, offset;
+@@ -198,7 +200,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -278,6 +280,21 @@ int main(int argc, char *argv[])
+ case 'X':
+ getcross = 1;
+ break;
++ case 'y':
++ if (!strcasecmp(optarg, "realtime"))
++ ext_clockid = CLOCK_REALTIME;
++ else if (!strcasecmp(optarg, "monotonic"))
++ ext_clockid = CLOCK_MONOTONIC;
++ else if (!strcasecmp(optarg, "monotonic-raw"))
++ ext_clockid = CLOCK_MONOTONIC_RAW;
++ else {
++ fprintf(stderr,
++ "type needs to be realtime, monotonic or monotonic-raw; was given %s\n",
++ optarg);
++ return -1;
++ }
++ break;
++
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -566,6 +583,7 @@ int main(int argc, char *argv[])
+ }
+
+ soe->n_samples = getextended;
++ soe->clockid = ext_clockid;
+
+ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) {
+ perror("PTP_SYS_OFFSET_EXTENDED");
+@@ -574,12 +592,46 @@ int main(int argc, char *argv[])
+ getextended);
+
+ for (i = 0; i < getextended; i++) {
+- printf("sample #%2d: system time before: %lld.%09u\n",
+- i, soe->ts[i][0].sec, soe->ts[i][0].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf("sample #%2d: real time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf("sample #%2d: monotonic time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf("sample #%2d: monotonic-raw time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ default:
++ break;
++ }
+ printf(" phc time: %lld.%09u\n",
+ soe->ts[i][1].sec, soe->ts[i][1].nsec);
+- printf(" system time after: %lld.%09u\n",
+- soe->ts[i][2].sec, soe->ts[i][2].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf(" real time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf(" monotonic time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf(" monotonic-raw time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ default:
++ break;
++ }
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+posix-clock-store-file-pointer-in-struct-posix_clock.patch
+ptp-add-phc-file-mode-checks.-allow-ro-adjtime-witho.patch
+selftest-ptp-update-ptp-selftest-to-exercise-the-get.patch
+testptp-add-option-to-open-phc-in-readonly-mode.patch
+dt-bindings-power-qcom-rpmpd-document-the-sm8750-rpm.patch
+dt-bindings-power-qcom-rpmpd-add-turbo-l5-corner.patch
+dt-bindings-power-qcom-rpmpd-split-rpmh-domains-defi.patch
+dt-bindings-power-qcom-rpmpd-add-sc8280xp_mxc_ao.patch
+pmdomain-qcom-rpmhpd-add-mxc-to-sc8280xp.patch
+arm64-dts-qcom-sc8280xp-add-missing-vdd_mxc-links.patch
+drivers-hv-always-do-hyper-v-panic-notification-in-h.patch
+btrfs-fix-missing-fields-in-superblock-backup-with-b.patch
--- /dev/null
+From 3613f2fa83b0db4b9691b4163361b45ab2a59d02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:45 +0200
+Subject: testptp: Add option to open PHC in readonly mode
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit 76868642e42795353106197abf9c607ad80f4c9e ]
+
+PTP Hardware Clocks no longer require WRITE permission to perform
+readonly operations, such as listing device capabilities or listening to
+EXTTS events once they have been enabled by a process with WRITE
+permissions.
+
+Add '-r' option to testptp to open the PHC in readonly mode instead of
+the default read-write mode. Skip enabling EXTTS if readonly mode is
+requested.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 37 +++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 14 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 58064151f2c89..edc08a4433fd4 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -140,6 +140,7 @@ static void usage(char *progname)
+ " -H val set output phase to 'val' nanoseconds (requires -p)\n"
+ " -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
+ " -P val enable or disable (val=1|0) the system clock PPS\n"
++ " -r open the ptp clock in readonly mode\n"
+ " -s set the ptp clock time from the system time\n"
+ " -S set the system time from the ptp clock time\n"
+ " -t val shift the ptp clock time by 'val' seconds\n"
+@@ -188,6 +189,7 @@ int main(int argc, char *argv[])
+ int pin_index = -1, pin_func;
+ int pps = -1;
+ int seconds = 0;
++ int readonly = 0;
+ int settime = 0;
+ int channel = -1;
+ clockid_t ext_clockid = CLOCK_REALTIME;
+@@ -200,7 +202,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -252,6 +254,9 @@ int main(int argc, char *argv[])
+ case 'P':
+ pps = atoi(optarg);
+ break;
++ case 'r':
++ readonly = 1;
++ break;
+ case 's':
+ settime = 1;
+ break;
+@@ -308,7 +313,7 @@ int main(int argc, char *argv[])
+ }
+ }
+
+- fd = open(device, O_RDWR);
++ fd = open(device, readonly ? O_RDONLY : O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
+ return -1;
+@@ -436,14 +441,16 @@ int main(int argc, char *argv[])
+ }
+
+ if (extts) {
+- memset(&extts_request, 0, sizeof(extts_request));
+- extts_request.index = index;
+- extts_request.flags = PTP_ENABLE_FEATURE;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
+- extts = 0;
+- } else {
+- puts("external time stamp request okay");
++ if (!readonly) {
++ memset(&extts_request, 0, sizeof(extts_request));
++ extts_request.index = index;
++ extts_request.flags = PTP_ENABLE_FEATURE;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ extts = 0;
++ } else {
++ puts("external time stamp request okay");
++ }
+ }
+ for (; extts; extts--) {
+ cnt = read(fd, &event, sizeof(event));
+@@ -455,10 +462,12 @@ int main(int argc, char *argv[])
+ event.t.sec, event.t.nsec);
+ fflush(stdout);
+ }
+- /* Disable the feature again. */
+- extts_request.flags = 0;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
++ if (!readonly) {
++ /* Disable the feature again. */
++ extts_request.flags = 0;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ }
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From f06d02e4728706b1ebd1c84c3173c9403ae22e84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:36:22 +0100
+Subject: arm64: dts: qcom: sc8280xp: Add missing VDD_MXC links
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 868b979c5328b867c95a6d5a93ba13ad0d3cd2f1 ]
+
+To make sure that power rail is voted for, wire it up to its consumers.
+
+Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-3-46cdf47a829e@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 963ce2362a52e..d89938e17e093 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -5773,8 +5773,12 @@ remoteproc_nsp0: remoteproc@1b300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp0_mem>;
+
+@@ -5904,8 +5908,12 @@ remoteproc_nsp1: remoteproc@21300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp1_mem>;
+
+--
+2.51.0
+
--- /dev/null
+From b344dd198f44fb85579793ab42e55b49f6e872f2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Dec 2025 20:18:55 +0530
+Subject: arm64: dts: qcom: sm8550: Fix compile warnings in USB controller node
+
+From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
+
+[ Upstream commit 9dbc9bed01837717b8ab755cf5067a6f8d35b00f ]
+
+With W=1, the following error comes up:
+
+Warning (avoid_unnecessary_addr_size): /soc@0/usb@a600000: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" or "ranges" property
+
+This is because the child node being removed during flattening and moving
+to latest bindings.
+
+Fixes: 33450878adfc ("arm64: dts: qcom: sm8550: Flatten the USB nodes")
+Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20251203144856.2711440-2-krishna.kurapati@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8550.dtsi | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+index 7724dba75db79..e294dc9c68c9a 100644
+--- a/arch/arm64/boot/dts/qcom/sm8550.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
+@@ -4097,8 +4097,6 @@ usb_dp_qmpphy_dp_in: endpoint {
+ usb_1: usb@a600000 {
+ compatible = "qcom,sm8550-dwc3", "qcom,snps-dwc3";
+ reg = <0x0 0x0a600000 0x0 0xfc100>;
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+ clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+ <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+--
+2.51.0
+
--- /dev/null
+From e7f8559966a905ca028d95e33d13b82c30932a2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Dec 2025 20:18:56 +0530
+Subject: arm64: dts: qcom: sm8650: Fix compile warnings in USB controller node
+
+From: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
+
+[ Upstream commit 1f6ca557088eb96c8c554f853eb7c60862f8a0a8 ]
+
+With W=1, the following error comes up:
+
+Warning (avoid_unnecessary_addr_size): /soc@0/usb@a600000: unnecessary #address-cells/#size-cells without "ranges", "dma-ranges" or child "reg" or "ranges" property
+
+This is because the child node being removed during flattening and moving
+to latest bindings.
+
+Fixes: 77e1f16b9302 ("arm64: dts: qcom: sm8650: Flatten the USB nodes")
+Signed-off-by: Krishna Kurapati <krishna.kurapati@oss.qualcomm.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
+Link: https://lore.kernel.org/r/20251203144856.2711440-3-krishna.kurapati@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sm8650.dtsi | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+index 3b03c13539386..d22a26a416ccc 100644
+--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi
++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
+@@ -5115,9 +5115,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>,
+
+ dma-coherent;
+
+- #address-cells = <1>;
+- #size-cells = <0>;
+-
+ status = "disabled";
+
+ ports {
+--
+2.51.0
+
--- /dev/null
+From 2ad0c8ecebcff29b4fd775e6dc38d8250e9d0e04 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Jan 2026 15:15:13 +0800
+Subject: arm64: dts: rockchip: Fix wrong register range of rk3576 gpu
+
+From: Chaoyi Chen <chaoyi.chen@rock-chips.com>
+
+[ Upstream commit 955b263c421c6fe5075369c52199f278289ec8c4 ]
+
+According to RK3576 TRM part1 Table 1-1 Address Mapping, the size of
+the GPU registers is 128 KB.
+
+The current mapping incorrectly includes the addresses of multiple
+following IP like the eInk interface at 0x27900000. This has not
+been detected by the DT tooling as none of the extra mapped IP is
+described in the upstream RK3576 DT so far.
+
+Fixes: 57b1ce903966 ("arm64: dts: rockchip: Add rk3576 SoC base DT")
+Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
+Reviewed-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://patch.msgid.link/20260106071513.209-1-kernel@airkyi.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3576.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+index a86fc6b4e8c45..c72343e7a0456 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
+@@ -1261,7 +1261,7 @@ power-domain@RK3576_PD_VO1 {
+
+ gpu: gpu@27800000 {
+ compatible = "rockchip,rk3576-mali", "arm,mali-bifrost";
+- reg = <0x0 0x27800000 0x0 0x200000>;
++ reg = <0x0 0x27800000 0x0 0x20000>;
+ assigned-clocks = <&scmi_clk SCMI_CLK_GPU>;
+ assigned-clock-rates = <198000000>;
+ clocks = <&cru CLK_GPU>;
+--
+2.51.0
+
--- /dev/null
+From 60b2a325f09177d8bd782a5e473be9bf14c9c348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 18:37:56 +0000
+Subject: btrfs: fix missing fields in superblock backup with BLOCK_GROUP_TREE
+
+From: Mark Harmstone <mark@harmstone.com>
+
+[ Upstream commit 1d8f69f453c2e8a2d99b158e58e02ed65031fa6d ]
+
+When the BLOCK_GROUP_TREE compat_ro flag is set, the extent root and
+csum root fields are getting missed.
+
+This is because EXTENT_TREE_V2 treated these differently, and when
+they were split off this special-casing was mistakenly assigned to
+BGT rather than the rump EXTENT_TREE_V2. There's no reason why the
+existence of the block group tree should mean that we don't record the
+details of the last commit's extent root and csum root.
+
+Fix the code in backup_super_roots() so that the correct check gets
+made.
+
+Fixes: 1c56ab991903 ("btrfs: separate BLOCK_GROUP_TREE compat RO flag from EXTENT_TREE_V2")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Mark Harmstone <mark@harmstone.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/disk-io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 0aa7e5d1b05f6..a5336f530c8ed 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -1666,7 +1666,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
+ btrfs_set_backup_chunk_root_level(root_backup,
+ btrfs_header_level(info->chunk_root->node));
+
+- if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
++ if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+ struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+ struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+
+--
+2.51.0
+
--- /dev/null
+From c9875f5dbb673b9933bd23f6ecc4371c443ff6af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Dec 2025 12:14:47 -0800
+Subject: Drivers: hv: Always do Hyper-V panic notification in hv_kmsg_dump()
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+[ Upstream commit 49f49d47af67f8a7b221db1d758fc634242dc91a ]
+
+hv_kmsg_dump() currently skips the panic notification entirely if it
+doesn't get any message bytes to pass to Hyper-V due to an error from
+kmsg_dump_get_buffer(). Skipping the notification is undesirable because
+it leaves the Hyper-V host uncertain about the state of a panic'ed guest.
+
+Fix this by always doing the panic notification, even if bytes_written
+is zero. Also ensure that bytes_written is initialized, which fixes a
+kernel test robot warning. The warning is actually bogus because
+kmsg_dump_get_buffer() happens to set bytes_written even if it fails, and
+in the kernel test robot's CONFIG_PRINTK not set case, hv_kmsg_dump() is
+never called. But do the initialization for robustness and to quiet the
+static checker.
+
+Fixes: 9c318a1d9b50 ("Drivers: hv: move panic report code from vmbus to hv early init code")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/all/202512172103.OcUspn1Z-lkp@intel.com/
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Roman Kisel <vdso@mailbox.org>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/hv_common.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
+index e109a620c83fc..71fd3ea4fa8bd 100644
+--- a/drivers/hv/hv_common.c
++++ b/drivers/hv/hv_common.c
+@@ -195,13 +195,15 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+
+ /*
+ * Write dump contents to the page. No need to synchronize; panic should
+- * be single-threaded.
++ * be single-threaded. Ignore failures from kmsg_dump_get_buffer() since
++ * panic notification should be done even if there is no message data.
++ * Don't assume bytes_written is set in case of failure, so initialize it.
+ */
+ kmsg_dump_rewind(&iter);
+- kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
++ bytes_written = 0;
++ (void)kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
+ &bytes_written);
+- if (!bytes_written)
+- return;
++
+ /*
+ * P3 to contain the physical address of the panic page & P4 to
+ * contain the size of the panic data in that page. Rest of the
+@@ -210,7 +212,7 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+ hv_set_msr(HV_MSR_CRASH_P0, 0);
+ hv_set_msr(HV_MSR_CRASH_P1, 0);
+ hv_set_msr(HV_MSR_CRASH_P2, 0);
+- hv_set_msr(HV_MSR_CRASH_P3, virt_to_phys(hv_panic_page));
++ hv_set_msr(HV_MSR_CRASH_P3, bytes_written ? virt_to_phys(hv_panic_page) : 0);
+ hv_set_msr(HV_MSR_CRASH_P4, bytes_written);
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 3943167728d8afd32aa2a451da13daf5ffc86c81 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 22 Sep 2025 23:38:34 +0530
+Subject: perf parse-events: Fix evsel allocation failure
+
+From: Faisal Bukhari <faisalbukhari523@gmail.com>
+
+[ Upstream commit 1eb217ab2e737609f8a861b517649e82e7236d05 ]
+
+If evsel__new_idx() returns NULL, the function currently jumps to label
+'out_err'. Here, references to `cpus` and `pmu_cpus` are dropped.
+Also, resources held by evsel->name and evsel->metric_id are freed.
+
+But if evsel__new_idx() returns NULL, it can lead to NULL pointer
+dereference.
+
+Fixes: cd63c22168257a0b ("perf parse-events: Minor __add_event refactoring")
+Signed-off-by: Faisal Bukhari <faisalbukhari523@gmail.com>
+Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/parse-events.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index cd9315d3ca117..4723c2955f22e 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -286,8 +286,11 @@ __add_event(struct list_head *list, int *idx,
+ event_attr_init(attr);
+
+ evsel = evsel__new_idx(attr, *idx);
+- if (!evsel)
+- goto out_err;
++ if (!evsel) {
++ perf_cpu_map__put(cpus);
++ perf_cpu_map__put(pmu_cpus);
++ return NULL;
++ }
+
+ if (name) {
+ evsel->name = strdup(name);
+--
+2.51.0
+
--- /dev/null
+arm64-dts-qcom-sc8280xp-add-missing-vdd_mxc-links.patch
+arm64-dts-qcom-sm8550-fix-compile-warnings-in-usb-co.patch
+arm64-dts-qcom-sm8650-fix-compile-warnings-in-usb-co.patch
+arm64-dts-rockchip-fix-wrong-register-range-of-rk357.patch
+perf-parse-events-fix-evsel-allocation-failure.patch
+drivers-hv-always-do-hyper-v-panic-notification-in-h.patch
+btrfs-fix-missing-fields-in-superblock-backup-with-b.patch
--- /dev/null
+From e7f9c1d30d9e96c25e4ed680321240df6d51f4ff Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Dec 2025 18:36:22 +0100
+Subject: arm64: dts: qcom: sc8280xp: Add missing VDD_MXC links
+
+From: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+
+[ Upstream commit 868b979c5328b867c95a6d5a93ba13ad0d3cd2f1 ]
+
+To make sure that power rail is voted for, wire it up to its consumers.
+
+Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform")
+Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org>
+Link: https://lore.kernel.org/r/20251202-topic-8280_mxc-v2-3-46cdf47a829e@oss.qualcomm.com
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+index 3e70e79ce24b0..8472e00bde5ab 100644
+--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
+@@ -4412,8 +4412,12 @@ remoteproc_nsp0: remoteproc@1b300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp0_mem>;
+
+@@ -4543,8 +4547,12 @@ remoteproc_nsp1: remoteproc@21300000 {
+ clocks = <&rpmhcc RPMH_CXO_CLK>;
+ clock-names = "xo";
+
+- power-domains = <&rpmhpd SC8280XP_NSP>;
+- power-domain-names = "nsp";
++ power-domains = <&rpmhpd SC8280XP_NSP>,
++ <&rpmhpd SC8280XP_CX>,
++ <&rpmhpd SC8280XP_MXC>;
++ power-domain-names = "nsp",
++ "cx",
++ "mxc";
+
+ memory-region = <&pil_nsp1_mem>;
+
+--
+2.51.0
+
--- /dev/null
+From 67be96d64a7cc1046b2a3fd6401168d4d6c06499 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 13 Jan 2026 18:37:56 +0000
+Subject: btrfs: fix missing fields in superblock backup with BLOCK_GROUP_TREE
+
+From: Mark Harmstone <mark@harmstone.com>
+
+[ Upstream commit 1d8f69f453c2e8a2d99b158e58e02ed65031fa6d ]
+
+When the BLOCK_GROUP_TREE compat_ro flag is set, the extent root and
+csum root fields are getting missed.
+
+This is because EXTENT_TREE_V2 treated these differently, and when
+they were split off this special-casing was mistakenly assigned to
+BGT rather than the rump EXTENT_TREE_V2. There's no reason why the
+existence of the block group tree should mean that we don't record the
+details of the last commit's extent root and csum root.
+
+Fix the code in backup_super_roots() so that the correct check gets
+made.
+
+Fixes: 1c56ab991903 ("btrfs: separate BLOCK_GROUP_TREE compat RO flag from EXTENT_TREE_V2")
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Mark Harmstone <mark@harmstone.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/btrfs/disk-io.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 7ad1734cbbfc9..3c26e91a8055f 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -1654,7 +1654,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
+ btrfs_set_backup_chunk_root_level(root_backup,
+ btrfs_header_level(info->chunk_root->node));
+
+- if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
++ if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+ struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
+ struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
+
+--
+2.51.0
+
--- /dev/null
+From a5c885cd6f0579083fbbd31723b6ec028e5eec7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Dec 2025 12:14:47 -0800
+Subject: Drivers: hv: Always do Hyper-V panic notification in hv_kmsg_dump()
+
+From: Michael Kelley <mhklinux@outlook.com>
+
+[ Upstream commit 49f49d47af67f8a7b221db1d758fc634242dc91a ]
+
+hv_kmsg_dump() currently skips the panic notification entirely if it
+doesn't get any message bytes to pass to Hyper-V due to an error from
+kmsg_dump_get_buffer(). Skipping the notification is undesirable because
+it leaves the Hyper-V host uncertain about the state of a panic'ed guest.
+
+Fix this by always doing the panic notification, even if bytes_written
+is zero. Also ensure that bytes_written is initialized, which fixes a
+kernel test robot warning. The warning is actually bogus because
+kmsg_dump_get_buffer() happens to set bytes_written even if it fails, and
+in the kernel test robot's CONFIG_PRINTK not set case, hv_kmsg_dump() is
+never called. But do the initialization for robustness and to quiet the
+static checker.
+
+Fixes: 9c318a1d9b50 ("Drivers: hv: move panic report code from vmbus to hv early init code")
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/all/202512172103.OcUspn1Z-lkp@intel.com/
+Signed-off-by: Michael Kelley <mhklinux@outlook.com>
+Reviewed-by: Roman Kisel <vdso@mailbox.org>
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hv/hv_common.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
+index 65c0740484cb9..5512861dd8d2d 100644
+--- a/drivers/hv/hv_common.c
++++ b/drivers/hv/hv_common.c
+@@ -216,13 +216,15 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+
+ /*
+ * Write dump contents to the page. No need to synchronize; panic should
+- * be single-threaded.
++ * be single-threaded. Ignore failures from kmsg_dump_get_buffer() since
++ * panic notification should be done even if there is no message data.
++ * Don't assume bytes_written is set in case of failure, so initialize it.
+ */
+ kmsg_dump_rewind(&iter);
+- kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
++ bytes_written = 0;
++ (void)kmsg_dump_get_buffer(&iter, false, hv_panic_page, HV_HYP_PAGE_SIZE,
+ &bytes_written);
+- if (!bytes_written)
+- return;
++
+ /*
+ * P3 to contain the physical address of the panic page & P4 to
+ * contain the size of the panic data in that page. Rest of the
+@@ -231,7 +233,7 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+ hv_set_msr(HV_MSR_CRASH_P0, 0);
+ hv_set_msr(HV_MSR_CRASH_P1, 0);
+ hv_set_msr(HV_MSR_CRASH_P2, 0);
+- hv_set_msr(HV_MSR_CRASH_P3, virt_to_phys(hv_panic_page));
++ hv_set_msr(HV_MSR_CRASH_P3, bytes_written ? virt_to_phys(hv_panic_page) : 0);
+ hv_set_msr(HV_MSR_CRASH_P4, bytes_written);
+
+ /*
+--
+2.51.0
+
--- /dev/null
+From 1ac7315f3082914eb56e65933688c1d794267dd5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Mar 2024 14:59:48 -0700
+Subject: Fix memory leak in posix_clock_open()
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+[ Upstream commit 5b4cdd9c5676559b8a7c944ac5269b914b8c0bb8 ]
+
+If the clk ops.open() function returns an error, we don't release the
+pccontext we allocated for this clock.
+
+Re-organize the code slightly to make it all more obvious.
+
+Reported-by: Rohit Keshri <rkeshri@redhat.com>
+Acked-by: Oleg Nesterov <oleg@redhat.com>
+Fixes: 60c6946675fc ("posix-clock: introduce posix_clock_context concept")
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Linus Torvalds <torvalds@linuxfoundation.org>
+Stable-dep-of: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/time/posix-clock.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 706559ed75793..a6487a9d60853 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,15 +129,17 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
+- fp->private_data = pccontext;
+- if (clk->ops.open)
++ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+- else
+- err = 0;
+-
+- if (!err) {
+- get_device(clk->dev);
++ if (err) {
++ kfree(pccontext);
++ goto out;
++ }
+ }
++
++ fp->private_data = pccontext;
++ get_device(clk->dev);
++ err = 0;
+ out:
+ up_read(&clk->rwsem);
+ return err;
+--
+2.51.0
+
--- /dev/null
+From c2d62953f5e94ddf27f623b0ea24e3dca32e6293 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 20 Feb 2024 06:55:33 -0800
+Subject: hyperv-tlfs: Change prefix of generic HV_REGISTER_* MSRs to HV_MSR_*
+
+From: Nuno Das Neves <nunodasneves@linux.microsoft.com>
+
+[ Upstream commit 0e3f7d120086c8b9d6e1ae0dd4917fc529daa1ca ]
+
+The HV_REGISTER_ are used as arguments to hv_set/get_register(), which
+delegate to arch-specific mechanisms for getting/setting synthetic
+Hyper-V MSRs.
+
+On arm64, HV_REGISTER_ defines are synthetic VP registers accessed via
+the get/set vp registers hypercalls. The naming matches the TLFS
+document, although these register names are not specific to arm64.
+
+However, on x86 the prefix HV_REGISTER_ indicates Hyper-V MSRs accessed
+via rdmsrl()/wrmsrl(). This is not consistent with the TLFS doc, where
+HV_REGISTER_ is *only* used for used for VP register names used by
+the get/set register hypercalls.
+
+To fix this inconsistency and prevent future confusion, change the
+arch-generic aliases used by callers of hv_set/get_register() to have
+the prefix HV_MSR_ instead of HV_REGISTER_.
+
+Use the prefix HV_X64_MSR_ for the x86-only Hyper-V MSRs. On x86, the
+generic HV_MSR_'s point to the corresponding HV_X64_MSR_.
+
+Move the arm64 HV_REGISTER_* defines to the asm-generic hyperv-tlfs.h,
+since these are not specific to arm64. On arm64, the generic HV_MSR_'s
+point to the corresponding HV_REGISTER_.
+
+While at it, rename hv_get/set_registers() and related functions to
+hv_get/set_msr(), hv_get/set_nested_msr(), etc. These are only used for
+Hyper-V MSRs and this naming makes that clear.
+
+Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
+Reviewed-by: Wei Liu <wei.liu@kernel.org>
+Reviewed-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/r/1708440933-27125-1-git-send-email-nunodasneves@linux.microsoft.com
+Signed-off-by: Wei Liu <wei.liu@kernel.org>
+Message-ID: <1708440933-27125-1-git-send-email-nunodasneves@linux.microsoft.com>
+Stable-dep-of: 49f49d47af67 ("Drivers: hv: Always do Hyper-V panic notification in hv_kmsg_dump()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/hyperv-tlfs.h | 45 ++++-----
+ arch/arm64/include/asm/mshyperv.h | 4 +-
+ arch/x86/hyperv/hv_init.c | 8 +-
+ arch/x86/include/asm/hyperv-tlfs.h | 145 ++++++++++++++-------------
+ arch/x86/include/asm/mshyperv.h | 30 +++---
+ arch/x86/kernel/cpu/mshyperv.c | 56 +++++------
+ drivers/clocksource/hyperv_timer.c | 26 ++---
+ drivers/hv/hv.c | 36 +++----
+ drivers/hv/hv_common.c | 22 ++--
+ include/asm-generic/hyperv-tlfs.h | 32 +++++-
+ include/asm-generic/mshyperv.h | 2 +-
+ 11 files changed, 216 insertions(+), 190 deletions(-)
+
+diff --git a/arch/arm64/include/asm/hyperv-tlfs.h b/arch/arm64/include/asm/hyperv-tlfs.h
+index bc6c7ac934a1a..54846d1d29c36 100644
+--- a/arch/arm64/include/asm/hyperv-tlfs.h
++++ b/arch/arm64/include/asm/hyperv-tlfs.h
+@@ -21,14 +21,6 @@
+ * byte ordering of Linux running on ARM64, so no special handling is required.
+ */
+
+-/*
+- * These Hyper-V registers provide information equivalent to the CPUID
+- * instruction on x86/x64.
+- */
+-#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */
+-#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */
+-#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */
+-
+ /*
+ * Group C Features. See the asm-generic version of hyperv-tlfs.h
+ * for a description of Feature Groups.
+@@ -41,28 +33,29 @@
+ #define HV_STIMER_DIRECT_MODE_AVAILABLE BIT(13)
+
+ /*
+- * Synthetic register definitions equivalent to MSRs on x86/x64
++ * To support arch-generic code calling hv_set/get_register:
++ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
++ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
+ */
+-#define HV_REGISTER_CRASH_P0 0x00000210
+-#define HV_REGISTER_CRASH_P1 0x00000211
+-#define HV_REGISTER_CRASH_P2 0x00000212
+-#define HV_REGISTER_CRASH_P3 0x00000213
+-#define HV_REGISTER_CRASH_P4 0x00000214
+-#define HV_REGISTER_CRASH_CTL 0x00000215
++#define HV_MSR_CRASH_P0 (HV_REGISTER_CRASH_P0)
++#define HV_MSR_CRASH_P1 (HV_REGISTER_CRASH_P1)
++#define HV_MSR_CRASH_P2 (HV_REGISTER_CRASH_P2)
++#define HV_MSR_CRASH_P3 (HV_REGISTER_CRASH_P3)
++#define HV_MSR_CRASH_P4 (HV_REGISTER_CRASH_P4)
++#define HV_MSR_CRASH_CTL (HV_REGISTER_CRASH_CTL)
+
+-#define HV_REGISTER_GUEST_OSID 0x00090002
+-#define HV_REGISTER_VP_INDEX 0x00090003
+-#define HV_REGISTER_TIME_REF_COUNT 0x00090004
+-#define HV_REGISTER_REFERENCE_TSC 0x00090017
++#define HV_MSR_VP_INDEX (HV_REGISTER_VP_INDEX)
++#define HV_MSR_TIME_REF_COUNT (HV_REGISTER_TIME_REF_COUNT)
++#define HV_MSR_REFERENCE_TSC (HV_REGISTER_REFERENCE_TSC)
+
+-#define HV_REGISTER_SINT0 0x000A0000
+-#define HV_REGISTER_SCONTROL 0x000A0010
+-#define HV_REGISTER_SIEFP 0x000A0012
+-#define HV_REGISTER_SIMP 0x000A0013
+-#define HV_REGISTER_EOM 0x000A0014
++#define HV_MSR_SINT0 (HV_REGISTER_SINT0)
++#define HV_MSR_SCONTROL (HV_REGISTER_SCONTROL)
++#define HV_MSR_SIEFP (HV_REGISTER_SIEFP)
++#define HV_MSR_SIMP (HV_REGISTER_SIMP)
++#define HV_MSR_EOM (HV_REGISTER_EOM)
+
+-#define HV_REGISTER_STIMER0_CONFIG 0x000B0000
+-#define HV_REGISTER_STIMER0_COUNT 0x000B0001
++#define HV_MSR_STIMER0_CONFIG (HV_REGISTER_STIMER0_CONFIG)
++#define HV_MSR_STIMER0_COUNT (HV_REGISTER_STIMER0_COUNT)
+
+ union hv_msi_entry {
+ u64 as_uint64[2];
+diff --git a/arch/arm64/include/asm/mshyperv.h b/arch/arm64/include/asm/mshyperv.h
+index 20070a847304c..a975e1a689ddb 100644
+--- a/arch/arm64/include/asm/mshyperv.h
++++ b/arch/arm64/include/asm/mshyperv.h
+@@ -31,12 +31,12 @@ void hv_set_vpreg(u32 reg, u64 value);
+ u64 hv_get_vpreg(u32 reg);
+ void hv_get_vpreg_128(u32 reg, struct hv_get_vp_registers_output *result);
+
+-static inline void hv_set_register(unsigned int reg, u64 value)
++static inline void hv_set_msr(unsigned int reg, u64 value)
+ {
+ hv_set_vpreg(reg, value);
+ }
+
+-static inline u64 hv_get_register(unsigned int reg)
++static inline u64 hv_get_msr(unsigned int reg)
+ {
+ return hv_get_vpreg(reg);
+ }
+diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c
+index d1e2d12279e26..95eada2994e15 100644
+--- a/arch/x86/hyperv/hv_init.c
++++ b/arch/x86/hyperv/hv_init.c
+@@ -664,14 +664,14 @@ void hyperv_cleanup(void)
+ hv_hypercall_pg = NULL;
+
+ /* Reset the hypercall page */
+- hypercall_msr.as_uint64 = hv_get_register(HV_X64_MSR_HYPERCALL);
++ hypercall_msr.as_uint64 = hv_get_msr(HV_X64_MSR_HYPERCALL);
+ hypercall_msr.enable = 0;
+- hv_set_register(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
++ hv_set_msr(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+
+ /* Reset the TSC page */
+- tsc_msr.as_uint64 = hv_get_register(HV_X64_MSR_REFERENCE_TSC);
++ tsc_msr.as_uint64 = hv_get_msr(HV_X64_MSR_REFERENCE_TSC);
+ tsc_msr.enable = 0;
+- hv_set_register(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
++ hv_set_msr(HV_X64_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+ }
+
+ void hyperv_report_panic(struct pt_regs *regs, long err, bool in_die)
+diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h
+index 2ff26f53cd624..3787d26810c1c 100644
+--- a/arch/x86/include/asm/hyperv-tlfs.h
++++ b/arch/x86/include/asm/hyperv-tlfs.h
+@@ -182,7 +182,7 @@ enum hv_isolation_type {
+ #define HV_X64_MSR_HYPERCALL 0x40000001
+
+ /* MSR used to provide vcpu index */
+-#define HV_REGISTER_VP_INDEX 0x40000002
++#define HV_X64_MSR_VP_INDEX 0x40000002
+
+ /* MSR used to reset the guest OS. */
+ #define HV_X64_MSR_RESET 0x40000003
+@@ -191,10 +191,10 @@ enum hv_isolation_type {
+ #define HV_X64_MSR_VP_RUNTIME 0x40000010
+
+ /* MSR used to read the per-partition time reference counter */
+-#define HV_REGISTER_TIME_REF_COUNT 0x40000020
++#define HV_X64_MSR_TIME_REF_COUNT 0x40000020
+
+ /* A partition's reference time stamp counter (TSC) page */
+-#define HV_REGISTER_REFERENCE_TSC 0x40000021
++#define HV_X64_MSR_REFERENCE_TSC 0x40000021
+
+ /* MSR used to retrieve the TSC frequency */
+ #define HV_X64_MSR_TSC_FREQUENCY 0x40000022
+@@ -209,61 +209,61 @@ enum hv_isolation_type {
+ #define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073
+
+ /* Define synthetic interrupt controller model specific registers. */
+-#define HV_REGISTER_SCONTROL 0x40000080
+-#define HV_REGISTER_SVERSION 0x40000081
+-#define HV_REGISTER_SIEFP 0x40000082
+-#define HV_REGISTER_SIMP 0x40000083
+-#define HV_REGISTER_EOM 0x40000084
+-#define HV_REGISTER_SINT0 0x40000090
+-#define HV_REGISTER_SINT1 0x40000091
+-#define HV_REGISTER_SINT2 0x40000092
+-#define HV_REGISTER_SINT3 0x40000093
+-#define HV_REGISTER_SINT4 0x40000094
+-#define HV_REGISTER_SINT5 0x40000095
+-#define HV_REGISTER_SINT6 0x40000096
+-#define HV_REGISTER_SINT7 0x40000097
+-#define HV_REGISTER_SINT8 0x40000098
+-#define HV_REGISTER_SINT9 0x40000099
+-#define HV_REGISTER_SINT10 0x4000009A
+-#define HV_REGISTER_SINT11 0x4000009B
+-#define HV_REGISTER_SINT12 0x4000009C
+-#define HV_REGISTER_SINT13 0x4000009D
+-#define HV_REGISTER_SINT14 0x4000009E
+-#define HV_REGISTER_SINT15 0x4000009F
++#define HV_X64_MSR_SCONTROL 0x40000080
++#define HV_X64_MSR_SVERSION 0x40000081
++#define HV_X64_MSR_SIEFP 0x40000082
++#define HV_X64_MSR_SIMP 0x40000083
++#define HV_X64_MSR_EOM 0x40000084
++#define HV_X64_MSR_SINT0 0x40000090
++#define HV_X64_MSR_SINT1 0x40000091
++#define HV_X64_MSR_SINT2 0x40000092
++#define HV_X64_MSR_SINT3 0x40000093
++#define HV_X64_MSR_SINT4 0x40000094
++#define HV_X64_MSR_SINT5 0x40000095
++#define HV_X64_MSR_SINT6 0x40000096
++#define HV_X64_MSR_SINT7 0x40000097
++#define HV_X64_MSR_SINT8 0x40000098
++#define HV_X64_MSR_SINT9 0x40000099
++#define HV_X64_MSR_SINT10 0x4000009A
++#define HV_X64_MSR_SINT11 0x4000009B
++#define HV_X64_MSR_SINT12 0x4000009C
++#define HV_X64_MSR_SINT13 0x4000009D
++#define HV_X64_MSR_SINT14 0x4000009E
++#define HV_X64_MSR_SINT15 0x4000009F
+
+ /*
+ * Define synthetic interrupt controller model specific registers for
+ * nested hypervisor.
+ */
+-#define HV_REGISTER_NESTED_SCONTROL 0x40001080
+-#define HV_REGISTER_NESTED_SVERSION 0x40001081
+-#define HV_REGISTER_NESTED_SIEFP 0x40001082
+-#define HV_REGISTER_NESTED_SIMP 0x40001083
+-#define HV_REGISTER_NESTED_EOM 0x40001084
+-#define HV_REGISTER_NESTED_SINT0 0x40001090
++#define HV_X64_MSR_NESTED_SCONTROL 0x40001080
++#define HV_X64_MSR_NESTED_SVERSION 0x40001081
++#define HV_X64_MSR_NESTED_SIEFP 0x40001082
++#define HV_X64_MSR_NESTED_SIMP 0x40001083
++#define HV_X64_MSR_NESTED_EOM 0x40001084
++#define HV_X64_MSR_NESTED_SINT0 0x40001090
+
+ /*
+ * Synthetic Timer MSRs. Four timers per vcpu.
+ */
+-#define HV_REGISTER_STIMER0_CONFIG 0x400000B0
+-#define HV_REGISTER_STIMER0_COUNT 0x400000B1
+-#define HV_REGISTER_STIMER1_CONFIG 0x400000B2
+-#define HV_REGISTER_STIMER1_COUNT 0x400000B3
+-#define HV_REGISTER_STIMER2_CONFIG 0x400000B4
+-#define HV_REGISTER_STIMER2_COUNT 0x400000B5
+-#define HV_REGISTER_STIMER3_CONFIG 0x400000B6
+-#define HV_REGISTER_STIMER3_COUNT 0x400000B7
++#define HV_X64_MSR_STIMER0_CONFIG 0x400000B0
++#define HV_X64_MSR_STIMER0_COUNT 0x400000B1
++#define HV_X64_MSR_STIMER1_CONFIG 0x400000B2
++#define HV_X64_MSR_STIMER1_COUNT 0x400000B3
++#define HV_X64_MSR_STIMER2_CONFIG 0x400000B4
++#define HV_X64_MSR_STIMER2_COUNT 0x400000B5
++#define HV_X64_MSR_STIMER3_CONFIG 0x400000B6
++#define HV_X64_MSR_STIMER3_COUNT 0x400000B7
+
+ /* Hyper-V guest idle MSR */
+ #define HV_X64_MSR_GUEST_IDLE 0x400000F0
+
+ /* Hyper-V guest crash notification MSR's */
+-#define HV_REGISTER_CRASH_P0 0x40000100
+-#define HV_REGISTER_CRASH_P1 0x40000101
+-#define HV_REGISTER_CRASH_P2 0x40000102
+-#define HV_REGISTER_CRASH_P3 0x40000103
+-#define HV_REGISTER_CRASH_P4 0x40000104
+-#define HV_REGISTER_CRASH_CTL 0x40000105
++#define HV_X64_MSR_CRASH_P0 0x40000100
++#define HV_X64_MSR_CRASH_P1 0x40000101
++#define HV_X64_MSR_CRASH_P2 0x40000102
++#define HV_X64_MSR_CRASH_P3 0x40000103
++#define HV_X64_MSR_CRASH_P4 0x40000104
++#define HV_X64_MSR_CRASH_CTL 0x40000105
+
+ /* TSC emulation after migration */
+ #define HV_X64_MSR_REENLIGHTENMENT_CONTROL 0x40000106
+@@ -276,31 +276,38 @@ enum hv_isolation_type {
+ /* HV_X64_MSR_TSC_INVARIANT_CONTROL bits */
+ #define HV_EXPOSE_INVARIANT_TSC BIT_ULL(0)
+
+-/* Register name aliases for temporary compatibility */
+-#define HV_X64_MSR_STIMER0_COUNT HV_REGISTER_STIMER0_COUNT
+-#define HV_X64_MSR_STIMER0_CONFIG HV_REGISTER_STIMER0_CONFIG
+-#define HV_X64_MSR_STIMER1_COUNT HV_REGISTER_STIMER1_COUNT
+-#define HV_X64_MSR_STIMER1_CONFIG HV_REGISTER_STIMER1_CONFIG
+-#define HV_X64_MSR_STIMER2_COUNT HV_REGISTER_STIMER2_COUNT
+-#define HV_X64_MSR_STIMER2_CONFIG HV_REGISTER_STIMER2_CONFIG
+-#define HV_X64_MSR_STIMER3_COUNT HV_REGISTER_STIMER3_COUNT
+-#define HV_X64_MSR_STIMER3_CONFIG HV_REGISTER_STIMER3_CONFIG
+-#define HV_X64_MSR_SCONTROL HV_REGISTER_SCONTROL
+-#define HV_X64_MSR_SVERSION HV_REGISTER_SVERSION
+-#define HV_X64_MSR_SIMP HV_REGISTER_SIMP
+-#define HV_X64_MSR_SIEFP HV_REGISTER_SIEFP
+-#define HV_X64_MSR_VP_INDEX HV_REGISTER_VP_INDEX
+-#define HV_X64_MSR_EOM HV_REGISTER_EOM
+-#define HV_X64_MSR_SINT0 HV_REGISTER_SINT0
+-#define HV_X64_MSR_SINT15 HV_REGISTER_SINT15
+-#define HV_X64_MSR_CRASH_P0 HV_REGISTER_CRASH_P0
+-#define HV_X64_MSR_CRASH_P1 HV_REGISTER_CRASH_P1
+-#define HV_X64_MSR_CRASH_P2 HV_REGISTER_CRASH_P2
+-#define HV_X64_MSR_CRASH_P3 HV_REGISTER_CRASH_P3
+-#define HV_X64_MSR_CRASH_P4 HV_REGISTER_CRASH_P4
+-#define HV_X64_MSR_CRASH_CTL HV_REGISTER_CRASH_CTL
+-#define HV_X64_MSR_TIME_REF_COUNT HV_REGISTER_TIME_REF_COUNT
+-#define HV_X64_MSR_REFERENCE_TSC HV_REGISTER_REFERENCE_TSC
++/*
++ * To support arch-generic code calling hv_set/get_register:
++ * - On x86, HV_MSR_ indicates an MSR accessed via rdmsrl/wrmsrl
++ * - On ARM, HV_MSR_ indicates a VP register accessed via hypercall
++ */
++#define HV_MSR_CRASH_P0 (HV_X64_MSR_CRASH_P0)
++#define HV_MSR_CRASH_P1 (HV_X64_MSR_CRASH_P1)
++#define HV_MSR_CRASH_P2 (HV_X64_MSR_CRASH_P2)
++#define HV_MSR_CRASH_P3 (HV_X64_MSR_CRASH_P3)
++#define HV_MSR_CRASH_P4 (HV_X64_MSR_CRASH_P4)
++#define HV_MSR_CRASH_CTL (HV_X64_MSR_CRASH_CTL)
++
++#define HV_MSR_VP_INDEX (HV_X64_MSR_VP_INDEX)
++#define HV_MSR_TIME_REF_COUNT (HV_X64_MSR_TIME_REF_COUNT)
++#define HV_MSR_REFERENCE_TSC (HV_X64_MSR_REFERENCE_TSC)
++
++#define HV_MSR_SINT0 (HV_X64_MSR_SINT0)
++#define HV_MSR_SVERSION (HV_X64_MSR_SVERSION)
++#define HV_MSR_SCONTROL (HV_X64_MSR_SCONTROL)
++#define HV_MSR_SIEFP (HV_X64_MSR_SIEFP)
++#define HV_MSR_SIMP (HV_X64_MSR_SIMP)
++#define HV_MSR_EOM (HV_X64_MSR_EOM)
++
++#define HV_MSR_NESTED_SCONTROL (HV_X64_MSR_NESTED_SCONTROL)
++#define HV_MSR_NESTED_SVERSION (HV_X64_MSR_NESTED_SVERSION)
++#define HV_MSR_NESTED_SIEFP (HV_X64_MSR_NESTED_SIEFP)
++#define HV_MSR_NESTED_SIMP (HV_X64_MSR_NESTED_SIMP)
++#define HV_MSR_NESTED_EOM (HV_X64_MSR_NESTED_EOM)
++#define HV_MSR_NESTED_SINT0 (HV_X64_MSR_NESTED_SINT0)
++
++#define HV_MSR_STIMER0_CONFIG (HV_X64_MSR_STIMER0_CONFIG)
++#define HV_MSR_STIMER0_COUNT (HV_X64_MSR_STIMER0_COUNT)
+
+ /*
+ * Registers are only accessible via HVCALL_GET_VP_REGISTERS hvcall and
+diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
+index ec95d6e9f1682..aa76687ce520c 100644
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -292,24 +292,24 @@ static inline void hv_ivm_msr_write(u64 msr, u64 value) {}
+ static inline void hv_ivm_msr_read(u64 msr, u64 *value) {}
+ #endif
+
+-static inline bool hv_is_synic_reg(unsigned int reg)
++static inline bool hv_is_synic_msr(unsigned int reg)
+ {
+- return (reg >= HV_REGISTER_SCONTROL) &&
+- (reg <= HV_REGISTER_SINT15);
++ return (reg >= HV_X64_MSR_SCONTROL) &&
++ (reg <= HV_X64_MSR_SINT15);
+ }
+
+-static inline bool hv_is_sint_reg(unsigned int reg)
++static inline bool hv_is_sint_msr(unsigned int reg)
+ {
+- return (reg >= HV_REGISTER_SINT0) &&
+- (reg <= HV_REGISTER_SINT15);
++ return (reg >= HV_X64_MSR_SINT0) &&
++ (reg <= HV_X64_MSR_SINT15);
+ }
+
+-u64 hv_get_register(unsigned int reg);
+-void hv_set_register(unsigned int reg, u64 value);
+-u64 hv_get_non_nested_register(unsigned int reg);
+-void hv_set_non_nested_register(unsigned int reg, u64 value);
++u64 hv_get_msr(unsigned int reg);
++void hv_set_msr(unsigned int reg, u64 value);
++u64 hv_get_non_nested_msr(unsigned int reg);
++void hv_set_non_nested_msr(unsigned int reg, u64 value);
+
+-static __always_inline u64 hv_raw_get_register(unsigned int reg)
++static __always_inline u64 hv_raw_get_msr(unsigned int reg)
+ {
+ return __rdmsr(reg);
+ }
+@@ -330,10 +330,10 @@ static inline int hyperv_flush_guest_mapping_range(u64 as,
+ {
+ return -1;
+ }
+-static inline void hv_set_register(unsigned int reg, u64 value) { }
+-static inline u64 hv_get_register(unsigned int reg) { return 0; }
+-static inline void hv_set_non_nested_register(unsigned int reg, u64 value) { }
+-static inline u64 hv_get_non_nested_register(unsigned int reg) { return 0; }
++static inline void hv_set_msr(unsigned int reg, u64 value) { }
++static inline u64 hv_get_msr(unsigned int reg) { return 0; }
++static inline void hv_set_non_nested_msr(unsigned int reg, u64 value) { }
++static inline u64 hv_get_non_nested_msr(unsigned int reg) { return 0; }
+ #endif /* CONFIG_HYPERV */
+
+
+diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
+index e709070eed708..fc692125d82f3 100644
+--- a/arch/x86/kernel/cpu/mshyperv.c
++++ b/arch/x86/kernel/cpu/mshyperv.c
+@@ -44,70 +44,70 @@ bool hyperv_paravisor_present __ro_after_init;
+ EXPORT_SYMBOL_GPL(hyperv_paravisor_present);
+
+ #if IS_ENABLED(CONFIG_HYPERV)
+-static inline unsigned int hv_get_nested_reg(unsigned int reg)
++static inline unsigned int hv_get_nested_msr(unsigned int reg)
+ {
+- if (hv_is_sint_reg(reg))
+- return reg - HV_REGISTER_SINT0 + HV_REGISTER_NESTED_SINT0;
++ if (hv_is_sint_msr(reg))
++ return reg - HV_X64_MSR_SINT0 + HV_X64_MSR_NESTED_SINT0;
+
+ switch (reg) {
+- case HV_REGISTER_SIMP:
+- return HV_REGISTER_NESTED_SIMP;
+- case HV_REGISTER_SIEFP:
+- return HV_REGISTER_NESTED_SIEFP;
+- case HV_REGISTER_SVERSION:
+- return HV_REGISTER_NESTED_SVERSION;
+- case HV_REGISTER_SCONTROL:
+- return HV_REGISTER_NESTED_SCONTROL;
+- case HV_REGISTER_EOM:
+- return HV_REGISTER_NESTED_EOM;
++ case HV_X64_MSR_SIMP:
++ return HV_X64_MSR_NESTED_SIMP;
++ case HV_X64_MSR_SIEFP:
++ return HV_X64_MSR_NESTED_SIEFP;
++ case HV_X64_MSR_SVERSION:
++ return HV_X64_MSR_NESTED_SVERSION;
++ case HV_X64_MSR_SCONTROL:
++ return HV_X64_MSR_NESTED_SCONTROL;
++ case HV_X64_MSR_EOM:
++ return HV_X64_MSR_NESTED_EOM;
+ default:
+ return reg;
+ }
+ }
+
+-u64 hv_get_non_nested_register(unsigned int reg)
++u64 hv_get_non_nested_msr(unsigned int reg)
+ {
+ u64 value;
+
+- if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present)
++ if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present)
+ hv_ivm_msr_read(reg, &value);
+ else
+ rdmsrl(reg, value);
+ return value;
+ }
+-EXPORT_SYMBOL_GPL(hv_get_non_nested_register);
++EXPORT_SYMBOL_GPL(hv_get_non_nested_msr);
+
+-void hv_set_non_nested_register(unsigned int reg, u64 value)
++void hv_set_non_nested_msr(unsigned int reg, u64 value)
+ {
+- if (hv_is_synic_reg(reg) && ms_hyperv.paravisor_present) {
++ if (hv_is_synic_msr(reg) && ms_hyperv.paravisor_present) {
+ hv_ivm_msr_write(reg, value);
+
+ /* Write proxy bit via wrmsl instruction */
+- if (hv_is_sint_reg(reg))
++ if (hv_is_sint_msr(reg))
+ wrmsrl(reg, value | 1 << 20);
+ } else {
+ wrmsrl(reg, value);
+ }
+ }
+-EXPORT_SYMBOL_GPL(hv_set_non_nested_register);
++EXPORT_SYMBOL_GPL(hv_set_non_nested_msr);
+
+-u64 hv_get_register(unsigned int reg)
++u64 hv_get_msr(unsigned int reg)
+ {
+ if (hv_nested)
+- reg = hv_get_nested_reg(reg);
++ reg = hv_get_nested_msr(reg);
+
+- return hv_get_non_nested_register(reg);
++ return hv_get_non_nested_msr(reg);
+ }
+-EXPORT_SYMBOL_GPL(hv_get_register);
++EXPORT_SYMBOL_GPL(hv_get_msr);
+
+-void hv_set_register(unsigned int reg, u64 value)
++void hv_set_msr(unsigned int reg, u64 value)
+ {
+ if (hv_nested)
+- reg = hv_get_nested_reg(reg);
++ reg = hv_get_nested_msr(reg);
+
+- hv_set_non_nested_register(reg, value);
++ hv_set_non_nested_msr(reg, value);
+ }
+-EXPORT_SYMBOL_GPL(hv_set_register);
++EXPORT_SYMBOL_GPL(hv_set_msr);
+
+ static void (*vmbus_handler)(void);
+ static void (*hv_stimer0_handler)(void);
+diff --git a/drivers/clocksource/hyperv_timer.c b/drivers/clocksource/hyperv_timer.c
+index 5eec1457e1396..51ee0a7566812 100644
+--- a/drivers/clocksource/hyperv_timer.c
++++ b/drivers/clocksource/hyperv_timer.c
+@@ -82,14 +82,14 @@ static int hv_ce_set_next_event(unsigned long delta,
+
+ current_tick = hv_read_reference_counter();
+ current_tick += delta;
+- hv_set_register(HV_REGISTER_STIMER0_COUNT, current_tick);
++ hv_set_msr(HV_MSR_STIMER0_COUNT, current_tick);
+ return 0;
+ }
+
+ static int hv_ce_shutdown(struct clock_event_device *evt)
+ {
+- hv_set_register(HV_REGISTER_STIMER0_COUNT, 0);
+- hv_set_register(HV_REGISTER_STIMER0_CONFIG, 0);
++ hv_set_msr(HV_MSR_STIMER0_COUNT, 0);
++ hv_set_msr(HV_MSR_STIMER0_CONFIG, 0);
+ if (direct_mode_enabled && stimer0_irq >= 0)
+ disable_percpu_irq(stimer0_irq);
+
+@@ -120,7 +120,7 @@ static int hv_ce_set_oneshot(struct clock_event_device *evt)
+ timer_cfg.direct_mode = 0;
+ timer_cfg.sintx = stimer0_message_sint;
+ }
+- hv_set_register(HV_REGISTER_STIMER0_CONFIG, timer_cfg.as_uint64);
++ hv_set_msr(HV_MSR_STIMER0_CONFIG, timer_cfg.as_uint64);
+ return 0;
+ }
+
+@@ -373,11 +373,11 @@ static __always_inline u64 read_hv_clock_msr(void)
+ * is set to 0 when the partition is created and is incremented in 100
+ * nanosecond units.
+ *
+- * Use hv_raw_get_register() because this function is used from
+- * noinstr. Notable; while HV_REGISTER_TIME_REF_COUNT is a synthetic
++ * Use hv_raw_get_msr() because this function is used from
++ * noinstr. Notable; while HV_MSR_TIME_REF_COUNT is a synthetic
+ * register it doesn't need the GHCB path.
+ */
+- return hv_raw_get_register(HV_REGISTER_TIME_REF_COUNT);
++ return hv_raw_get_msr(HV_MSR_TIME_REF_COUNT);
+ }
+
+ /*
+@@ -440,9 +440,9 @@ static void suspend_hv_clock_tsc(struct clocksource *arg)
+ union hv_reference_tsc_msr tsc_msr;
+
+ /* Disable the TSC page */
+- tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
++ tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC);
+ tsc_msr.enable = 0;
+- hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
++ hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+ }
+
+
+@@ -451,10 +451,10 @@ static void resume_hv_clock_tsc(struct clocksource *arg)
+ union hv_reference_tsc_msr tsc_msr;
+
+ /* Re-enable the TSC page */
+- tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
++ tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC);
+ tsc_msr.enable = 1;
+ tsc_msr.pfn = tsc_pfn;
+- hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
++ hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+ }
+
+ /*
+@@ -567,14 +567,14 @@ static void __init hv_init_tsc_clocksource(void)
+ * thus TSC clocksource will work even without the real TSC page
+ * mapped.
+ */
+- tsc_msr.as_uint64 = hv_get_register(HV_REGISTER_REFERENCE_TSC);
++ tsc_msr.as_uint64 = hv_get_msr(HV_MSR_REFERENCE_TSC);
+ if (hv_root_partition)
+ tsc_pfn = tsc_msr.pfn;
+ else
+ tsc_pfn = HVPFN_DOWN(virt_to_phys(tsc_page));
+ tsc_msr.enable = 1;
+ tsc_msr.pfn = tsc_pfn;
+- hv_set_register(HV_REGISTER_REFERENCE_TSC, tsc_msr.as_uint64);
++ hv_set_msr(HV_MSR_REFERENCE_TSC, tsc_msr.as_uint64);
+
+ clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
+
+diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
+index 51e5018ac9b26..a8ad728354cb0 100644
+--- a/drivers/hv/hv.c
++++ b/drivers/hv/hv.c
+@@ -270,7 +270,7 @@ void hv_synic_enable_regs(unsigned int cpu)
+ union hv_synic_scontrol sctrl;
+
+ /* Setup the Synic's message page */
+- simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP);
++ simp.as_uint64 = hv_get_msr(HV_MSR_SIMP);
+ simp.simp_enabled = 1;
+
+ if (ms_hyperv.paravisor_present || hv_root_partition) {
+@@ -286,10 +286,10 @@ void hv_synic_enable_regs(unsigned int cpu)
+ >> HV_HYP_PAGE_SHIFT;
+ }
+
+- hv_set_register(HV_REGISTER_SIMP, simp.as_uint64);
++ hv_set_msr(HV_MSR_SIMP, simp.as_uint64);
+
+ /* Setup the Synic's event page */
+- siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
++ siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP);
+ siefp.siefp_enabled = 1;
+
+ if (ms_hyperv.paravisor_present || hv_root_partition) {
+@@ -305,13 +305,12 @@ void hv_synic_enable_regs(unsigned int cpu)
+ >> HV_HYP_PAGE_SHIFT;
+ }
+
+- hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64);
++ hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64);
+
+ /* Setup the shared SINT. */
+ if (vmbus_irq != -1)
+ enable_percpu_irq(vmbus_irq, 0);
+- shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 +
+- VMBUS_MESSAGE_SINT);
++ shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT);
+
+ shared_sint.vector = vmbus_interrupt;
+ shared_sint.masked = false;
+@@ -326,14 +325,13 @@ void hv_synic_enable_regs(unsigned int cpu)
+ #else
+ shared_sint.auto_eoi = 0;
+ #endif
+- hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT,
+- shared_sint.as_uint64);
++ hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
+
+ /* Enable the global synic bit */
+- sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL);
++ sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL);
+ sctrl.enable = 1;
+
+- hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64);
++ hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64);
+ }
+
+ int hv_synic_init(unsigned int cpu)
+@@ -357,17 +355,15 @@ void hv_synic_disable_regs(unsigned int cpu)
+ union hv_synic_siefp siefp;
+ union hv_synic_scontrol sctrl;
+
+- shared_sint.as_uint64 = hv_get_register(HV_REGISTER_SINT0 +
+- VMBUS_MESSAGE_SINT);
++ shared_sint.as_uint64 = hv_get_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT);
+
+ shared_sint.masked = 1;
+
+ /* Need to correctly cleanup in the case of SMP!!! */
+ /* Disable the interrupt */
+- hv_set_register(HV_REGISTER_SINT0 + VMBUS_MESSAGE_SINT,
+- shared_sint.as_uint64);
++ hv_set_msr(HV_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
+
+- simp.as_uint64 = hv_get_register(HV_REGISTER_SIMP);
++ simp.as_uint64 = hv_get_msr(HV_MSR_SIMP);
+ /*
+ * In Isolation VM, sim and sief pages are allocated by
+ * paravisor. These pages also will be used by kdump
+@@ -382,9 +378,9 @@ void hv_synic_disable_regs(unsigned int cpu)
+ simp.base_simp_gpa = 0;
+ }
+
+- hv_set_register(HV_REGISTER_SIMP, simp.as_uint64);
++ hv_set_msr(HV_MSR_SIMP, simp.as_uint64);
+
+- siefp.as_uint64 = hv_get_register(HV_REGISTER_SIEFP);
++ siefp.as_uint64 = hv_get_msr(HV_MSR_SIEFP);
+ siefp.siefp_enabled = 0;
+
+ if (ms_hyperv.paravisor_present || hv_root_partition) {
+@@ -394,12 +390,12 @@ void hv_synic_disable_regs(unsigned int cpu)
+ siefp.base_siefp_gpa = 0;
+ }
+
+- hv_set_register(HV_REGISTER_SIEFP, siefp.as_uint64);
++ hv_set_msr(HV_MSR_SIEFP, siefp.as_uint64);
+
+ /* Disable the global synic bit */
+- sctrl.as_uint64 = hv_get_register(HV_REGISTER_SCONTROL);
++ sctrl.as_uint64 = hv_get_msr(HV_MSR_SCONTROL);
+ sctrl.enable = 0;
+- hv_set_register(HV_REGISTER_SCONTROL, sctrl.as_uint64);
++ hv_set_msr(HV_MSR_SCONTROL, sctrl.as_uint64);
+
+ if (vmbus_irq != -1)
+ disable_percpu_irq(vmbus_irq);
+diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
+index ccad7bca3fd3d..65c0740484cb9 100644
+--- a/drivers/hv/hv_common.c
++++ b/drivers/hv/hv_common.c
+@@ -228,19 +228,19 @@ static void hv_kmsg_dump(struct kmsg_dumper *dumper,
+ * contain the size of the panic data in that page. Rest of the
+ * registers are no-op when the NOTIFY_MSG flag is set.
+ */
+- hv_set_register(HV_REGISTER_CRASH_P0, 0);
+- hv_set_register(HV_REGISTER_CRASH_P1, 0);
+- hv_set_register(HV_REGISTER_CRASH_P2, 0);
+- hv_set_register(HV_REGISTER_CRASH_P3, virt_to_phys(hv_panic_page));
+- hv_set_register(HV_REGISTER_CRASH_P4, bytes_written);
++ hv_set_msr(HV_MSR_CRASH_P0, 0);
++ hv_set_msr(HV_MSR_CRASH_P1, 0);
++ hv_set_msr(HV_MSR_CRASH_P2, 0);
++ hv_set_msr(HV_MSR_CRASH_P3, virt_to_phys(hv_panic_page));
++ hv_set_msr(HV_MSR_CRASH_P4, bytes_written);
+
+ /*
+ * Let Hyper-V know there is crash data available along with
+ * the panic message.
+ */
+- hv_set_register(HV_REGISTER_CRASH_CTL,
+- (HV_CRASH_CTL_CRASH_NOTIFY |
+- HV_CRASH_CTL_CRASH_NOTIFY_MSG));
++ hv_set_msr(HV_MSR_CRASH_CTL,
++ (HV_CRASH_CTL_CRASH_NOTIFY |
++ HV_CRASH_CTL_CRASH_NOTIFY_MSG));
+ }
+
+ static struct kmsg_dumper hv_kmsg_dumper = {
+@@ -311,7 +311,7 @@ int __init hv_common_init(void)
+ * Register for panic kmsg callback only if the right
+ * capability is supported by the hypervisor.
+ */
+- hyperv_crash_ctl = hv_get_register(HV_REGISTER_CRASH_CTL);
++ hyperv_crash_ctl = hv_get_msr(HV_MSR_CRASH_CTL);
+ if (hyperv_crash_ctl & HV_CRASH_CTL_CRASH_NOTIFY_MSG)
+ hv_kmsg_dump_register();
+
+@@ -410,7 +410,7 @@ int hv_common_cpu_init(unsigned int cpu)
+ *inputarg = mem;
+ }
+
+- msr_vp_index = hv_get_register(HV_REGISTER_VP_INDEX);
++ msr_vp_index = hv_get_msr(HV_MSR_VP_INDEX);
+
+ hv_vp_index[cpu] = msr_vp_index;
+
+@@ -507,7 +507,7 @@ EXPORT_SYMBOL_GPL(hv_is_hibernation_supported);
+ */
+ static u64 __hv_read_ref_counter(void)
+ {
+- return hv_get_register(HV_REGISTER_TIME_REF_COUNT);
++ return hv_get_msr(HV_MSR_TIME_REF_COUNT);
+ }
+
+ u64 (*hv_read_reference_counter)(void) = __hv_read_ref_counter;
+diff --git a/include/asm-generic/hyperv-tlfs.h b/include/asm-generic/hyperv-tlfs.h
+index fdac4a1714ec0..3d1b31f90ed60 100644
+--- a/include/asm-generic/hyperv-tlfs.h
++++ b/include/asm-generic/hyperv-tlfs.h
+@@ -625,6 +625,37 @@ struct hv_retarget_device_interrupt {
+ struct hv_device_interrupt_target int_target;
+ } __packed __aligned(8);
+
++/*
++ * These Hyper-V registers provide information equivalent to the CPUID
++ * instruction on x86/x64.
++ */
++#define HV_REGISTER_HYPERVISOR_VERSION 0x00000100 /*CPUID 0x40000002 */
++#define HV_REGISTER_FEATURES 0x00000200 /*CPUID 0x40000003 */
++#define HV_REGISTER_ENLIGHTENMENTS 0x00000201 /*CPUID 0x40000004 */
++
++/*
++ * Synthetic register definitions equivalent to MSRs on x86/x64
++ */
++#define HV_REGISTER_CRASH_P0 0x00000210
++#define HV_REGISTER_CRASH_P1 0x00000211
++#define HV_REGISTER_CRASH_P2 0x00000212
++#define HV_REGISTER_CRASH_P3 0x00000213
++#define HV_REGISTER_CRASH_P4 0x00000214
++#define HV_REGISTER_CRASH_CTL 0x00000215
++
++#define HV_REGISTER_GUEST_OSID 0x00090002
++#define HV_REGISTER_VP_INDEX 0x00090003
++#define HV_REGISTER_TIME_REF_COUNT 0x00090004
++#define HV_REGISTER_REFERENCE_TSC 0x00090017
++
++#define HV_REGISTER_SINT0 0x000A0000
++#define HV_REGISTER_SCONTROL 0x000A0010
++#define HV_REGISTER_SIEFP 0x000A0012
++#define HV_REGISTER_SIMP 0x000A0013
++#define HV_REGISTER_EOM 0x000A0014
++
++#define HV_REGISTER_STIMER0_CONFIG 0x000B0000
++#define HV_REGISTER_STIMER0_COUNT 0x000B0001
+
+ /* HvGetVpRegisters hypercall input with variable size reg name list*/
+ struct hv_get_vp_registers_input {
+@@ -640,7 +671,6 @@ struct hv_get_vp_registers_input {
+ } element[];
+ } __packed;
+
+-
+ /* HvGetVpRegisters returns an array of these output elements */
+ struct hv_get_vp_registers_output {
+ union {
+diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
+index 430f0ae0dde2d..04424a446bb73 100644
+--- a/include/asm-generic/mshyperv.h
++++ b/include/asm-generic/mshyperv.h
+@@ -157,7 +157,7 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type)
+ * possibly deliver another msg from the
+ * hypervisor
+ */
+- hv_set_register(HV_REGISTER_EOM, 0);
++ hv_set_msr(HV_MSR_EOM, 0);
+ }
+ }
+
+--
+2.51.0
+
--- /dev/null
+From ec2d222665c9127b8c0983c55c4173daa847d47c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 00:39:53 +0200
+Subject: posix-clock: introduce posix_clock_context concept
+
+From: Xabier Marquiegui <reibax@gmail.com>
+
+[ Upstream commit 60c6946675fc06dd2fd2b7a4b6fd1c1f046f1056 ]
+
+Add the necessary structure to support custom private-data per
+posix-clock user.
+
+The previous implementation of posix-clock assumed all file open
+instances need access to the same clock structure on private_data.
+
+The need for individual data structures per file open instance has been
+identified when developing support for multiple timestamp event queue
+users for ptp_clock.
+
+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: e859d375d169 ("posix-clock: Store file pointer in struct posix_clock_context")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 21 +++++++++++++--------
+ drivers/ptp/ptp_private.h | 16 +++++++++-------
+ include/linux/posix-clock.h | 35 +++++++++++++++++++++++++++--------
+ kernel/time/posix-clock.c | 36 +++++++++++++++++++++++++++---------
+ 4 files changed, 76 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index 6f6019fb41c0c..6eecb53b3e670 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -103,14 +103,16 @@ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ return 0;
+ }
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode)
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode)
+ {
+ return 0;
+ }
+
+-long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct ptp_sys_offset_extended *extoff = NULL;
+ struct ptp_sys_offset_precise precise_offset;
+ struct system_device_crosststamp xtstamp;
+@@ -437,9 +439,11 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
+ return err;
+ }
+
+-__poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+
+ poll_wait(fp, &ptp->tsev_wq, wait);
+
+@@ -448,10 +452,11 @@ __poll_t ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
+
+ #define EXTTS_BUFSIZE (PTP_BUF_TIMESTAMPS * sizeof(struct ptp_extts_event))
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint rdflags, char __user *buf, size_t cnt)
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint rdflags,
++ char __user *buf, size_t cnt)
+ {
+- struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
++ struct ptp_clock *ptp =
++ container_of(pccontext->clk, struct ptp_clock, clock);
+ struct timestamp_event_queue *queue = &ptp->tsevq;
+ struct ptp_extts_event *event;
+ unsigned long flags;
+diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
+index 3fbd1d68a9bcb..e25be08fa6ae9 100644
+--- a/drivers/ptp/ptp_private.h
++++ b/drivers/ptp/ptp_private.h
+@@ -136,16 +136,18 @@ extern struct class *ptp_class;
+ int ptp_set_pinfunc(struct ptp_clock *ptp, unsigned int pin,
+ enum ptp_pin_function func, unsigned int chan);
+
+-long ptp_ioctl(struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+-int ptp_open(struct posix_clock *pc, fmode_t fmode);
++int ptp_open(struct posix_clock_context *pccontext, fmode_t fmode);
+
+-ssize_t ptp_read(struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++int ptp_release(struct posix_clock_context *pccontext);
+
+-__poll_t ptp_poll(struct posix_clock *pc,
+- struct file *fp, poll_table *wait);
++ssize_t ptp_read(struct posix_clock_context *pccontext, uint flags, char __user *buf,
++ size_t cnt);
++
++__poll_t ptp_poll(struct posix_clock_context *pccontext, struct file *fp,
++ poll_table *wait);
+
+ /*
+ * see ptp_sysfs.c
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index 468328b1e1dd5..ef8619f489203 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -14,6 +14,7 @@
+ #include <linux/rwsem.h>
+
+ struct posix_clock;
++struct posix_clock_context;
+
+ /**
+ * struct posix_clock_operations - functional interface to the clock
+@@ -50,18 +51,18 @@ struct posix_clock_operations {
+ /*
+ * Optional character device methods:
+ */
+- long (*ioctl) (struct posix_clock *pc,
+- unsigned int cmd, unsigned long arg);
++ long (*ioctl)(struct posix_clock_context *pccontext, unsigned int cmd,
++ unsigned long arg);
+
+- int (*open) (struct posix_clock *pc, fmode_t f_mode);
++ int (*open)(struct posix_clock_context *pccontext, fmode_t f_mode);
+
+- __poll_t (*poll) (struct posix_clock *pc,
+- struct file *file, poll_table *wait);
++ __poll_t (*poll)(struct posix_clock_context *pccontext, struct file *file,
++ poll_table *wait);
+
+- int (*release) (struct posix_clock *pc);
++ int (*release)(struct posix_clock_context *pccontext);
+
+- ssize_t (*read) (struct posix_clock *pc,
+- uint flags, char __user *buf, size_t cnt);
++ ssize_t (*read)(struct posix_clock_context *pccontext, uint flags,
++ char __user *buf, size_t cnt);
+ };
+
+ /**
+@@ -90,6 +91,24 @@ struct posix_clock {
+ bool zombie;
+ };
+
++/**
++ * struct posix_clock_context - represents clock file operations context
++ *
++ * @clk: Pointer to the clock
++ * @private_clkdata: Pointer to user data
++ *
++ * Drivers should use struct posix_clock_context during specific character
++ * device file operation methods to access the posix clock.
++ *
++ * Drivers can store a private data structure during the open operation
++ * if they have specific information that is required in other file
++ * operations.
++ */
++struct posix_clock_context {
++ struct posix_clock *clk;
++ void *private_clkdata;
++};
++
+ /**
+ * posix_clock_register() - register a new clock
+ * @clk: Pointer to the clock. Caller must provide 'ops' field
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index 05e73d209aa87..706559ed75793 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -19,7 +19,8 @@
+ */
+ static struct posix_clock *get_posix_clock(struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk = pccontext->clk;
+
+ down_read(&clk->rwsem);
+
+@@ -39,6 +40,7 @@ static void put_posix_clock(struct posix_clock *clk)
+ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ size_t count, loff_t *ppos)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -EINVAL;
+
+@@ -46,7 +48,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+ return -ENODEV;
+
+ if (clk->ops.read)
+- err = clk->ops.read(clk, fp->f_flags, buf, count);
++ err = clk->ops.read(pccontext, fp->f_flags, buf, count);
+
+ put_posix_clock(clk);
+
+@@ -55,6 +57,7 @@ static ssize_t posix_clock_read(struct file *fp, char __user *buf,
+
+ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ __poll_t result = 0;
+
+@@ -62,7 +65,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ return EPOLLERR;
+
+ if (clk->ops.poll)
+- result = clk->ops.poll(clk, fp, wait);
++ result = clk->ops.poll(pccontext, fp, wait);
+
+ put_posix_clock(clk);
+
+@@ -72,6 +75,7 @@ static __poll_t posix_clock_poll(struct file *fp, poll_table *wait)
+ static long posix_clock_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -79,7 +83,7 @@ static long posix_clock_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -90,6 +94,7 @@ static long posix_clock_ioctl(struct file *fp,
+ static long posix_clock_compat_ioctl(struct file *fp,
+ unsigned int cmd, unsigned long arg)
+ {
++ struct posix_clock_context *pccontext = fp->private_data;
+ struct posix_clock *clk = get_posix_clock(fp);
+ int err = -ENOTTY;
+
+@@ -97,7 +102,7 @@ static long posix_clock_compat_ioctl(struct file *fp,
+ return -ENODEV;
+
+ if (clk->ops.ioctl)
+- err = clk->ops.ioctl(clk, cmd, arg);
++ err = clk->ops.ioctl(pccontext, cmd, arg);
+
+ put_posix_clock(clk);
+
+@@ -110,6 +115,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ int err;
+ struct posix_clock *clk =
+ container_of(inode->i_cdev, struct posix_clock, cdev);
++ struct posix_clock_context *pccontext;
+
+ down_read(&clk->rwsem);
+
+@@ -117,14 +123,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ err = -ENODEV;
+ goto out;
+ }
++ pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL);
++ if (!pccontext) {
++ err = -ENOMEM;
++ goto out;
++ }
++ pccontext->clk = clk;
++ fp->private_data = pccontext;
+ if (clk->ops.open)
+- err = clk->ops.open(clk, fp->f_mode);
++ err = clk->ops.open(pccontext, fp->f_mode);
+ else
+ err = 0;
+
+ if (!err) {
+ get_device(clk->dev);
+- fp->private_data = clk;
+ }
+ out:
+ up_read(&clk->rwsem);
+@@ -133,14 +145,20 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+
+ static int posix_clock_release(struct inode *inode, struct file *fp)
+ {
+- struct posix_clock *clk = fp->private_data;
++ struct posix_clock_context *pccontext = fp->private_data;
++ struct posix_clock *clk;
+ int err = 0;
+
++ if (!pccontext)
++ return -ENODEV;
++ clk = pccontext->clk;
++
+ if (clk->ops.release)
+- err = clk->ops.release(clk);
++ err = clk->ops.release(pccontext);
+
+ put_device(clk->dev);
+
++ kfree(pccontext);
+ fp->private_data = NULL;
+
+ return err;
+--
+2.51.0
+
--- /dev/null
+From 1f898a350190e2fccfe0455387d43638b2d9fb49 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:43 +0200
+Subject: posix-clock: Store file pointer in struct posix_clock_context
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit e859d375d1694488015e6804bfeea527a0b25b9f ]
+
+File descriptor based pc_clock_*() operations of dynamic posix clocks
+have access to the file pointer and implement permission checks in the
+generic code before invoking the relevant dynamic clock callback.
+
+Character device operations (open, read, poll, ioctl) do not implement a
+generic permission control and the dynamic clock callbacks have no
+access to the file pointer to implement them.
+
+Extend struct posix_clock_context with a struct file pointer and
+initialize it in posix_clock_open(), so that all dynamic clock callbacks
+can access it.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/posix-clock.h | 6 +++++-
+ kernel/time/posix-clock.c | 1 +
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/posix-clock.h b/include/linux/posix-clock.h
+index ef8619f489203..a500d3160fe8c 100644
+--- a/include/linux/posix-clock.h
++++ b/include/linux/posix-clock.h
+@@ -95,10 +95,13 @@ struct posix_clock {
+ * struct posix_clock_context - represents clock file operations context
+ *
+ * @clk: Pointer to the clock
++ * @fp: Pointer to the file used to open the clock
+ * @private_clkdata: Pointer to user data
+ *
+ * Drivers should use struct posix_clock_context during specific character
+- * device file operation methods to access the posix clock.
++ * device file operation methods to access the posix clock. In particular,
++ * the file pointer can be used to verify correct access mode for ioctl()
++ * calls.
+ *
+ * Drivers can store a private data structure during the open operation
+ * if they have specific information that is required in other file
+@@ -106,6 +109,7 @@ struct posix_clock {
+ */
+ struct posix_clock_context {
+ struct posix_clock *clk;
++ struct file *fp;
+ void *private_clkdata;
+ };
+
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index a6487a9d60853..b130bb56cc4e0 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -129,6 +129,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp)
+ goto out;
+ }
+ pccontext->clk = clk;
++ pccontext->fp = fp;
+ if (clk->ops.open) {
+ err = clk->ops.open(pccontext, fp->f_mode);
+ if (err) {
+--
+2.51.0
+
--- /dev/null
+From 60f056e8647499def6248be9957ccb35ea7930ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:44 +0200
+Subject: ptp: Add PHC file mode checks. Allow RO adjtime() without
+ FMODE_WRITE.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit b4e53b15c04e3852949003752f48f7a14ae39e86 ]
+
+Many devices implement highly accurate clocks, which the kernel manages
+as PTP Hardware Clocks (PHCs). Userspace applications rely on these
+clocks to timestamp events, trace workload execution, correlate
+timescales across devices, and keep various clocks in sync.
+
+The kernel’s current implementation of PTP clocks does not enforce file
+permissions checks for most device operations except for POSIX clock
+operations, where file mode is verified in the POSIX layer before
+forwarding the call to the PTP subsystem. Consequently, it is common
+practice to not give unprivileged userspace applications any access to
+PTP clocks whatsoever by giving the PTP chardevs 600 permissions. An
+example of users running into this limitation is documented in [1].
+Additionally, POSIX layer requires WRITE permission even for readonly
+adjtime() calls which are used in PTP layer to return current frequency
+offset applied to the PHC.
+
+Add permission checks for functions that modify the state of a PTP
+device. Continue enforcing permission checks for POSIX clock operations
+(settime, adjtime) in the POSIX layer. Only require WRITE access for
+dynamic clocks adjtime() if any flags are set in the modes field.
+
+[1] https://lists.nwtime.org/sympa/arc/linuxptp-users/2024-01/msg00036.html
+
+Changes in v4:
+- Require FMODE_WRITE in ajtime() only for calls modifying the clock in
+ any way.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_chardev.c | 16 ++++++++++++++++
+ kernel/time/posix-clock.c | 2 +-
+ 2 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index 6eecb53b3e670..1ed12e86ee000 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -153,6 +153,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_EXTTS_REQUEST:
+ case PTP_EXTTS_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.extts, (void __user *)arg,
+@@ -194,6 +198,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PEROUT_REQUEST:
+ case PTP_PEROUT_REQUEST2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (copy_from_user(&req.perout, (void __user *)arg,
+@@ -262,6 +270,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_ENABLE_PPS:
+ case PTP_ENABLE_PPS2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ memset(&req, 0, sizeof(req));
+
+ if (!capable(CAP_SYS_TIME))
+@@ -400,6 +412,10 @@ long ptp_ioctl(struct posix_clock_context *pccontext, unsigned int cmd,
+
+ case PTP_PIN_SETFUNC:
+ case PTP_PIN_SETFUNC2:
++ if ((pccontext->fp->f_mode & FMODE_WRITE) == 0) {
++ err = -EACCES;
++ break;
++ }
+ if (copy_from_user(&pd, (void __user *)arg, sizeof(pd))) {
+ err = -EFAULT;
+ break;
+diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c
+index b130bb56cc4e0..827abede72745 100644
+--- a/kernel/time/posix-clock.c
++++ b/kernel/time/posix-clock.c
+@@ -253,7 +253,7 @@ static int pc_clock_adjtime(clockid_t id, struct __kernel_timex *tx)
+ if (err)
+ return err;
+
+- if ((cd.fp->f_mode & FMODE_WRITE) == 0) {
++ if (tx->modes && (cd.fp->f_mode & FMODE_WRITE) == 0) {
+ err = -EACCES;
+ goto out;
+ }
+--
+2.51.0
+
--- /dev/null
+From c7f332a6b5ccd98cf038ed82634ce66099c299bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 00:39:58 +0200
+Subject: ptp: add testptp mask test
+
+From: Xabier Marquiegui <reibax@gmail.com>
+
+[ Upstream commit 26285e689c6cd2cf3849568c83b2ebe53f467143 ]
+
+Add option to test timestamp event queue mask manipulation in testptp.
+
+Option -F allows the user to specify a single channel that will be
+applied on the mask filter via IOCTL.
+
+The test program will maintain the file open until user input is
+received.
+
+This allows checking the effect of the IOCTL in debugfs.
+
+eg:
+
+Console 1:
+```
+Channel 12 exclusively enabled. Check on debugfs.
+Press any key to continue
+```
+
+Console 2:
+```
+0x00000000 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000
+0x00000000 0x00000000 0x00000000 0x00000000
+```
+
+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: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index c9f6cca4feb45..011252fe238c8 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -121,6 +121,7 @@ static void usage(char *progname)
+ " -d name device to open\n"
+ " -e val read 'val' external time stamp events\n"
+ " -f val adjust the ptp clock frequency by 'val' ppb\n"
++ " -F chan Enable single channel mask and keep device open for debugfs verification.\n"
+ " -g get the ptp clock time\n"
+ " -h prints this message\n"
+ " -i val index for event/trigger\n"
+@@ -187,6 +188,7 @@ int main(int argc, char *argv[])
+ int pps = -1;
+ int seconds = 0;
+ int settime = 0;
++ int channel = -1;
+
+ int64_t t1, t2, tp;
+ int64_t interval, offset;
+@@ -196,7 +198,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -210,6 +212,9 @@ int main(int argc, char *argv[])
+ case 'f':
+ adjfreq = atoi(optarg);
+ break;
++ case 'F':
++ channel = atoi(optarg);
++ break;
+ case 'g':
+ gettime = 1;
+ break;
+@@ -604,6 +609,18 @@ int main(int argc, char *argv[])
+ free(xts);
+ }
+
++ if (channel >= 0) {
++ if (ioctl(fd, PTP_MASK_CLEAR_ALL)) {
++ perror("PTP_MASK_CLEAR_ALL");
++ } else if (ioctl(fd, PTP_MASK_EN_SINGLE, (unsigned int *)&channel)) {
++ perror("PTP_MASK_EN_SINGLE");
++ } else {
++ printf("Channel %d exclusively enabled. Check on debugfs.\n", channel);
++ printf("Press any key to continue\n.");
++ getchar();
++ }
++ }
++
+ close(fd);
+ return 0;
+ }
+--
+2.51.0
+
--- /dev/null
+From 26f3626a5a8412227c4b0d1fc6161e02b526515a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Oct 2024 03:15:06 -0700
+Subject: selftest/ptp: update ptp selftest to exercise the gettimex options
+
+From: Mahesh Bandewar <maheshb@google.com>
+
+[ Upstream commit 3d07b691ee707c00afaf365440975e81bb96cd9b ]
+
+With the inclusion of commit c259acab839e ("ptp/ioctl: support
+MONOTONIC{,_RAW} timestamps for PTP_SYS_OFFSET_EXTENDED") clock_gettime()
+now allows retrieval of pre/post timestamps for CLOCK_MONOTONIC and
+CLOCK_MONOTONIC_RAW timebases along with the previously supported
+CLOCK_REALTIME.
+
+This patch adds a command line option 'y' to the testptp program to
+choose one of the allowed timebases [realtime aka system, monotonic,
+and monotonic-raw).
+
+Signed-off-by: Mahesh Bandewar <maheshb@google.com>
+Cc: Shuah Khan <shuah@kernel.org>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://patch.msgid.link/20241003101506.769418-1-maheshb@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 76868642e427 ("testptp: Add option to open PHC in readonly mode")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 62 ++++++++++++++++++++++++---
+ 1 file changed, 57 insertions(+), 5 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 011252fe238c8..58064151f2c89 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -146,6 +146,7 @@ static void usage(char *progname)
+ " -T val set the ptp clock time to 'val' seconds\n"
+ " -x val get an extended ptp clock time with the desired number of samples (up to %d)\n"
+ " -X get a ptp clock cross timestamp\n"
++ " -y val pre/post tstamp timebase to use {realtime|monotonic|monotonic-raw}\n"
+ " -z test combinations of rising/falling external time stamp flags\n",
+ progname, PTP_MAX_SAMPLES);
+ }
+@@ -189,6 +190,7 @@ int main(int argc, char *argv[])
+ int seconds = 0;
+ int settime = 0;
+ int channel = -1;
++ clockid_t ext_clockid = CLOCK_REALTIME;
+
+ int64_t t1, t2, tp;
+ int64_t interval, offset;
+@@ -198,7 +200,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xz"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -278,6 +280,21 @@ int main(int argc, char *argv[])
+ case 'X':
+ getcross = 1;
+ break;
++ case 'y':
++ if (!strcasecmp(optarg, "realtime"))
++ ext_clockid = CLOCK_REALTIME;
++ else if (!strcasecmp(optarg, "monotonic"))
++ ext_clockid = CLOCK_MONOTONIC;
++ else if (!strcasecmp(optarg, "monotonic-raw"))
++ ext_clockid = CLOCK_MONOTONIC_RAW;
++ else {
++ fprintf(stderr,
++ "type needs to be realtime, monotonic or monotonic-raw; was given %s\n",
++ optarg);
++ return -1;
++ }
++ break;
++
+ case 'z':
+ flagtest = 1;
+ break;
+@@ -566,6 +583,7 @@ int main(int argc, char *argv[])
+ }
+
+ soe->n_samples = getextended;
++ soe->clockid = ext_clockid;
+
+ if (ioctl(fd, PTP_SYS_OFFSET_EXTENDED, soe)) {
+ perror("PTP_SYS_OFFSET_EXTENDED");
+@@ -574,12 +592,46 @@ int main(int argc, char *argv[])
+ getextended);
+
+ for (i = 0; i < getextended; i++) {
+- printf("sample #%2d: system time before: %lld.%09u\n",
+- i, soe->ts[i][0].sec, soe->ts[i][0].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf("sample #%2d: real time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf("sample #%2d: monotonic time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf("sample #%2d: monotonic-raw time before: %lld.%09u\n",
++ i, soe->ts[i][0].sec,
++ soe->ts[i][0].nsec);
++ break;
++ default:
++ break;
++ }
+ printf(" phc time: %lld.%09u\n",
+ soe->ts[i][1].sec, soe->ts[i][1].nsec);
+- printf(" system time after: %lld.%09u\n",
+- soe->ts[i][2].sec, soe->ts[i][2].nsec);
++ switch (ext_clockid) {
++ case CLOCK_REALTIME:
++ printf(" real time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC:
++ printf(" monotonic time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ case CLOCK_MONOTONIC_RAW:
++ printf(" monotonic-raw time after: %lld.%09u\n",
++ soe->ts[i][2].sec,
++ soe->ts[i][2].nsec);
++ break;
++ default:
++ break;
++ }
+ }
+ }
+
+--
+2.51.0
+
dmaengine-ti-k3-udma-fix-device-leak-on-udma-lookup.patch
btrfs-fix-deadlock-in-wait_current_trans-due-to-ignored-transaction-type.patch
io_uring-move-local-task_work-in-exit-cancel-loop.patch
+posix-clock-introduce-posix_clock_context-concept.patch
+fix-memory-leak-in-posix_clock_open.patch
+posix-clock-store-file-pointer-in-struct-posix_clock.patch
+ptp-add-phc-file-mode-checks.-allow-ro-adjtime-witho.patch
+ptp-add-testptp-mask-test.patch
+selftest-ptp-update-ptp-selftest-to-exercise-the-get.patch
+testptp-add-option-to-open-phc-in-readonly-mode.patch
+arm64-dts-qcom-sc8280xp-add-missing-vdd_mxc-links.patch
+hyperv-tlfs-change-prefix-of-generic-hv_register_-ms.patch
+drivers-hv-always-do-hyper-v-panic-notification-in-h.patch
+btrfs-fix-missing-fields-in-superblock-backup-with-b.patch
--- /dev/null
+From 56a44762aaab2c36c530241965ce0ba43f75bc5a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 3 Mar 2025 18:13:45 +0200
+Subject: testptp: Add option to open PHC in readonly mode
+
+From: Wojtek Wasko <wwasko@nvidia.com>
+
+[ Upstream commit 76868642e42795353106197abf9c607ad80f4c9e ]
+
+PTP Hardware Clocks no longer require WRITE permission to perform
+readonly operations, such as listing device capabilities or listening to
+EXTTS events once they have been enabled by a process with WRITE
+permissions.
+
+Add '-r' option to testptp to open the PHC in readonly mode instead of
+the default read-write mode. Skip enabling EXTTS if readonly mode is
+requested.
+
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
+Signed-off-by: Wojtek Wasko <wwasko@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/ptp/testptp.c | 37 +++++++++++++++++----------
+ 1 file changed, 23 insertions(+), 14 deletions(-)
+
+diff --git a/tools/testing/selftests/ptp/testptp.c b/tools/testing/selftests/ptp/testptp.c
+index 58064151f2c89..edc08a4433fd4 100644
+--- a/tools/testing/selftests/ptp/testptp.c
++++ b/tools/testing/selftests/ptp/testptp.c
+@@ -140,6 +140,7 @@ static void usage(char *progname)
+ " -H val set output phase to 'val' nanoseconds (requires -p)\n"
+ " -w val set output pulse width to 'val' nanoseconds (requires -p)\n"
+ " -P val enable or disable (val=1|0) the system clock PPS\n"
++ " -r open the ptp clock in readonly mode\n"
+ " -s set the ptp clock time from the system time\n"
+ " -S set the system time from the ptp clock time\n"
+ " -t val shift the ptp clock time by 'val' seconds\n"
+@@ -188,6 +189,7 @@ int main(int argc, char *argv[])
+ int pin_index = -1, pin_func;
+ int pps = -1;
+ int seconds = 0;
++ int readonly = 0;
+ int settime = 0;
+ int channel = -1;
+ clockid_t ext_clockid = CLOCK_REALTIME;
+@@ -200,7 +202,7 @@ int main(int argc, char *argv[])
+
+ progname = strrchr(argv[0], '/');
+ progname = progname ? 1+progname : argv[0];
+- while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:sSt:T:w:x:Xy:z"))) {
++ while (EOF != (c = getopt(argc, argv, "cd:e:f:F:ghH:i:k:lL:n:o:p:P:rsSt:T:w:x:Xy:z"))) {
+ switch (c) {
+ case 'c':
+ capabilities = 1;
+@@ -252,6 +254,9 @@ int main(int argc, char *argv[])
+ case 'P':
+ pps = atoi(optarg);
+ break;
++ case 'r':
++ readonly = 1;
++ break;
+ case 's':
+ settime = 1;
+ break;
+@@ -308,7 +313,7 @@ int main(int argc, char *argv[])
+ }
+ }
+
+- fd = open(device, O_RDWR);
++ fd = open(device, readonly ? O_RDONLY : O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
+ return -1;
+@@ -436,14 +441,16 @@ int main(int argc, char *argv[])
+ }
+
+ if (extts) {
+- memset(&extts_request, 0, sizeof(extts_request));
+- extts_request.index = index;
+- extts_request.flags = PTP_ENABLE_FEATURE;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
+- extts = 0;
+- } else {
+- puts("external time stamp request okay");
++ if (!readonly) {
++ memset(&extts_request, 0, sizeof(extts_request));
++ extts_request.index = index;
++ extts_request.flags = PTP_ENABLE_FEATURE;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ extts = 0;
++ } else {
++ puts("external time stamp request okay");
++ }
+ }
+ for (; extts; extts--) {
+ cnt = read(fd, &event, sizeof(event));
+@@ -455,10 +462,12 @@ int main(int argc, char *argv[])
+ event.t.sec, event.t.nsec);
+ fflush(stdout);
+ }
+- /* Disable the feature again. */
+- extts_request.flags = 0;
+- if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+- perror("PTP_EXTTS_REQUEST");
++ if (!readonly) {
++ /* Disable the feature again. */
++ extts_request.flags = 0;
++ if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
++ perror("PTP_EXTTS_REQUEST");
++ }
+ }
+ }
+
+--
+2.51.0
+