--- /dev/null
+From 9d2789ac9d60c049d26ef6d3005d9c94c5a559e9 Mon Sep 17 00:00:00 2001
+From: Jens Axboe <axboe@kernel.dk>
+Date: Mon, 20 Mar 2023 20:01:25 -0600
+Subject: block/io_uring: pass in issue_flags for uring_cmd task_work handling
+
+From: Jens Axboe <axboe@kernel.dk>
+
+commit 9d2789ac9d60c049d26ef6d3005d9c94c5a559e9 upstream.
+
+io_uring_cmd_done() currently assumes that the uring_lock is held
+when invoked, and while it generally is, this is not guaranteed.
+Pass in the issue_flags associated with it, so that we have
+IO_URING_F_UNLOCKED available to be able to lock the CQ ring
+appropriately when completing events.
+
+Cc: stable@vger.kernel.org
+Fixes: ee692a21e9bf ("fs,io_uring: add infrastructure for uring-cmd")
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/block/ublk_drv.c | 31 ++++++++++++++++++-------------
+ drivers/nvme/host/ioctl.c | 14 ++++++++------
+ include/linux/io_uring.h | 11 ++++++-----
+ io_uring/uring_cmd.c | 10 ++++++----
+ 4 files changed, 38 insertions(+), 28 deletions(-)
+
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -656,7 +656,8 @@ static void __ublk_fail_req(struct ublk_
+ }
+ }
+
+-static void ubq_complete_io_cmd(struct ublk_io *io, int res)
++static void ubq_complete_io_cmd(struct ublk_io *io, int res,
++ unsigned issue_flags)
+ {
+ /* mark this cmd owned by ublksrv */
+ io->flags |= UBLK_IO_FLAG_OWNED_BY_SRV;
+@@ -668,7 +669,7 @@ static void ubq_complete_io_cmd(struct u
+ io->flags &= ~UBLK_IO_FLAG_ACTIVE;
+
+ /* tell ublksrv one io request is coming */
+- io_uring_cmd_done(io->cmd, res, 0);
++ io_uring_cmd_done(io->cmd, res, 0, issue_flags);
+ }
+
+ #define UBLK_REQUEUE_DELAY_MS 3
+@@ -685,7 +686,8 @@ static inline void __ublk_abort_rq(struc
+ mod_delayed_work(system_wq, &ubq->dev->monitor_work, 0);
+ }
+
+-static inline void __ublk_rq_task_work(struct request *req)
++static inline void __ublk_rq_task_work(struct request *req,
++ unsigned issue_flags)
+ {
+ struct ublk_queue *ubq = req->mq_hctx->driver_data;
+ int tag = req->tag;
+@@ -723,7 +725,7 @@ static inline void __ublk_rq_task_work(s
+ pr_devel("%s: need get data. op %d, qid %d tag %d io_flags %x\n",
+ __func__, io->cmd->cmd_op, ubq->q_id,
+ req->tag, io->flags);
+- ubq_complete_io_cmd(io, UBLK_IO_RES_NEED_GET_DATA);
++ ubq_complete_io_cmd(io, UBLK_IO_RES_NEED_GET_DATA, issue_flags);
+ return;
+ }
+ /*
+@@ -761,17 +763,18 @@ static inline void __ublk_rq_task_work(s
+ mapped_bytes >> 9;
+ }
+
+- ubq_complete_io_cmd(io, UBLK_IO_RES_OK);
++ ubq_complete_io_cmd(io, UBLK_IO_RES_OK, issue_flags);
+ }
+
+-static inline void ublk_forward_io_cmds(struct ublk_queue *ubq)
++static inline void ublk_forward_io_cmds(struct ublk_queue *ubq,
++ unsigned issue_flags)
+ {
+ struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds);
+ struct ublk_rq_data *data, *tmp;
+
+ io_cmds = llist_reverse_order(io_cmds);
+ llist_for_each_entry_safe(data, tmp, io_cmds, node)
+- __ublk_rq_task_work(blk_mq_rq_from_pdu(data));
++ __ublk_rq_task_work(blk_mq_rq_from_pdu(data), issue_flags);
+ }
+
+ static inline void ublk_abort_io_cmds(struct ublk_queue *ubq)
+@@ -783,12 +786,12 @@ static inline void ublk_abort_io_cmds(st
+ __ublk_abort_rq(ubq, blk_mq_rq_from_pdu(data));
+ }
+
+-static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd)
++static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, unsigned issue_flags)
+ {
+ struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd);
+ struct ublk_queue *ubq = pdu->ubq;
+
+- ublk_forward_io_cmds(ubq);
++ ublk_forward_io_cmds(ubq, issue_flags);
+ }
+
+ static void ublk_rq_task_work_fn(struct callback_head *work)
+@@ -797,8 +800,9 @@ static void ublk_rq_task_work_fn(struct
+ struct ublk_rq_data, work);
+ struct request *req = blk_mq_rq_from_pdu(data);
+ struct ublk_queue *ubq = req->mq_hctx->driver_data;
++ unsigned issue_flags = IO_URING_F_UNLOCKED;
+
+- ublk_forward_io_cmds(ubq);
++ ublk_forward_io_cmds(ubq, issue_flags);
+ }
+
+ static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
+@@ -1052,7 +1056,8 @@ static void ublk_cancel_queue(struct ubl
+ struct ublk_io *io = &ubq->ios[i];
+
+ if (io->flags & UBLK_IO_FLAG_ACTIVE)
+- io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, 0);
++ io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, 0,
++ IO_URING_F_UNLOCKED);
+ }
+
+ /* all io commands are canceled */
+@@ -1295,7 +1300,7 @@ static int ublk_ch_uring_cmd(struct io_u
+ return -EIOCBQUEUED;
+
+ out:
+- io_uring_cmd_done(cmd, ret, 0);
++ io_uring_cmd_done(cmd, ret, 0, issue_flags);
+ pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n",
+ __func__, cmd_op, tag, ret, io->flags);
+ return -EIOCBQUEUED;
+@@ -2053,7 +2058,7 @@ static int ublk_ctrl_uring_cmd(struct io
+ break;
+ }
+ out:
+- io_uring_cmd_done(cmd, ret, 0);
++ io_uring_cmd_done(cmd, ret, 0, issue_flags);
+ pr_devel("%s: cmd done ret %d cmd_op %x, dev id %d qid %d\n",
+ __func__, ret, cmd->cmd_op, header->dev_id, header->queue_id);
+ return -EIOCBQUEUED;
+--- a/drivers/nvme/host/ioctl.c
++++ b/drivers/nvme/host/ioctl.c
+@@ -463,7 +463,8 @@ static inline struct nvme_uring_cmd_pdu
+ return (struct nvme_uring_cmd_pdu *)&ioucmd->pdu;
+ }
+
+-static void nvme_uring_task_meta_cb(struct io_uring_cmd *ioucmd)
++static void nvme_uring_task_meta_cb(struct io_uring_cmd *ioucmd,
++ unsigned issue_flags)
+ {
+ struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
+ struct request *req = pdu->req;
+@@ -484,17 +485,18 @@ static void nvme_uring_task_meta_cb(stru
+ blk_rq_unmap_user(req->bio);
+ blk_mq_free_request(req);
+
+- io_uring_cmd_done(ioucmd, status, result);
++ io_uring_cmd_done(ioucmd, status, result, issue_flags);
+ }
+
+-static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd)
++static void nvme_uring_task_cb(struct io_uring_cmd *ioucmd,
++ unsigned issue_flags)
+ {
+ struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd);
+
+ if (pdu->bio)
+ blk_rq_unmap_user(pdu->bio);
+
+- io_uring_cmd_done(ioucmd, pdu->nvme_status, pdu->u.result);
++ io_uring_cmd_done(ioucmd, pdu->nvme_status, pdu->u.result, issue_flags);
+ }
+
+ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req,
+@@ -516,7 +518,7 @@ static enum rq_end_io_ret nvme_uring_cmd
+ * Otherwise, move the completion to task work.
+ */
+ if (cookie != NULL && blk_rq_is_poll(req))
+- nvme_uring_task_cb(ioucmd);
++ nvme_uring_task_cb(ioucmd, IO_URING_F_UNLOCKED);
+ else
+ io_uring_cmd_complete_in_task(ioucmd, nvme_uring_task_cb);
+
+@@ -538,7 +540,7 @@ static enum rq_end_io_ret nvme_uring_cmd
+ * Otherwise, move the completion to task work.
+ */
+ if (cookie != NULL && blk_rq_is_poll(req))
+- nvme_uring_task_meta_cb(ioucmd);
++ nvme_uring_task_meta_cb(ioucmd, IO_URING_F_UNLOCKED);
+ else
+ io_uring_cmd_complete_in_task(ioucmd, nvme_uring_task_meta_cb);
+
+--- a/include/linux/io_uring.h
++++ b/include/linux/io_uring.h
+@@ -27,7 +27,7 @@ struct io_uring_cmd {
+ const void *cmd;
+ union {
+ /* callback to defer completions to task context */
+- void (*task_work_cb)(struct io_uring_cmd *cmd);
++ void (*task_work_cb)(struct io_uring_cmd *cmd, unsigned);
+ /* used for polled completion */
+ void *cookie;
+ };
+@@ -39,9 +39,10 @@ struct io_uring_cmd {
+ #if defined(CONFIG_IO_URING)
+ int io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
+ struct iov_iter *iter, void *ioucmd);
+-void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2);
++void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret, ssize_t res2,
++ unsigned issue_flags);
+ void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd,
+- void (*task_work_cb)(struct io_uring_cmd *));
++ void (*task_work_cb)(struct io_uring_cmd *, unsigned));
+ struct sock *io_uring_get_socket(struct file *file);
+ void __io_uring_cancel(bool cancel_all);
+ void __io_uring_free(struct task_struct *tsk);
+@@ -72,11 +73,11 @@ static inline int io_uring_cmd_import_fi
+ return -EOPNOTSUPP;
+ }
+ static inline void io_uring_cmd_done(struct io_uring_cmd *cmd, ssize_t ret,
+- ssize_t ret2)
++ ssize_t ret2, unsigned issue_flags)
+ {
+ }
+ static inline void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd,
+- void (*task_work_cb)(struct io_uring_cmd *))
++ void (*task_work_cb)(struct io_uring_cmd *, unsigned))
+ {
+ }
+ static inline struct sock *io_uring_get_socket(struct file *file)
+--- a/io_uring/uring_cmd.c
++++ b/io_uring/uring_cmd.c
+@@ -15,12 +15,13 @@
+ static void io_uring_cmd_work(struct io_kiocb *req, bool *locked)
+ {
+ struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
++ unsigned issue_flags = *locked ? 0 : IO_URING_F_UNLOCKED;
+
+- ioucmd->task_work_cb(ioucmd);
++ ioucmd->task_work_cb(ioucmd, issue_flags);
+ }
+
+ void io_uring_cmd_complete_in_task(struct io_uring_cmd *ioucmd,
+- void (*task_work_cb)(struct io_uring_cmd *))
++ void (*task_work_cb)(struct io_uring_cmd *, unsigned))
+ {
+ struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
+
+@@ -42,7 +43,8 @@ static inline void io_req_set_cqe32_extr
+ * Called by consumers of io_uring_cmd, if they originally returned
+ * -EIOCBQUEUED upon receiving the command.
+ */
+-void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2)
++void io_uring_cmd_done(struct io_uring_cmd *ioucmd, ssize_t ret, ssize_t res2,
++ unsigned issue_flags)
+ {
+ struct io_kiocb *req = cmd_to_io_kiocb(ioucmd);
+
+@@ -56,7 +58,7 @@ void io_uring_cmd_done(struct io_uring_c
+ /* order with io_iopoll_req_issued() checking ->iopoll_complete */
+ smp_store_release(&req->iopoll_completed, 1);
+ else
+- io_req_complete_post(req, 0);
++ io_req_complete_post(req, issue_flags);
+ }
+ EXPORT_SYMBOL_GPL(io_uring_cmd_done);
+
--- /dev/null
+From fddc6ccc487e5de07b98df8d04118d5dcb5e0407 Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Fri, 17 Mar 2023 12:51:17 +0000
+Subject: cifs: append path to open_enter trace event
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit fddc6ccc487e5de07b98df8d04118d5dcb5e0407 upstream.
+
+We do not dump the file path for smb3_open_enter ftrace
+calls, which is a severe handicap while debugging
+using ftrace evens. This change adds that info.
+
+Unfortunately, we're not updating the path in open params
+in many places; which I had to do as a part of this change.
+SMB2_open gets path in utf16 format, but it's easier of
+path is supplied as char pointer in oparms.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cached_dir.c | 1 +
+ fs/cifs/link.c | 2 ++
+ fs/cifs/smb2inode.c | 1 +
+ fs/cifs/smb2ops.c | 11 +++++++++++
+ fs/cifs/smb2pdu.c | 4 ++--
+ fs/cifs/trace.h | 12 ++++++++----
+ 6 files changed, 25 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/cached_dir.c
++++ b/fs/cifs/cached_dir.c
+@@ -184,6 +184,7 @@ int open_cached_dir(unsigned int xid, st
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = path,
+ .create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE),
+ .desired_access = FILE_READ_ATTRIBUTES,
+ .disposition = FILE_OPEN,
+--- a/fs/cifs/link.c
++++ b/fs/cifs/link.c
+@@ -360,6 +360,7 @@ smb3_query_mf_symlink(unsigned int xid,
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
+ .cifs_sb = cifs_sb,
++ .path = path,
+ .desired_access = GENERIC_READ,
+ .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
+ .disposition = FILE_OPEN,
+@@ -427,6 +428,7 @@ smb3_create_mf_symlink(unsigned int xid,
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
+ .cifs_sb = cifs_sb,
++ .path = path,
+ .desired_access = GENERIC_WRITE,
+ .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
+ .disposition = FILE_CREATE,
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -107,6 +107,7 @@ static int smb2_compound_op(const unsign
+
+ vars->oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = full_path,
+ .desired_access = desired_access,
+ .disposition = create_disposition,
+ .create_options = cifs_create_options(cifs_sb, create_options),
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -731,6 +731,7 @@ smb3_qfs_tcon(const unsigned int xid, st
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = "",
+ .desired_access = FILE_READ_ATTRIBUTES,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -774,6 +775,7 @@ smb2_qfs_tcon(const unsigned int xid, st
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = "",
+ .desired_access = FILE_READ_ATTRIBUTES,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -821,6 +823,7 @@ smb2_is_path_accessible(const unsigned i
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = full_path,
+ .desired_access = FILE_READ_ATTRIBUTES,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -1105,6 +1108,7 @@ smb2_set_ea(const unsigned int xid, stru
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = path,
+ .desired_access = FILE_WRITE_EA,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -2096,6 +2100,7 @@ smb3_notify(const unsigned int xid, stru
+ tcon = cifs_sb_master_tcon(cifs_sb);
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = path,
+ .desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -2168,6 +2173,7 @@ smb2_query_dir_first(const unsigned int
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = path,
+ .desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -2500,6 +2506,7 @@ smb2_query_info_compound(const unsigned
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = path,
+ .desired_access = desired_access,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -2634,6 +2641,7 @@ smb311_queryfs(const unsigned int xid, s
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = "",
+ .desired_access = FILE_READ_ATTRIBUTES,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, 0),
+@@ -2928,6 +2936,7 @@ smb2_query_symlink(const unsigned int xi
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = full_path,
+ .desired_access = FILE_READ_ATTRIBUTES,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, create_options),
+@@ -3068,6 +3077,7 @@ smb2_query_reparse_tag(const unsigned in
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = full_path,
+ .desired_access = FILE_READ_ATTRIBUTES,
+ .disposition = FILE_OPEN,
+ .create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT),
+@@ -3208,6 +3218,7 @@ get_smb2_acl_by_path(struct cifs_sb_info
+
+ oparms = (struct cifs_open_parms) {
+ .tcon = tcon,
++ .path = path,
+ .desired_access = READ_CONTROL,
+ .disposition = FILE_OPEN,
+ /*
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -2742,7 +2742,7 @@ int smb311_posix_mkdir(const unsigned in
+ rqst.rq_nvec = n_iov;
+
+ /* no need to inc num_remote_opens because we close it just below */
+- trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, CREATE_NOT_FILE,
++ trace_smb3_posix_mkdir_enter(xid, tcon->tid, ses->Suid, full_path, CREATE_NOT_FILE,
+ FILE_WRITE_ATTRIBUTES);
+ /* resource #4: response buffer */
+ rc = cifs_send_recv(xid, ses, server,
+@@ -3010,7 +3010,7 @@ SMB2_open(const unsigned int xid, struct
+ if (rc)
+ goto creat_exit;
+
+- trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid,
++ trace_smb3_open_enter(xid, tcon->tid, tcon->ses->Suid, oparms->path,
+ oparms->create_options, oparms->desired_access);
+
+ rc = cifs_send_recv(xid, ses, server,
+--- a/fs/cifs/trace.h
++++ b/fs/cifs/trace.h
+@@ -701,13 +701,15 @@ DECLARE_EVENT_CLASS(smb3_open_enter_clas
+ TP_PROTO(unsigned int xid,
+ __u32 tid,
+ __u64 sesid,
++ const char *full_path,
+ int create_options,
+ int desired_access),
+- TP_ARGS(xid, tid, sesid, create_options, desired_access),
++ TP_ARGS(xid, tid, sesid, full_path, create_options, desired_access),
+ TP_STRUCT__entry(
+ __field(unsigned int, xid)
+ __field(__u32, tid)
+ __field(__u64, sesid)
++ __string(path, full_path)
+ __field(int, create_options)
+ __field(int, desired_access)
+ ),
+@@ -715,11 +717,12 @@ DECLARE_EVENT_CLASS(smb3_open_enter_clas
+ __entry->xid = xid;
+ __entry->tid = tid;
+ __entry->sesid = sesid;
++ __assign_str(path, full_path);
+ __entry->create_options = create_options;
+ __entry->desired_access = desired_access;
+ ),
+- TP_printk("xid=%u sid=0x%llx tid=0x%x cr_opts=0x%x des_access=0x%x",
+- __entry->xid, __entry->sesid, __entry->tid,
++ TP_printk("xid=%u sid=0x%llx tid=0x%x path=%s cr_opts=0x%x des_access=0x%x",
++ __entry->xid, __entry->sesid, __entry->tid, __get_str(path),
+ __entry->create_options, __entry->desired_access)
+ )
+
+@@ -728,9 +731,10 @@ DEFINE_EVENT(smb3_open_enter_class, smb3
+ TP_PROTO(unsigned int xid, \
+ __u32 tid, \
+ __u64 sesid, \
++ const char *full_path, \
+ int create_options, \
+ int desired_access), \
+- TP_ARGS(xid, tid, sesid, create_options, desired_access))
++ TP_ARGS(xid, tid, sesid, full_path, create_options, desired_access))
+
+ DEFINE_SMB3_OPEN_ENTER_EVENT(open_enter);
+ DEFINE_SMB3_OPEN_ENTER_EVENT(posix_mkdir_enter);
--- /dev/null
+From 072a28c8907c841f7d4b56c78bce46d3ee211e73 Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Wed, 8 Mar 2023 12:11:31 +0000
+Subject: cifs: do not poll server interfaces too regularly
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit 072a28c8907c841f7d4b56c78bce46d3ee211e73 upstream.
+
+We have the server interface list hanging off the tcon
+structure today for reasons unknown. So each tcon which is
+connected to a file server can query them separately,
+which is really unnecessary. To avoid this, in the query
+function, we will check the time of last update of the
+interface list, and avoid querying the server if it is
+within a certain range.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2ops.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -530,6 +530,14 @@ parse_server_interfaces(struct network_i
+ p = buf;
+
+ spin_lock(&ses->iface_lock);
++ /* do not query too frequently, this time with lock held */
++ if (ses->iface_last_update &&
++ time_before(jiffies, ses->iface_last_update +
++ (SMB_INTERFACE_POLL_INTERVAL * HZ))) {
++ spin_unlock(&ses->iface_lock);
++ return 0;
++ }
++
+ /*
+ * Go through iface_list and do kref_put to remove
+ * any unused ifaces. ifaces in use will be removed
+@@ -696,6 +704,12 @@ SMB3_request_interfaces(const unsigned i
+ struct network_interface_info_ioctl_rsp *out_buf = NULL;
+ struct cifs_ses *ses = tcon->ses;
+
++ /* do not query too frequently */
++ if (ses->iface_last_update &&
++ time_before(jiffies, ses->iface_last_update +
++ (SMB_INTERFACE_POLL_INTERVAL * HZ)))
++ return 0;
++
+ rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
+ FSCTL_QUERY_NETWORK_INTERFACE_INFO,
+ NULL /* no data input */, 0 /* no data input */,
--- /dev/null
+From d12bc6d26f92c51b28e8f4a146ffcc630b688198 Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Mon, 13 Mar 2023 11:09:12 +0000
+Subject: cifs: dump pending mids for all channels in DebugData
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit d12bc6d26f92c51b28e8f4a146ffcc630b688198 upstream.
+
+Currently, we only dump the pending mid information only
+on the primary channel in /proc/fs/cifs/DebugData.
+If multichannel is active, we do not print the pending MID
+list on secondary channels.
+
+This change will dump the pending mids for all the channels
+based on server->conn_id.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifs_debug.c | 41 +++++++++++++++++++++++++++--------------
+ 1 file changed, 27 insertions(+), 14 deletions(-)
+
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -215,6 +215,7 @@ static int cifs_debug_data_proc_show(str
+ {
+ struct mid_q_entry *mid_entry;
+ struct TCP_Server_Info *server;
++ struct TCP_Server_Info *chan_server;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
+ struct cifs_server_iface *iface;
+@@ -471,23 +472,35 @@ skip_rdma:
+ seq_puts(m, "\t\t[CONNECTED]\n");
+ }
+ spin_unlock(&ses->iface_lock);
++
++ seq_puts(m, "\n\n\tMIDs: ");
++ spin_lock(&ses->chan_lock);
++ for (j = 0; j < ses->chan_count; j++) {
++ chan_server = ses->chans[j].server;
++ if (!chan_server)
++ continue;
++
++ if (list_empty(&chan_server->pending_mid_q))
++ continue;
++
++ seq_printf(m, "\n\tServer ConnectionId: 0x%llx",
++ chan_server->conn_id);
++ spin_lock(&chan_server->mid_lock);
++ list_for_each_entry(mid_entry, &chan_server->pending_mid_q, qhead) {
++ seq_printf(m, "\n\t\tState: %d com: %d pid: %d cbdata: %p mid %llu",
++ mid_entry->mid_state,
++ le16_to_cpu(mid_entry->command),
++ mid_entry->pid,
++ mid_entry->callback_data,
++ mid_entry->mid);
++ }
++ spin_unlock(&chan_server->mid_lock);
++ }
++ spin_unlock(&ses->chan_lock);
++ seq_puts(m, "\n--\n");
+ }
+ if (i == 0)
+ seq_printf(m, "\n\t\t[NONE]");
+-
+- seq_puts(m, "\n\n\tMIDs: ");
+- spin_lock(&server->mid_lock);
+- list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
+- seq_printf(m, "\n\tState: %d com: %d pid:"
+- " %d cbdata: %p mid %llu\n",
+- mid_entry->mid_state,
+- le16_to_cpu(mid_entry->command),
+- mid_entry->pid,
+- mid_entry->callback_data,
+- mid_entry->mid);
+- }
+- spin_unlock(&server->mid_lock);
+- seq_printf(m, "\n--\n");
+ }
+ if (c == 0)
+ seq_printf(m, "\n\t[NONE]");
--- /dev/null
+From 896cd316b841053f6df95ab77b5f1322c16a8e18 Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Thu, 9 Mar 2023 13:23:29 +0000
+Subject: cifs: empty interface list when server doesn't support query interfaces
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit 896cd316b841053f6df95ab77b5f1322c16a8e18 upstream.
+
+When querying server interfaces returns -EOPNOTSUPP,
+clear the list of interfaces. Assumption is that multichannel
+would be disabled too.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2ops.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -717,7 +717,7 @@ SMB3_request_interfaces(const unsigned i
+ if (rc == -EOPNOTSUPP) {
+ cifs_dbg(FYI,
+ "server does not support query network interfaces\n");
+- goto out;
++ ret_data_len = 0;
+ } else if (rc != 0) {
+ cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc);
+ goto out;
--- /dev/null
+From be4fde79812f02914e350bde0bc4cfeae8429378 Mon Sep 17 00:00:00 2001
+From: Paulo Alcantara <pc@manguebit.com>
+Date: Fri, 24 Mar 2023 13:56:33 -0300
+Subject: cifs: fix dentry lookups in directory handle cache
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+commit be4fde79812f02914e350bde0bc4cfeae8429378 upstream.
+
+Get rid of any prefix paths in @path before lookup_positive_unlocked()
+as it will call ->lookup() which already adds those prefix paths
+through build_path_from_dentry().
+
+This has caused a performance regression when mounting shares with a
+prefix path where readdir(2) would end up retrying several times to
+open bad directory names that contained duplicate prefix paths.
+
+Fix this by skipping any prefix paths in @path before calling
+lookup_positive_unlocked().
+
+Fixes: e4029e072673 ("cifs: find and use the dentry for cached non-root directories also")
+Cc: stable@vger.kernel.org # 6.1+
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cached_dir.c | 36 ++++++++++++++++++++++++++++++++++--
+ 1 file changed, 34 insertions(+), 2 deletions(-)
+
+--- a/fs/cifs/cached_dir.c
++++ b/fs/cifs/cached_dir.c
+@@ -99,6 +99,23 @@ path_to_dentry(struct cifs_sb_info *cifs
+ return dentry;
+ }
+
++static const char *path_no_prefix(struct cifs_sb_info *cifs_sb,
++ const char *path)
++{
++ size_t len = 0;
++
++ if (!*path)
++ return path;
++
++ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
++ cifs_sb->prepath) {
++ len = strlen(cifs_sb->prepath) + 1;
++ if (unlikely(len > strlen(path)))
++ return ERR_PTR(-EINVAL);
++ }
++ return path + len;
++}
++
+ /*
+ * Open the and cache a directory handle.
+ * If error then *cfid is not initialized.
+@@ -125,6 +142,7 @@ int open_cached_dir(unsigned int xid, st
+ struct dentry *dentry = NULL;
+ struct cached_fid *cfid;
+ struct cached_fids *cfids;
++ const char *npath;
+
+ if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache ||
+ is_smb1_server(tcon->ses->server))
+@@ -161,6 +179,20 @@ int open_cached_dir(unsigned int xid, st
+ }
+
+ /*
++ * Skip any prefix paths in @path as lookup_positive_unlocked() ends up
++ * calling ->lookup() which already adds those through
++ * build_path_from_dentry(). Also, do it earlier as we might reconnect
++ * below when trying to send compounded request and then potentially
++ * having a different prefix path (e.g. after DFS failover).
++ */
++ npath = path_no_prefix(cifs_sb, path);
++ if (IS_ERR(npath)) {
++ rc = PTR_ERR(npath);
++ kfree(utf16_path);
++ return rc;
++ }
++
++ /*
+ * We do not hold the lock for the open because in case
+ * SMB2_open needs to reconnect.
+ * This is safe because no other thread will be able to get a ref
+@@ -252,10 +284,10 @@ int open_cached_dir(unsigned int xid, st
+ (char *)&cfid->file_all_info))
+ cfid->file_all_info_is_valid = true;
+
+- if (!path[0])
++ if (!npath[0])
+ dentry = dget(cifs_sb->root);
+ else {
+- dentry = path_to_dentry(cifs_sb, path);
++ dentry = path_to_dentry(cifs_sb, npath);
+ if (IS_ERR(dentry)) {
+ rc = -ENOENT;
+ goto oshr_free;
--- /dev/null
+From 2f4e429c846972c8405951a9ff7a82aceeca7461 Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Mon, 20 Feb 2023 13:02:11 +0000
+Subject: cifs: lock chan_lock outside match_session
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit 2f4e429c846972c8405951a9ff7a82aceeca7461 upstream.
+
+Coverity had rightly indicated a possible deadlock
+due to chan_lock being done inside match_session.
+All callers of match_* functions should pick up the
+necessary locks and call them.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Cc: stable@vger.kernel.org
+Fixes: 724244cdb382 ("cifs: protect session channel fields with chan_lock")
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/connect.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -1770,7 +1770,7 @@ out_err:
+ return ERR_PTR(rc);
+ }
+
+-/* this function must be called with ses_lock held */
++/* this function must be called with ses_lock and chan_lock held */
+ static int match_session(struct cifs_ses *ses, struct smb3_fs_context *ctx)
+ {
+ if (ctx->sectype != Unspecified &&
+@@ -1781,12 +1781,8 @@ static int match_session(struct cifs_ses
+ * If an existing session is limited to less channels than
+ * requested, it should not be reused
+ */
+- spin_lock(&ses->chan_lock);
+- if (ses->chan_max < ctx->max_channels) {
+- spin_unlock(&ses->chan_lock);
++ if (ses->chan_max < ctx->max_channels)
+ return 0;
+- }
+- spin_unlock(&ses->chan_lock);
+
+ switch (ses->sectype) {
+ case Kerberos:
+@@ -1914,10 +1910,13 @@ cifs_find_smb_ses(struct TCP_Server_Info
+ spin_unlock(&ses->ses_lock);
+ continue;
+ }
++ spin_lock(&ses->chan_lock);
+ if (!match_session(ses, ctx)) {
++ spin_unlock(&ses->chan_lock);
+ spin_unlock(&ses->ses_lock);
+ continue;
+ }
++ spin_unlock(&ses->chan_lock);
+ spin_unlock(&ses->ses_lock);
+
+ ++ses->ses_count;
+@@ -2743,6 +2742,7 @@ cifs_match_super(struct super_block *sb,
+
+ spin_lock(&tcp_srv->srv_lock);
+ spin_lock(&ses->ses_lock);
++ spin_lock(&ses->chan_lock);
+ spin_lock(&tcon->tc_lock);
+ if (!match_server(tcp_srv, ctx, dfs_super_cmp) ||
+ !match_session(ses, ctx) ||
+@@ -2755,6 +2755,7 @@ cifs_match_super(struct super_block *sb,
+ rc = compare_mount_options(sb, mnt_data);
+ out:
+ spin_unlock(&tcon->tc_lock);
++ spin_unlock(&ses->chan_lock);
+ spin_unlock(&ses->ses_lock);
+ spin_unlock(&tcp_srv->srv_lock);
+
--- /dev/null
+From 175b54abc443b6965e9379b71ec05f7c73c192e9 Mon Sep 17 00:00:00 2001
+From: Shyam Prasad N <sprasad@microsoft.com>
+Date: Mon, 13 Mar 2023 12:17:34 +0000
+Subject: cifs: print session id while listing open files
+
+From: Shyam Prasad N <sprasad@microsoft.com>
+
+commit 175b54abc443b6965e9379b71ec05f7c73c192e9 upstream.
+
+In the output of /proc/fs/cifs/open_files, we only print
+the tree id for the tcon of each open file. It becomes
+difficult to know which tcon these files belong to with
+just the tree id.
+
+This change dumps ses id in addition to all other data today.
+
+Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/cifs_debug.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -175,7 +175,7 @@ static int cifs_debug_files_proc_show(st
+
+ seq_puts(m, "# Version:1\n");
+ seq_puts(m, "# Format:\n");
+- seq_puts(m, "# <tree id> <persistent fid> <flags> <count> <pid> <uid>");
++ seq_puts(m, "# <tree id> <ses id> <persistent fid> <flags> <count> <pid> <uid>");
+ #ifdef CONFIG_CIFS_DEBUG2
+ seq_printf(m, " <filename> <mid>\n");
+ #else
+@@ -188,8 +188,9 @@ static int cifs_debug_files_proc_show(st
+ spin_lock(&tcon->open_file_lock);
+ list_for_each_entry(cfile, &tcon->openFileList, tlist) {
+ seq_printf(m,
+- "0x%x 0x%llx 0x%x %d %d %d %pd",
++ "0x%x 0x%llx 0x%llx 0x%x %d %d %d %pd",
+ tcon->tid,
++ ses->Suid,
+ cfile->fid.persistent_fid,
+ cfile->f_flags,
+ cfile->count,
--- /dev/null
+From a204b490595de71016b2360a1886ec8c12d0afac Mon Sep 17 00:00:00 2001
+From: Joel Selvaraj <joelselvaraj.oss@gmail.com>
+Date: Sun, 12 Mar 2023 23:14:02 -0500
+Subject: scsi: core: Add BLIST_SKIP_VPD_PAGES for SKhynix H28U74301AMR
+
+From: Joel Selvaraj <joelselvaraj.oss@gmail.com>
+
+commit a204b490595de71016b2360a1886ec8c12d0afac upstream.
+
+Xiaomi Poco F1 (qcom/sdm845-xiaomi-beryllium*.dts) comes with a SKhynix
+H28U74301AMR UFS. The sd_read_cpr() operation leads to a 120 second
+timeout, making the device bootup very slow:
+
+[ 121.457736] sd 0:0:0:1: [sdb] tag#23 timing out command, waited 120s
+
+Setting the BLIST_SKIP_VPD_PAGES allows the device to skip the failing
+sd_read_cpr operation and boot normally.
+
+Signed-off-by: Joel Selvaraj <joelselvaraj.oss@gmail.com>
+Link: https://lore.kernel.org/r/20230313041402.39330-1-joelselvaraj.oss@gmail.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/scsi_devinfo.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/scsi/scsi_devinfo.c
++++ b/drivers/scsi/scsi_devinfo.c
+@@ -234,6 +234,7 @@ static struct {
+ {"SGI", "RAID5", "*", BLIST_SPARSELUN},
+ {"SGI", "TP9100", "*", BLIST_REPORTLUN2},
+ {"SGI", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
++ {"SKhynix", "H28U74301AMR", NULL, BLIST_SKIP_VPD_PAGES},
+ {"IBM", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
+ {"SUN", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
+ {"DELL", "Universal Xport", "*", BLIST_NO_ULD_ATTACH},
--- /dev/null
+From 62faca1ca10cc84e99ae7f38aa28df2bc945369b Mon Sep 17 00:00:00 2001
+From: "Chang S. Bae" <chang.seok.bae@intel.com>
+Date: Mon, 27 Feb 2023 13:05:04 -0800
+Subject: selftests/x86/amx: Add a ptrace test
+
+From: Chang S. Bae <chang.seok.bae@intel.com>
+
+commit 62faca1ca10cc84e99ae7f38aa28df2bc945369b upstream.
+
+Include a test case to validate the XTILEDATA injection to the target.
+
+Also, it ensures the kernel's ability to copy states between different
+XSAVE formats.
+
+Refactor the memcmp() code to be usable for the state validation.
+
+Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20230227210504.18520-3-chang.seok.bae%40intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/x86/amx.c | 108 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 105 insertions(+), 3 deletions(-)
+
+--- a/tools/testing/selftests/x86/amx.c
++++ b/tools/testing/selftests/x86/amx.c
+@@ -14,8 +14,10 @@
+ #include <sys/auxv.h>
+ #include <sys/mman.h>
+ #include <sys/shm.h>
++#include <sys/ptrace.h>
+ #include <sys/syscall.h>
+ #include <sys/wait.h>
++#include <sys/uio.h>
+
+ #include "../kselftest.h" /* For __cpuid_count() */
+
+@@ -583,6 +585,13 @@ static void test_dynamic_state(void)
+ _exit(0);
+ }
+
++static inline int __compare_tiledata_state(struct xsave_buffer *xbuf1, struct xsave_buffer *xbuf2)
++{
++ return memcmp(&xbuf1->bytes[xtiledata.xbuf_offset],
++ &xbuf2->bytes[xtiledata.xbuf_offset],
++ xtiledata.size);
++}
++
+ /*
+ * Save current register state and compare it to @xbuf1.'
+ *
+@@ -599,9 +608,7 @@ static inline bool __validate_tiledata_r
+ fatal_error("failed to allocate XSAVE buffer\n");
+
+ xsave(xbuf2, XFEATURE_MASK_XTILEDATA);
+- ret = memcmp(&xbuf1->bytes[xtiledata.xbuf_offset],
+- &xbuf2->bytes[xtiledata.xbuf_offset],
+- xtiledata.size);
++ ret = __compare_tiledata_state(xbuf1, xbuf2);
+
+ free(xbuf2);
+
+@@ -826,6 +833,99 @@ static void test_context_switch(void)
+ free(finfo);
+ }
+
++/* Ptrace test */
++
++/*
++ * Make sure the ptracee has the expanded kernel buffer on the first
++ * use. Then, initialize the state before performing the state
++ * injection from the ptracer.
++ */
++static inline void ptracee_firstuse_tiledata(void)
++{
++ load_rand_tiledata(stashed_xsave);
++ init_xtiledata();
++}
++
++/*
++ * Ptracer injects the randomized tile data state. It also reads
++ * before and after that, which will execute the kernel's state copy
++ * functions. So, the tester is advised to double-check any emitted
++ * kernel messages.
++ */
++static void ptracer_inject_tiledata(pid_t target)
++{
++ struct xsave_buffer *xbuf;
++ struct iovec iov;
++
++ xbuf = alloc_xbuf();
++ if (!xbuf)
++ fatal_error("unable to allocate XSAVE buffer");
++
++ printf("\tRead the init'ed tiledata via ptrace().\n");
++
++ iov.iov_base = xbuf;
++ iov.iov_len = xbuf_size;
++
++ memset(stashed_xsave, 0, xbuf_size);
++
++ if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
++ fatal_error("PTRACE_GETREGSET");
++
++ if (!__compare_tiledata_state(stashed_xsave, xbuf))
++ printf("[OK]\tThe init'ed tiledata was read from ptracee.\n");
++ else
++ printf("[FAIL]\tThe init'ed tiledata was not read from ptracee.\n");
++
++ printf("\tInject tiledata via ptrace().\n");
++
++ load_rand_tiledata(xbuf);
++
++ memcpy(&stashed_xsave->bytes[xtiledata.xbuf_offset],
++ &xbuf->bytes[xtiledata.xbuf_offset],
++ xtiledata.size);
++
++ if (ptrace(PTRACE_SETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
++ fatal_error("PTRACE_SETREGSET");
++
++ if (ptrace(PTRACE_GETREGSET, target, (uint32_t)NT_X86_XSTATE, &iov))
++ fatal_error("PTRACE_GETREGSET");
++
++ if (!__compare_tiledata_state(stashed_xsave, xbuf))
++ printf("[OK]\tTiledata was correctly written to ptracee.\n");
++ else
++ printf("[FAIL]\tTiledata was not correctly written to ptracee.\n");
++}
++
++static void test_ptrace(void)
++{
++ pid_t child;
++ int status;
++
++ child = fork();
++ if (child < 0) {
++ err(1, "fork");
++ } else if (!child) {
++ if (ptrace(PTRACE_TRACEME, 0, NULL, NULL))
++ err(1, "PTRACE_TRACEME");
++
++ ptracee_firstuse_tiledata();
++
++ raise(SIGTRAP);
++ _exit(0);
++ }
++
++ do {
++ wait(&status);
++ } while (WSTOPSIG(status) != SIGTRAP);
++
++ ptracer_inject_tiledata(child);
++
++ ptrace(PTRACE_DETACH, child, NULL, NULL);
++ wait(&status);
++ if (!WIFEXITED(status) || WEXITSTATUS(status))
++ err(1, "ptrace test");
++}
++
+ int main(void)
+ {
+ /* Check hardware availability at first */
+@@ -846,6 +946,8 @@ int main(void)
+ ctxtswtest_config.num_threads = 5;
+ test_context_switch();
+
++ test_ptrace();
++
+ clearhandler(SIGILL);
+ free_stashed_xsave();
+
drm-amd-fix-initialization-mistake-for-nbio-7.3.0.patch
net-sched-act_mirred-better-wording-on-protection-ag.patch
act_mirred-use-the-backlog-for-nested-calls-to-mirre.patch
+cifs-lock-chan_lock-outside-match_session.patch
+cifs-append-path-to-open_enter-trace-event.patch
+cifs-do-not-poll-server-interfaces-too-regularly.patch
+cifs-empty-interface-list-when-server-doesn-t-support-query-interfaces.patch
+cifs-dump-pending-mids-for-all-channels-in-debugdata.patch
+cifs-print-session-id-while-listing-open-files.patch
+cifs-fix-dentry-lookups-in-directory-handle-cache.patch
+x86-mm-do-not-shuffle-cpu-entry-areas-without-kaslr.patch
+x86-fpu-xstate-prevent-false-positive-warning-in-__copy_xstate_uabi_buf.patch
+selftests-x86-amx-add-a-ptrace-test.patch
+scsi-core-add-blist_skip_vpd_pages-for-skhynix-h28u74301amr.patch
+usb-misc-onboard-hub-add-support-for-microchip-usb2517-usb-2.0-hub.patch
+usb-dwc2-fix-a-race-don-t-power-off-on-phy-for-dual-role-mode.patch
+usb-dwc2-drd-fix-inconsistent-mode-if-role-switch-default-mode-host.patch
+usb-dwc2-fix-a-devres-leak-in-hw_enable-upon-suspend-resume.patch
+block-io_uring-pass-in-issue_flags-for-uring_cmd-task_work-handling.patch
+usb-gadget-u_audio-don-t-let-userspace-block-driver-unbind.patch
--- /dev/null
+From 82f5332d3b9872ab5b287e85c57b76d8bb640cd1 Mon Sep 17 00:00:00 2001
+From: Ziyang Huang <hzyitc@outlook.com>
+Date: Tue, 21 Feb 2023 18:30:04 +0800
+Subject: usb: dwc2: drd: fix inconsistent mode if role-switch-default-mode="host"
+
+From: Ziyang Huang <hzyitc@outlook.com>
+
+commit 82f5332d3b9872ab5b287e85c57b76d8bb640cd1 upstream.
+
+Some boards might use USB-A female connector for USB ports, however,
+the port could be connected to a dual-mode USB controller, making it
+also behaves as a peripheral device if male-to-male cable is connected.
+
+In this case, the dts looks like this:
+
+ &usb0 {
+ status = "okay";
+ dr_mode = "otg";
+ usb-role-switch;
+ role-switch-default-mode = "host";
+ };
+
+After boot, dwc2_ovr_init() sets GOTGCTL to GOTGCTL_AVALOVAL and call
+dwc2_force_mode() with parameter host=false, which causes inconsistent
+mode - The hardware is in peripheral mode while the kernel status is
+in host mode.
+
+What we can do now is to call dwc2_drd_role_sw_set() to switch to
+device mode, and everything should work just fine now, even switching
+back to none(default) mode afterwards.
+
+Fixes: e14acb876985 ("usb: dwc2: drd: add role-switch-default-node support")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Ziyang Huang <hzyitc@outlook.com>
+Tested-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Acked-by: Minas Harutyunyan <hminas@synopsys.com>
+Reviewed-by: Amelie Delaunay <amelie.delaunay@foss.st.com>
+Link: https://lore.kernel.org/r/SG2PR01MB204837BF68EDB0E343D2A375C9A59@SG2PR01MB2048.apcprd01.prod.exchangelabs.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc2/drd.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/dwc2/drd.c
++++ b/drivers/usb/dwc2/drd.c
+@@ -35,7 +35,8 @@ static void dwc2_ovr_init(struct dwc2_hs
+
+ spin_unlock_irqrestore(&hsotg->lock, flags);
+
+- dwc2_force_mode(hsotg, (hsotg->dr_mode == USB_DR_MODE_HOST));
++ dwc2_force_mode(hsotg, (hsotg->dr_mode == USB_DR_MODE_HOST) ||
++ (hsotg->role_sw_default_mode == USB_DR_MODE_HOST));
+ }
+
+ static int dwc2_ovr_avalid(struct dwc2_hsotg *hsotg, bool valid)
--- /dev/null
+From f747313249b74f323ddf841a9c8db14d989f296a Mon Sep 17 00:00:00 2001
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Date: Thu, 16 Mar 2023 09:41:27 +0100
+Subject: usb: dwc2: fix a devres leak in hw_enable upon suspend resume
+
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+
+commit f747313249b74f323ddf841a9c8db14d989f296a upstream.
+
+Each time the platform goes to low power, PM suspend / resume routines
+call: __dwc2_lowlevel_hw_enable -> devm_add_action_or_reset().
+This adds a new devres each time.
+This may also happen at runtime, as dwc2_lowlevel_hw_enable() can be
+called from udc_start().
+
+This can be seen with tracing:
+- echo 1 > /sys/kernel/debug/tracing/events/dev/devres_log/enable
+- go to low power
+- cat /sys/kernel/debug/tracing/trace
+
+A new "ADD" entry is found upon each low power cycle:
+... devres_log: 49000000.usb-otg ADD 82a13bba devm_action_release (8 bytes)
+... devres_log: 49000000.usb-otg ADD 49889daf devm_action_release (8 bytes)
+...
+
+A second issue is addressed here:
+- regulator_bulk_enable() is called upon each PM cycle (suspend/resume).
+- regulator_bulk_disable() never gets called.
+
+So the reference count for these regulators constantly increase, by one
+upon each low power cycle, due to missing regulator_bulk_disable() call
+in __dwc2_lowlevel_hw_disable().
+
+The original fix that introduced the devm_add_action_or_reset() call,
+fixed an issue during probe, that happens due to other errors in
+dwc2_driver_probe() -> dwc2_core_reset(). Then the probe fails without
+disabling regulators, when dr_mode == USB_DR_MODE_PERIPHERAL.
+
+Rather fix the error path: disable all the low level hardware in the
+error path, by using the "hsotg->ll_hw_enabled" flag. Checking dr_mode
+has been introduced to avoid a dual call to dwc2_lowlevel_hw_disable().
+"ll_hw_enabled" should achieve the same (and is used currently in the
+remove() routine).
+
+Fixes: 54c196060510 ("usb: dwc2: Always disable regulators on driver teardown")
+Fixes: 33a06f1300a7 ("usb: dwc2: Fix error path in gadget registration")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Link: https://lore.kernel.org/r/20230316084127.126084-1-fabrice.gasnier@foss.st.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc2/platform.c | 16 ++--------------
+ 1 file changed, 2 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/dwc2/platform.c
++++ b/drivers/usb/dwc2/platform.c
+@@ -91,13 +91,6 @@ static int dwc2_get_dr_mode(struct dwc2_
+ return 0;
+ }
+
+-static void __dwc2_disable_regulators(void *data)
+-{
+- struct dwc2_hsotg *hsotg = data;
+-
+- regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+-}
+-
+ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg)
+ {
+ struct platform_device *pdev = to_platform_device(hsotg->dev);
+@@ -108,11 +101,6 @@ static int __dwc2_lowlevel_hw_enable(str
+ if (ret)
+ return ret;
+
+- ret = devm_add_action_or_reset(&pdev->dev,
+- __dwc2_disable_regulators, hsotg);
+- if (ret)
+- return ret;
+-
+ if (hsotg->clk) {
+ ret = clk_prepare_enable(hsotg->clk);
+ if (ret)
+@@ -168,7 +156,7 @@ static int __dwc2_lowlevel_hw_disable(st
+ if (hsotg->clk)
+ clk_disable_unprepare(hsotg->clk);
+
+- return 0;
++ return regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies);
+ }
+
+ /**
+@@ -607,7 +595,7 @@ error_init:
+ if (hsotg->params.activate_stm_id_vb_detection)
+ regulator_disable(hsotg->usb33d);
+ error:
+- if (hsotg->dr_mode != USB_DR_MODE_PERIPHERAL)
++ if (hsotg->ll_hw_enabled)
+ dwc2_lowlevel_hw_disable(hsotg);
+ return retval;
+ }
--- /dev/null
+From 5021383242ada277a38bd052a4c12ed4707faccb Mon Sep 17 00:00:00 2001
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Date: Wed, 15 Mar 2023 15:44:33 +0100
+Subject: usb: dwc2: fix a race, don't power off/on phy for dual-role mode
+
+From: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+
+commit 5021383242ada277a38bd052a4c12ed4707faccb upstream.
+
+When in dual role mode (dr_mode == USB_DR_MODE_OTG), platform probe
+successively basically calls:
+- dwc2_gadget_init()
+- dwc2_hcd_init()
+- dwc2_lowlevel_hw_disable() since recent change [1]
+- usb_add_gadget_udc()
+
+The PHYs (and so the clocks it may provide) shouldn't be disabled for all
+SoCs, in OTG mode, as the HCD part has been initialized.
+
+On STM32 this creates some weird race condition upon boot, when:
+- initially attached as a device, to a HOST
+- and there is a gadget script invoked to setup the device part.
+Below issue becomes systematic, as long as the gadget script isn't
+started by userland: the hardware PHYs (and so the clocks provided by the
+PHYs) remains disabled.
+It ends up in having an endless interrupt storm, before the watchdog
+resets the platform.
+
+[ 16.924163] dwc2 49000000.usb-otg: EPs: 9, dedicated fifos, 952 entries in SPRAM
+[ 16.962704] dwc2 49000000.usb-otg: DWC OTG Controller
+[ 16.966488] dwc2 49000000.usb-otg: new USB bus registered, assigned bus number 2
+[ 16.974051] dwc2 49000000.usb-otg: irq 77, io mem 0x49000000
+[ 17.032170] hub 2-0:1.0: USB hub found
+[ 17.042299] hub 2-0:1.0: 1 port detected
+[ 17.175408] dwc2 49000000.usb-otg: Mode Mismatch Interrupt: currently in Host mode
+[ 17.181741] dwc2 49000000.usb-otg: Mode Mismatch Interrupt: currently in Host mode
+[ 17.189303] dwc2 49000000.usb-otg: Mode Mismatch Interrupt: currently in Host mode
+...
+
+The host part is also not functional, until the gadget part is configured.
+
+The HW may only be disabled for peripheral mode (original init), e.g.
+dr_mode == USB_DR_MODE_PERIPHERAL, until the gadget driver initializes.
+
+But when in USB_DR_MODE_OTG, the HW should remain enabled, as the HCD part
+is able to run, while the gadget part isn't necessarily configured.
+
+I don't fully get the of purpose the original change, that claims disabling
+the hardware is missing. It creates conditions on SOCs using the PHY
+initialization to be completely non working in OTG mode. Original
+change [1] should be reworked to be platform specific.
+
+[1] https://lore.kernel.org/r/20221206-dwc2-gadget-dual-role-v1-2-36515e1092cd@theobroma-systems.com
+
+Fixes: ade23d7b7ec5 ("usb: dwc2: power on/off phy for peripheral mode in dual-role mode")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
+Reviewed-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+Tested-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
+Link: https://lore.kernel.org/r/20230315144433.3095859-1-fabrice.gasnier@foss.st.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc2/gadget.c | 6 ++----
+ drivers/usb/dwc2/platform.c | 3 +--
+ 2 files changed, 3 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/dwc2/gadget.c
++++ b/drivers/usb/dwc2/gadget.c
+@@ -4549,8 +4549,7 @@ static int dwc2_hsotg_udc_start(struct u
+ hsotg->gadget.dev.of_node = hsotg->dev->of_node;
+ hsotg->gadget.speed = USB_SPEED_UNKNOWN;
+
+- if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
+- (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg))) {
++ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) {
+ ret = dwc2_lowlevel_hw_enable(hsotg);
+ if (ret)
+ goto err;
+@@ -4612,8 +4611,7 @@ static int dwc2_hsotg_udc_stop(struct us
+ if (!IS_ERR_OR_NULL(hsotg->uphy))
+ otg_set_peripheral(hsotg->uphy->otg, NULL);
+
+- if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
+- (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg)))
++ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+ dwc2_lowlevel_hw_disable(hsotg);
+
+ return 0;
+--- a/drivers/usb/dwc2/platform.c
++++ b/drivers/usb/dwc2/platform.c
+@@ -576,8 +576,7 @@ static int dwc2_driver_probe(struct plat
+ dwc2_debugfs_init(hsotg);
+
+ /* Gadget code manages lowlevel hw on its own */
+- if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL ||
+- (hsotg->dr_mode == USB_DR_MODE_OTG && dwc2_is_device_mode(hsotg)))
++ if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
+ dwc2_lowlevel_hw_disable(hsotg);
+
+ #if IS_ENABLED(CONFIG_USB_DWC2_PERIPHERAL) || \
--- /dev/null
+From 6c67ed9ad9b83e453e808f9b31a931a20a25629b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Alvin=20=C5=A0ipraga?= <alsi@bang-olufsen.dk>
+Date: Thu, 2 Mar 2023 17:36:47 +0100
+Subject: usb: gadget: u_audio: don't let userspace block driver unbind
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alvin Šipraga <alsi@bang-olufsen.dk>
+
+commit 6c67ed9ad9b83e453e808f9b31a931a20a25629b upstream.
+
+In the unbind callback for f_uac1 and f_uac2, a call to snd_card_free()
+via g_audio_cleanup() will disconnect the card and then wait for all
+resources to be released, which happens when the refcount falls to zero.
+Since userspace can keep the refcount incremented by not closing the
+relevant file descriptor, the call to unbind may block indefinitely.
+This can cause a deadlock during reboot, as evidenced by the following
+blocked task observed on my machine:
+
+ task:reboot state:D stack:0 pid:2827 ppid:569 flags:0x0000000c
+ Call trace:
+ __switch_to+0xc8/0x140
+ __schedule+0x2f0/0x7c0
+ schedule+0x60/0xd0
+ schedule_timeout+0x180/0x1d4
+ wait_for_completion+0x78/0x180
+ snd_card_free+0x90/0xa0
+ g_audio_cleanup+0x2c/0x64
+ afunc_unbind+0x28/0x60
+ ...
+ kernel_restart+0x4c/0xac
+ __do_sys_reboot+0xcc/0x1ec
+ __arm64_sys_reboot+0x28/0x30
+ invoke_syscall+0x4c/0x110
+ ...
+
+The issue can also be observed by opening the card with arecord and
+then stopping the process through the shell before unbinding:
+
+ # arecord -D hw:UAC2Gadget -f S32_LE -c 2 -r 48000 /dev/null
+ Recording WAVE '/dev/null' : Signed 32 bit Little Endian, Rate 48000 Hz, Stereo
+ ^Z[1]+ Stopped arecord -D hw:UAC2Gadget -f S32_LE -c 2 -r 48000 /dev/null
+ # echo gadget.0 > /sys/bus/gadget/drivers/configfs-gadget/unbind
+ (observe that the unbind command never finishes)
+
+Fix the problem by using snd_card_free_when_closed() instead, which will
+still disconnect the card as desired, but defer the task of freeing the
+resources to the core once userspace closes its file descriptor.
+
+Fixes: 132fcb460839 ("usb: gadget: Add Audio Class 2.0 Driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
+Reviewed-by: Ruslan Bilovol <ruslan.bilovol@gmail.com>
+Reviewed-by: John Keeping <john@metanate.com>
+Link: https://lore.kernel.org/r/20230302163648.3349669-1-alvin@pqrs.dk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/u_audio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/function/u_audio.c
++++ b/drivers/usb/gadget/function/u_audio.c
+@@ -1422,7 +1422,7 @@ void g_audio_cleanup(struct g_audio *g_a
+ uac = g_audio->uac;
+ card = uac->card;
+ if (card)
+- snd_card_free(card);
++ snd_card_free_when_closed(card);
+
+ kfree(uac->p_prm.reqs);
+ kfree(uac->c_prm.reqs);
--- /dev/null
+From f7c13cb48e85538709850589b496c4ddb3d3898e Mon Sep 17 00:00:00 2001
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+Date: Thu, 23 Feb 2023 08:39:20 +0100
+Subject: usb: misc: onboard-hub: add support for Microchip USB2517 USB 2.0 hub
+
+From: Alexander Stein <alexander.stein@ew.tq-group.com>
+
+commit f7c13cb48e85538709850589b496c4ddb3d3898e upstream.
+
+Add support for Microchip USB2517 USB 2.0 hub to the onboard usb hub
+driver. Adopt the generic usb-device compatible ("usbVID,PID").
+This hub has the same reset timings as USB2514, so reuse that one.
+There is also an USB2517I which just has industrial temperature range.
+
+Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Cc: stable <stable@kernel.org>
+Acked-by: Matthias Kaehlcke <mka@chromium.org>
+Link: https://lore.kernel.org/r/20230223073920.2912298-1-alexander.stein@ew.tq-group.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/misc/onboard_usb_hub.c | 1 +
+ drivers/usb/misc/onboard_usb_hub.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/usb/misc/onboard_usb_hub.c
++++ b/drivers/usb/misc/onboard_usb_hub.c
+@@ -408,6 +408,7 @@ static void onboard_hub_usbdev_disconnec
+ static const struct usb_device_id onboard_hub_id_table[] = {
+ { USB_DEVICE(VENDOR_ID_GENESYS, 0x0608) }, /* Genesys Logic GL850G USB 2.0 */
+ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2514) }, /* USB2514B USB 2.0 */
++ { USB_DEVICE(VENDOR_ID_MICROCHIP, 0x2517) }, /* USB2517 USB 2.0 */
+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x0411) }, /* RTS5411 USB 3.1 */
+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x5411) }, /* RTS5411 USB 2.1 */
+ { USB_DEVICE(VENDOR_ID_REALTEK, 0x0414) }, /* RTS5414 USB 3.2 */
+--- a/drivers/usb/misc/onboard_usb_hub.h
++++ b/drivers/usb/misc/onboard_usb_hub.h
+@@ -28,6 +28,7 @@ static const struct onboard_hub_pdata ge
+
+ static const struct of_device_id onboard_hub_match[] = {
+ { .compatible = "usb424,2514", .data = µchip_usb424_data, },
++ { .compatible = "usb424,2517", .data = µchip_usb424_data, },
+ { .compatible = "usb451,8140", .data = &ti_tusb8041_data, },
+ { .compatible = "usb451,8142", .data = &ti_tusb8041_data, },
+ { .compatible = "usb5e3,608", .data = &genesys_gl850g_data, },
--- /dev/null
+From b15888840207c2bfe678dd1f68a32db54315e71f Mon Sep 17 00:00:00 2001
+From: "Chang S. Bae" <chang.seok.bae@intel.com>
+Date: Mon, 27 Feb 2023 13:05:03 -0800
+Subject: x86/fpu/xstate: Prevent false-positive warning in __copy_xstate_uabi_buf()
+
+From: Chang S. Bae <chang.seok.bae@intel.com>
+
+commit b15888840207c2bfe678dd1f68a32db54315e71f upstream.
+
+__copy_xstate_to_uabi_buf() copies either from the tasks XSAVE buffer
+or from init_fpstate into the ptrace buffer. Dynamic features, like
+XTILEDATA, have an all zeroes init state and are not saved in
+init_fpstate, which means the corresponding bit is not set in the
+xfeatures bitmap of the init_fpstate header.
+
+But __copy_xstate_to_uabi_buf() retrieves addresses for both the tasks
+xstate and init_fpstate unconditionally via __raw_xsave_addr().
+
+So if the tasks XSAVE buffer has a dynamic feature set, then the
+address retrieval for init_fpstate triggers the warning in
+__raw_xsave_addr() which checks the feature bit in the init_fpstate
+header.
+
+Remove the address retrieval from init_fpstate for extended features.
+They have an all zeroes init state so init_fpstate has zeros for them.
+Then zeroing the user buffer for the init state is the same as copying
+them from init_fpstate.
+
+Fixes: 2308ee57d93d ("x86/fpu/amx: Enable the AMX feature in 64-bit mode")
+Reported-by: Mingwei Zhang <mizhang@google.com>
+Link: https://lore.kernel.org/kvm/20230221163655.920289-2-mizhang@google.com/
+Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Tested-by: Mingwei Zhang <mizhang@google.com>
+Link: https://lore.kernel.org/all/20230227210504.18520-2-chang.seok.bae%40intel.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/fpu/xstate.c | 30 ++++++++++++++----------------
+ 1 file changed, 14 insertions(+), 16 deletions(-)
+
+--- a/arch/x86/kernel/fpu/xstate.c
++++ b/arch/x86/kernel/fpu/xstate.c
+@@ -1118,21 +1118,20 @@ void __copy_xstate_to_uabi_buf(struct me
+ zerofrom = offsetof(struct xregs_state, extended_state_area);
+
+ /*
+- * The ptrace buffer is in non-compacted XSAVE format. In
+- * non-compacted format disabled features still occupy state space,
+- * but there is no state to copy from in the compacted
+- * init_fpstate. The gap tracking will zero these states.
++ * This 'mask' indicates which states to copy from fpstate.
++ * Those extended states that are not present in fpstate are
++ * either disabled or initialized:
++ *
++ * In non-compacted format, disabled features still occupy
++ * state space but there is no state to copy from in the
++ * compacted init_fpstate. The gap tracking will zero these
++ * states.
++ *
++ * The extended features have an all zeroes init state. Thus,
++ * remove them from 'mask' to zero those features in the user
++ * buffer instead of retrieving them from init_fpstate.
+ */
+- mask = fpstate->user_xfeatures;
+-
+- /*
+- * Dynamic features are not present in init_fpstate. When they are
+- * in an all zeros init state, remove those from 'mask' to zero
+- * those features in the user buffer instead of retrieving them
+- * from init_fpstate.
+- */
+- if (fpu_state_size_dynamic())
+- mask &= (header.xfeatures | xinit->header.xcomp_bv);
++ mask = header.xfeatures;
+
+ for_each_extended_xfeature(i, mask) {
+ /*
+@@ -1151,9 +1150,8 @@ void __copy_xstate_to_uabi_buf(struct me
+ pkru.pkru = pkru_val;
+ membuf_write(&to, &pkru, sizeof(pkru));
+ } else {
+- copy_feature(header.xfeatures & BIT_ULL(i), &to,
++ membuf_write(&to,
+ __raw_xsave_addr(xsave, i),
+- __raw_xsave_addr(xinit, i),
+ xstate_sizes[i]);
+ }
+ /*
--- /dev/null
+From a3f547addcaa10df5a226526bc9e2d9a94542344 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Michal=20Koutn=C3=BD?= <mkoutny@suse.com>
+Date: Mon, 6 Mar 2023 20:31:44 +0100
+Subject: x86/mm: Do not shuffle CPU entry areas without KASLR
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Michal Koutný <mkoutny@suse.com>
+
+commit a3f547addcaa10df5a226526bc9e2d9a94542344 upstream.
+
+The commit 97e3d26b5e5f ("x86/mm: Randomize per-cpu entry area") fixed
+an omission of KASLR on CPU entry areas. It doesn't take into account
+KASLR switches though, which may result in unintended non-determinism
+when a user wants to avoid it (e.g. debugging, benchmarking).
+
+Generate only a single combination of CPU entry areas offsets -- the
+linear array that existed prior randomization when KASLR is turned off.
+
+Since we have 3f148f331814 ("x86/kasan: Map shadow for percpu pages on
+demand") and followups, we can use the more relaxed guard
+kasrl_enabled() (in contrast to kaslr_memory_enabled()).
+
+Fixes: 97e3d26b5e5f ("x86/mm: Randomize per-cpu entry area")
+Signed-off-by: Michal Koutný <mkoutny@suse.com>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/all/20230306193144.24605-1-mkoutny%40suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/mm/cpu_entry_area.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/arch/x86/mm/cpu_entry_area.c b/arch/x86/mm/cpu_entry_area.c
+index 7316a8224259..e91500a80963 100644
+--- a/arch/x86/mm/cpu_entry_area.c
++++ b/arch/x86/mm/cpu_entry_area.c
+@@ -10,6 +10,7 @@
+ #include <asm/fixmap.h>
+ #include <asm/desc.h>
+ #include <asm/kasan.h>
++#include <asm/setup.h>
+
+ static DEFINE_PER_CPU_PAGE_ALIGNED(struct entry_stack_page, entry_stack_storage);
+
+@@ -29,6 +30,12 @@ static __init void init_cea_offsets(void)
+ unsigned int max_cea;
+ unsigned int i, j;
+
++ if (!kaslr_enabled()) {
++ for_each_possible_cpu(i)
++ per_cpu(_cea_offset, i) = i;
++ return;
++ }
++
+ max_cea = (CPU_ENTRY_AREA_MAP_SIZE - PAGE_SIZE) / CPU_ENTRY_AREA_SIZE;
+
+ /* O(sodding terrible) */
+--
+2.40.0
+