]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Mar 2023 10:58:36 +0000 (11:58 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Mar 2023 10:58:36 +0000 (11:58 +0100)
added patches:
cifs-check-the-lease-context-if-we-actually-got-a-lease.patch
cifs-don-t-try-to-use-rdma-offload-on-encrypted-connections.patch
cifs-fix-mount-on-old-smb-servers.patch
cifs-fix-uninitialized-memory-read-in-smb3_qfs_tcon.patch
cifs-fix-uninitialized-memory-reads-for-oparms.mode.patch
cifs-introduce-cifs_io_parms-in-smb2_async_writev.patch
cifs-return-a-single-use-cfid-if-we-did-not-get-a-lease.patch
cifs-split-out-smb3_use_rdma_offload-helper.patch
kvm-s390-disable-migration-mode-when-dirty-tracking-is-disabled.patch
s390-discard-.interp-section.patch
s390-extmem-return-correct-segment-type-in-__segment_load.patch
s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch
s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch
scsi-mpi3mr-fix-issues-in-mpi3mr_get_all_tgt_info.patch
scsi-mpi3mr-fix-missing-mrioc-evtack_cmds-initialization.patch
scsi-mpi3mr-remove-unnecessary-memcpy-to-alltgt_info-dmi.patch

17 files changed:
queue-6.1/cifs-check-the-lease-context-if-we-actually-got-a-lease.patch [new file with mode: 0644]
queue-6.1/cifs-don-t-try-to-use-rdma-offload-on-encrypted-connections.patch [new file with mode: 0644]
queue-6.1/cifs-fix-mount-on-old-smb-servers.patch [new file with mode: 0644]
queue-6.1/cifs-fix-uninitialized-memory-read-in-smb3_qfs_tcon.patch [new file with mode: 0644]
queue-6.1/cifs-fix-uninitialized-memory-reads-for-oparms.mode.patch [new file with mode: 0644]
queue-6.1/cifs-introduce-cifs_io_parms-in-smb2_async_writev.patch [new file with mode: 0644]
queue-6.1/cifs-return-a-single-use-cfid-if-we-did-not-get-a-lease.patch [new file with mode: 0644]
queue-6.1/cifs-split-out-smb3_use_rdma_offload-helper.patch [new file with mode: 0644]
queue-6.1/kvm-s390-disable-migration-mode-when-dirty-tracking-is-disabled.patch [new file with mode: 0644]
queue-6.1/s390-discard-.interp-section.patch [new file with mode: 0644]
queue-6.1/s390-extmem-return-correct-segment-type-in-__segment_load.patch [new file with mode: 0644]
queue-6.1/s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch [new file with mode: 0644]
queue-6.1/s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch [new file with mode: 0644]
queue-6.1/scsi-mpi3mr-fix-issues-in-mpi3mr_get_all_tgt_info.patch [new file with mode: 0644]
queue-6.1/scsi-mpi3mr-fix-missing-mrioc-evtack_cmds-initialization.patch [new file with mode: 0644]
queue-6.1/scsi-mpi3mr-remove-unnecessary-memcpy-to-alltgt_info-dmi.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/cifs-check-the-lease-context-if-we-actually-got-a-lease.patch b/queue-6.1/cifs-check-the-lease-context-if-we-actually-got-a-lease.patch
new file mode 100644 (file)
index 0000000..ca2acca
--- /dev/null
@@ -0,0 +1,74 @@
+From 66d45ca1350a3bb8d5f4db8879ccad3ed492337a Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+Date: Fri, 17 Feb 2023 13:35:00 +1000
+Subject: cifs: Check the lease context if we actually got a lease
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+commit 66d45ca1350a3bb8d5f4db8879ccad3ed492337a upstream.
+
+Some servers may return that we got a lease in rsp->OplockLevel
+but then in the lease context contradict this and say we got no lease
+at all.  Thus we need to check the context if we have a lease.
+Additionally, If we do not get a lease we need to make sure we close
+the handle before we return an error to the caller.
+
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Bharath SM <bharathsm@microsoft.com>
+Reviewed-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 |   14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+--- a/fs/cifs/cached_dir.c
++++ b/fs/cifs/cached_dir.c
+@@ -221,8 +221,7 @@ int open_cached_dir(unsigned int xid, st
+               }
+               goto oshr_free;
+       }
+-
+-      atomic_inc(&tcon->num_remote_opens);
++      cfid->is_open = true;
+       o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
+       oparms.fid->persistent_fid = o_rsp->PersistentFileId;
+@@ -239,7 +238,8 @@ int open_cached_dir(unsigned int xid, st
+                           &oparms.fid->epoch,
+                           oparms.fid->lease_key, &oplock,
+                           NULL, NULL);
+-
++      if (!(oplock & SMB2_LEASE_READ_CACHING_HE))
++              goto oshr_free;
+       qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
+       if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info))
+               goto oshr_free;
+@@ -262,7 +262,6 @@ int open_cached_dir(unsigned int xid, st
+       cfid->dentry = dentry;
+       cfid->tcon = tcon;
+       cfid->time = jiffies;
+-      cfid->is_open = true;
+       cfid->has_lease = true;
+ oshr_free:
+@@ -282,12 +281,17 @@ oshr_free:
+       }
+       spin_unlock(&cfids->cfid_list_lock);
+       if (rc) {
++              if (cfid->is_open)
++                      SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
++                                 cfid->fid.volatile_fid);
+               free_cached_dir(cfid);
+               cfid = NULL;
+       }
+-      if (rc == 0)
++      if (rc == 0) {
+               *ret_cfid = cfid;
++              atomic_inc(&tcon->num_remote_opens);
++      }
+       return rc;
+ }
diff --git a/queue-6.1/cifs-don-t-try-to-use-rdma-offload-on-encrypted-connections.patch b/queue-6.1/cifs-don-t-try-to-use-rdma-offload-on-encrypted-connections.patch
new file mode 100644 (file)
index 0000000..a208ad1
--- /dev/null
@@ -0,0 +1,48 @@
+From 3891f6c7655a39065e44980f51ba46bb32be3133 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze@samba.org>
+Date: Wed, 1 Feb 2023 16:21:41 +0100
+Subject: cifs: don't try to use rdma offload on encrypted connections
+
+From: Stefan Metzmacher <metze@samba.org>
+
+commit 3891f6c7655a39065e44980f51ba46bb32be3133 upstream.
+
+The aim of using encryption on a connection is to keep
+the data confidential, so we must not use plaintext rdma offload
+for that data!
+
+It seems that current windows servers and ksmbd would allow
+this, but that's no reason to expose the users data in plaintext!
+And servers hopefully reject this in future.
+
+Note modern windows servers support signed or encrypted offload,
+see MS-SMB2 2.2.3.1.6 SMB2_RDMA_TRANSFORM_CAPABILITIES, but we don't
+support that yet.
+
+Signed-off-by: Stefan Metzmacher <metze@samba.org>
+Cc: Steve French <smfrench@gmail.com>
+Cc: Tom Talpey <tom@talpey.com>
+Cc: Long Li <longli@microsoft.com>
+Cc: Namjae Jeon <linkinjeon@kernel.org>
+Cc: David Howells <dhowells@redhat.com>
+Cc: linux-cifs@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2pdu.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -4081,6 +4081,10 @@ static inline bool smb3_use_rdma_offload
+       if (server->sign)
+               return false;
++      /* we don't support encrypted offload yet */
++      if (smb3_encryption_required(tcon))
++              return false;
++
+       /* offload also has its overhead, so only do it if desired */
+       if (io_parms->length < server->smbd_conn->rdma_readwrite_threshold)
+               return false;
diff --git a/queue-6.1/cifs-fix-mount-on-old-smb-servers.patch b/queue-6.1/cifs-fix-mount-on-old-smb-servers.patch
new file mode 100644 (file)
index 0000000..e1d5184
--- /dev/null
@@ -0,0 +1,140 @@
+From d99e86ebde2d7b3a04190f8d14de5bf6814bf10f Mon Sep 17 00:00:00 2001
+From: Paulo Alcantara <pc@manguebit.com>
+Date: Thu, 16 Feb 2023 15:33:22 -0300
+Subject: cifs: fix mount on old smb servers
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+commit d99e86ebde2d7b3a04190f8d14de5bf6814bf10f upstream.
+
+The client was sending rfc1002 session request packet with a wrong
+length field set, therefore failing to mount shares against old SMB
+servers over port 139.
+
+Fix this by calculating the correct length as specified in rfc1002.
+
+Fixes: d7173623bf0b ("cifs: use ALIGN() and round_up() macros")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paulo Alcantara (SUSE) <pc@manguebit.com>
+Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/connect.c | 94 ++++++++++++++++++-----------------------------
+ 1 file changed, 35 insertions(+), 59 deletions(-)
+
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index b2a04b4e89a5..af49ae53aaf4 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -2843,72 +2843,48 @@ ip_rfc1001_connect(struct TCP_Server_Info *server)
+        * negprot - BB check reconnection in case where second
+        * sessinit is sent but no second negprot
+        */
+-      struct rfc1002_session_packet *ses_init_buf;
+-      unsigned int req_noscope_len;
+-      struct smb_hdr *smb_buf;
++      struct rfc1002_session_packet req = {};
++      struct smb_hdr *smb_buf = (struct smb_hdr *)&req;
++      unsigned int len;
+-      ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
+-                             GFP_KERNEL);
++      req.trailer.session_req.called_len = sizeof(req.trailer.session_req.called_name);
+-      if (ses_init_buf) {
+-              ses_init_buf->trailer.session_req.called_len = 32;
++      if (server->server_RFC1001_name[0] != 0)
++              rfc1002mangle(req.trailer.session_req.called_name,
++                            server->server_RFC1001_name,
++                            RFC1001_NAME_LEN_WITH_NULL);
++      else
++              rfc1002mangle(req.trailer.session_req.called_name,
++                            DEFAULT_CIFS_CALLED_NAME,
++                            RFC1001_NAME_LEN_WITH_NULL);
+-              if (server->server_RFC1001_name[0] != 0)
+-                      rfc1002mangle(ses_init_buf->trailer.
+-                                    session_req.called_name,
+-                                    server->server_RFC1001_name,
+-                                    RFC1001_NAME_LEN_WITH_NULL);
+-              else
+-                      rfc1002mangle(ses_init_buf->trailer.
+-                                    session_req.called_name,
+-                                    DEFAULT_CIFS_CALLED_NAME,
+-                                    RFC1001_NAME_LEN_WITH_NULL);
++      req.trailer.session_req.calling_len = sizeof(req.trailer.session_req.calling_name);
+-              ses_init_buf->trailer.session_req.calling_len = 32;
++      /* calling name ends in null (byte 16) from old smb convention */
++      if (server->workstation_RFC1001_name[0] != 0)
++              rfc1002mangle(req.trailer.session_req.calling_name,
++                            server->workstation_RFC1001_name,
++                            RFC1001_NAME_LEN_WITH_NULL);
++      else
++              rfc1002mangle(req.trailer.session_req.calling_name,
++                            "LINUX_CIFS_CLNT",
++                            RFC1001_NAME_LEN_WITH_NULL);
+-              /*
+-               * calling name ends in null (byte 16) from old smb
+-               * convention.
+-               */
+-              if (server->workstation_RFC1001_name[0] != 0)
+-                      rfc1002mangle(ses_init_buf->trailer.
+-                                    session_req.calling_name,
+-                                    server->workstation_RFC1001_name,
+-                                    RFC1001_NAME_LEN_WITH_NULL);
+-              else
+-                      rfc1002mangle(ses_init_buf->trailer.
+-                                    session_req.calling_name,
+-                                    "LINUX_CIFS_CLNT",
+-                                    RFC1001_NAME_LEN_WITH_NULL);
+-
+-              ses_init_buf->trailer.session_req.scope1 = 0;
+-              ses_init_buf->trailer.session_req.scope2 = 0;
+-              smb_buf = (struct smb_hdr *)ses_init_buf;
+-
+-              /* sizeof RFC1002_SESSION_REQUEST with no scopes */
+-              req_noscope_len = sizeof(struct rfc1002_session_packet) - 2;
+-
+-              /* == cpu_to_be32(0x81000044) */
+-              smb_buf->smb_buf_length =
+-                      cpu_to_be32((RFC1002_SESSION_REQUEST << 24) | req_noscope_len);
+-              rc = smb_send(server, smb_buf, 0x44);
+-              kfree(ses_init_buf);
+-              /*
+-               * RFC1001 layer in at least one server
+-               * requires very short break before negprot
+-               * presumably because not expecting negprot
+-               * to follow so fast.  This is a simple
+-               * solution that works without
+-               * complicating the code and causes no
+-               * significant slowing down on mount
+-               * for everyone else
+-               */
+-              usleep_range(1000, 2000);
+-      }
+       /*
+-       * else the negprot may still work without this
+-       * even though malloc failed
++       * As per rfc1002, @len must be the number of bytes that follows the
++       * length field of a rfc1002 session request payload.
++       */
++      len = sizeof(req) - offsetof(struct rfc1002_session_packet, trailer.session_req);
++
++      smb_buf->smb_buf_length = cpu_to_be32((RFC1002_SESSION_REQUEST << 24) | len);
++      rc = smb_send(server, smb_buf, len);
++      /*
++       * RFC1001 layer in at least one server requires very short break before
++       * negprot presumably because not expecting negprot to follow so fast.
++       * This is a simple solution that works without complicating the code
++       * and causes no significant slowing down on mount for everyone else
+        */
++      usleep_range(1000, 2000);
+       return rc;
+ }
+-- 
+2.39.2
+
diff --git a/queue-6.1/cifs-fix-uninitialized-memory-read-in-smb3_qfs_tcon.patch b/queue-6.1/cifs-fix-uninitialized-memory-read-in-smb3_qfs_tcon.patch
new file mode 100644 (file)
index 0000000..ecd0983
--- /dev/null
@@ -0,0 +1,42 @@
+From d447e794a37288ec7a080aa1b044a8d9deebbab7 Mon Sep 17 00:00:00 2001
+From: Volker Lendecke <vl@samba.org>
+Date: Wed, 11 Jan 2023 12:37:58 +0100
+Subject: cifs: Fix uninitialized memory read in smb3_qfs_tcon()
+
+From: Volker Lendecke <vl@samba.org>
+
+commit d447e794a37288ec7a080aa1b044a8d9deebbab7 upstream.
+
+oparms was not fully initialized
+
+Signed-off-by: Volker Lendecke <vl@samba.org>
+Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
+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 |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -729,12 +729,13 @@ smb3_qfs_tcon(const unsigned int xid, st
+       struct cifs_fid fid;
+       struct cached_fid *cfid = NULL;
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = &fid,
++      };
+       rc = open_cached_dir(xid, tcon, "", cifs_sb, false, &cfid);
+       if (rc == 0)
diff --git a/queue-6.1/cifs-fix-uninitialized-memory-reads-for-oparms.mode.patch b/queue-6.1/cifs-fix-uninitialized-memory-reads-for-oparms.mode.patch
new file mode 100644 (file)
index 0000000..ebfb251
--- /dev/null
@@ -0,0 +1,789 @@
+From de036dcaca65cf94bf7ff09c571c077f02bc92b4 Mon Sep 17 00:00:00 2001
+From: Volker Lendecke <vl@samba.org>
+Date: Wed, 11 Jan 2023 12:37:58 +0100
+Subject: cifs: Fix uninitialized memory reads for oparms.mode
+
+From: Volker Lendecke <vl@samba.org>
+
+commit de036dcaca65cf94bf7ff09c571c077f02bc92b4 upstream.
+
+Use a struct assignment with implicit member initialization
+
+Signed-off-by: Volker Lendecke <vl@samba.org>
+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 |   13 +--
+ fs/cifs/cifsacl.c    |   34 ++++-----
+ fs/cifs/cifssmb.c    |   17 ++--
+ fs/cifs/dir.c        |   19 ++---
+ fs/cifs/file.c       |   35 +++++----
+ fs/cifs/inode.c      |   53 +++++++-------
+ fs/cifs/link.c       |   66 +++++++++--------
+ fs/cifs/smb1ops.c    |   72 ++++++++++---------
+ fs/cifs/smb2inode.c  |   17 ++--
+ fs/cifs/smb2ops.c    |  191 ++++++++++++++++++++++++++-------------------------
+ 10 files changed, 274 insertions(+), 243 deletions(-)
+
+--- a/fs/cifs/cached_dir.c
++++ b/fs/cifs/cached_dir.c
+@@ -181,12 +181,13 @@ int open_cached_dir(unsigned int xid, st
+       rqst[0].rq_iov = open_iov;
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
+-      oparms.tcon = tcon;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE);
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.fid = pfid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE),
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .disposition = FILE_OPEN,
++              .fid = pfid,
++      };
+       rc = SMB2_open_init(tcon, server,
+                           &rqst[0], &oplock, &oparms, utf16_path);
+--- a/fs/cifs/cifsacl.c
++++ b/fs/cifs/cifsacl.c
+@@ -1423,14 +1423,15 @@ static struct cifs_ntsd *get_cifs_acl_by
+       tcon = tlink_tcon(tlink);
+       xid = get_xid();
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = READ_CONTROL;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = READ_CONTROL,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .disposition = FILE_OPEN,
++              .path = path,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+       if (!rc) {
+@@ -1489,14 +1490,15 @@ int set_cifs_acl(struct cifs_ntsd *pnnts
+       else
+               access_flags = WRITE_DAC;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = access_flags;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = access_flags,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .disposition = FILE_OPEN,
++              .path = path,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+       if (rc) {
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -5314,14 +5314,15 @@ CIFSSMBSetPathInfoFB(const unsigned int
+       struct cifs_fid fid;
+       int rc;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_WRITE;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = fileName;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_WRITE,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .disposition = FILE_OPEN,
++              .path = fileName,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+       if (rc)
+--- a/fs/cifs/dir.c
++++ b/fs/cifs/dir.c
+@@ -295,15 +295,16 @@ static int cifs_do_create(struct inode *
+       if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
+               create_options |= CREATE_OPTION_READONLY;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = desired_access;
+-      oparms.create_options = cifs_create_options(cifs_sb, create_options);
+-      oparms.disposition = disposition;
+-      oparms.path = full_path;
+-      oparms.fid = fid;
+-      oparms.reconnect = false;
+-      oparms.mode = mode;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = desired_access,
++              .create_options = cifs_create_options(cifs_sb, create_options),
++              .disposition = disposition,
++              .path = full_path,
++              .fid = fid,
++              .mode = mode,
++      };
+       rc = server->ops->open(xid, &oparms, oplock, buf);
+       if (rc) {
+               cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc);
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -260,14 +260,15 @@ static int cifs_nt_open(const char *full
+       if (f_flags & O_DIRECT)
+               create_options |= CREATE_NO_BUFFER;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = desired_access;
+-      oparms.create_options = cifs_create_options(cifs_sb, create_options);
+-      oparms.disposition = disposition;
+-      oparms.path = full_path;
+-      oparms.fid = fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = desired_access,
++              .create_options = cifs_create_options(cifs_sb, create_options),
++              .disposition = disposition,
++              .path = full_path,
++              .fid = fid,
++      };
+       rc = server->ops->open(xid, &oparms, oplock, buf);
+       if (rc)
+@@ -848,14 +849,16 @@ cifs_reopen_file(struct cifsFileInfo *cf
+       if (server->ops->get_lease_key)
+               server->ops->get_lease_key(inode, &cfile->fid);
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = desired_access;
+-      oparms.create_options = cifs_create_options(cifs_sb, create_options);
+-      oparms.disposition = disposition;
+-      oparms.path = full_path;
+-      oparms.fid = &cfile->fid;
+-      oparms.reconnect = true;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = desired_access,
++              .create_options = cifs_create_options(cifs_sb, create_options),
++              .disposition = disposition,
++              .path = full_path,
++              .fid = &cfile->fid,
++              .reconnect = true,
++      };
+       /*
+        * Can not refresh inode by passing in file_info buf to be returned by
+--- a/fs/cifs/inode.c
++++ b/fs/cifs/inode.c
+@@ -508,14 +508,15 @@ cifs_sfu_type(struct cifs_fattr *fattr,
+               return PTR_ERR(tlink);
+       tcon = tlink_tcon(tlink);
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_READ;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_READ,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_OPEN,
++              .path = path,
++              .fid = &fid,
++      };
+       if (tcon->ses->server->oplocks)
+               oplock = REQ_OPLOCK;
+@@ -1513,14 +1514,15 @@ cifs_rename_pending_delete(const char *f
+               goto out;
+       }
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = DELETE | FILE_WRITE_ATTRIBUTES;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = full_path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = DELETE | FILE_WRITE_ATTRIBUTES,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_OPEN,
++              .path = full_path,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+       if (rc != 0)
+@@ -2107,15 +2109,16 @@ cifs_do_rename(const unsigned int xid, s
+       if (to_dentry->d_parent != from_dentry->d_parent)
+               goto do_rename_exit;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      /* open the file to be renamed -- we need DELETE perms */
+-      oparms.desired_access = DELETE;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = from_path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              /* open the file to be renamed -- we need DELETE perms */
++              .desired_access = DELETE,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_OPEN,
++              .path = from_path,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+       if (rc == 0) {
+--- a/fs/cifs/link.c
++++ b/fs/cifs/link.c
+@@ -271,14 +271,15 @@ cifs_query_mf_symlink(unsigned int xid,
+       int buf_type = CIFS_NO_BUFFER;
+       FILE_ALL_INFO file_info;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_READ;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_READ,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_OPEN,
++              .path = path,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, &file_info);
+       if (rc)
+@@ -313,14 +314,15 @@ cifs_create_mf_symlink(unsigned int xid,
+       struct cifs_open_parms oparms;
+       struct cifs_io_parms io_parms = {0};
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_WRITE;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_CREATE;
+-      oparms.path = path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_WRITE,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_CREATE,
++              .path = path,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+       if (rc)
+@@ -355,13 +357,14 @@ smb3_query_mf_symlink(unsigned int xid,
+       __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+       struct smb2_file_all_info *pfile_info = NULL;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_READ;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_READ,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_OPEN,
++              .fid = &fid,
++      };
+       utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
+       if (utf16_path == NULL)
+@@ -421,14 +424,15 @@ smb3_create_mf_symlink(unsigned int xid,
+       if (!utf16_path)
+               return -ENOMEM;
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_WRITE;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_CREATE;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
+-      oparms.mode = 0644;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_WRITE,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_CREATE,
++              .fid = &fid,
++              .mode = 0644,
++      };
+       rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
+                      NULL, NULL);
+--- a/fs/cifs/smb1ops.c
++++ b/fs/cifs/smb1ops.c
+@@ -576,14 +576,15 @@ static int cifs_query_path_info(const un
+               if (!(le32_to_cpu(fi.Attributes) & ATTR_REPARSE))
+                       return 0;
+-              oparms.tcon = tcon;
+-              oparms.cifs_sb = cifs_sb;
+-              oparms.desired_access = FILE_READ_ATTRIBUTES;
+-              oparms.create_options = cifs_create_options(cifs_sb, 0);
+-              oparms.disposition = FILE_OPEN;
+-              oparms.path = full_path;
+-              oparms.fid = &fid;
+-              oparms.reconnect = false;
++              oparms = (struct cifs_open_parms) {
++                      .tcon = tcon,
++                      .cifs_sb = cifs_sb,
++                      .desired_access = FILE_READ_ATTRIBUTES,
++                      .create_options = cifs_create_options(cifs_sb, 0),
++                      .disposition = FILE_OPEN,
++                      .path = full_path,
++                      .fid = &fid,
++              };
+               /* Need to check if this is a symbolic link or not */
+               tmprc = CIFS_open(xid, &oparms, &oplock, NULL);
+@@ -823,14 +824,15 @@ smb_set_file_info(struct inode *inode, c
+               goto out;
+       }
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = SYNCHRONIZE | FILE_WRITE_ATTRIBUTES;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = full_path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR),
++              .disposition = FILE_OPEN,
++              .path = full_path,
++              .fid = &fid,
++      };
+       cifs_dbg(FYI, "calling SetFileInfo since SetPathInfo for times not supported by this server\n");
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+@@ -998,15 +1000,16 @@ cifs_query_symlink(const unsigned int xi
+               goto out;
+       }
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.create_options = cifs_create_options(cifs_sb,
+-                                                  OPEN_REPARSE_POINT);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = full_path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .create_options = cifs_create_options(cifs_sb,
++                                                    OPEN_REPARSE_POINT),
++              .disposition = FILE_OPEN,
++              .path = full_path,
++              .fid = &fid,
++      };
+       rc = CIFS_open(xid, &oparms, &oplock, NULL);
+       if (rc)
+@@ -1115,15 +1118,16 @@ cifs_make_node(unsigned int xid, struct
+       cifs_dbg(FYI, "sfu compat create special file\n");
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_WRITE;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
+-                                                  CREATE_OPTION_SPECIAL);
+-      oparms.disposition = FILE_CREATE;
+-      oparms.path = full_path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_WRITE,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
++                                                    CREATE_OPTION_SPECIAL),
++              .disposition = FILE_CREATE,
++              .path = full_path,
++              .fid = &fid,
++      };
+       if (tcon->ses->server->oplocks)
+               oplock = REQ_OPLOCK;
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -104,14 +104,15 @@ static int smb2_compound_op(const unsign
+               goto finished;
+       }
+-      vars->oparms.tcon = tcon;
+-      vars->oparms.desired_access = desired_access;
+-      vars->oparms.disposition = create_disposition;
+-      vars->oparms.create_options = cifs_create_options(cifs_sb, create_options);
+-      vars->oparms.fid = &fid;
+-      vars->oparms.reconnect = false;
+-      vars->oparms.mode = mode;
+-      vars->oparms.cifs_sb = cifs_sb;
++      vars->oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = desired_access,
++              .disposition = create_disposition,
++              .create_options = cifs_create_options(cifs_sb, create_options),
++              .fid = &fid,
++              .mode = mode,
++              .cifs_sb = cifs_sb,
++      };
+       rqst[num_rqst].rq_iov = &vars->open_iov[0];
+       rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE;
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -772,12 +772,13 @@ smb2_qfs_tcon(const unsigned int xid, st
+       struct cifs_open_parms oparms;
+       struct cifs_fid fid;
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = &fid,
++      };
+       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
+                      NULL, NULL);
+@@ -817,12 +818,13 @@ smb2_is_path_accessible(const unsigned i
+       if (!utf16_path)
+               return -ENOMEM;
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = &fid,
++      };
+       rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
+                      &err_iov, &err_buftype);
+@@ -1098,13 +1100,13 @@ smb2_set_ea(const unsigned int xid, stru
+       rqst[0].rq_iov = open_iov;
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
+-      memset(&oparms, 0, sizeof(oparms));
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_WRITE_EA;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_WRITE_EA,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = &fid,
++      };
+       rc = SMB2_open_init(tcon, server,
+                           &rqst[0], &oplock, &oparms, utf16_path);
+@@ -1454,12 +1456,12 @@ smb2_ioctl_query_info(const unsigned int
+       rqst[0].rq_iov = &vars->open_iov[0];
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
+-      memset(&oparms, 0, sizeof(oparms));
+-      oparms.tcon = tcon;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, create_options);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, create_options),
++              .fid = &fid,
++      };
+       if (qi.flags & PASSTHRU_FSCTL) {
+               switch (qi.info_type & FSCTL_DEVICE_ACCESS_MASK) {
+@@ -2089,12 +2091,13 @@ smb3_notify(const unsigned int xid, stru
+       }
+       tcon = cifs_sb_master_tcon(cifs_sb);
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = &fid,
++      };
+       rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL,
+                      NULL);
+@@ -2160,12 +2163,13 @@ smb2_query_dir_first(const unsigned int
+       rqst[0].rq_iov = open_iov;
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = fid,
++      };
+       rc = SMB2_open_init(tcon, server,
+                           &rqst[0], &oplock, &oparms, utf16_path);
+@@ -2491,12 +2495,13 @@ smb2_query_info_compound(const unsigned
+       rqst[0].rq_iov = open_iov;
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
+-      oparms.tcon = tcon;
+-      oparms.desired_access = desired_access;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = desired_access,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = &fid,
++      };
+       rc = SMB2_open_init(tcon, server,
+                           &rqst[0], &oplock, &oparms, utf16_path);
+@@ -2624,12 +2629,13 @@ smb311_queryfs(const unsigned int xid, s
+       if (!tcon->posix_extensions)
+               return smb2_queryfs(xid, tcon, cifs_sb, buf);
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .fid = &fid,
++      };
+       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
+                      NULL, NULL);
+@@ -2917,13 +2923,13 @@ smb2_query_symlink(const unsigned int xi
+       rqst[0].rq_iov = open_iov;
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
+-      memset(&oparms, 0, sizeof(oparms));
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, create_options);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, create_options),
++              .fid = &fid,
++      };
+       rc = SMB2_open_init(tcon, server,
+                           &rqst[0], &oplock, &oparms, utf16_path);
+@@ -3057,13 +3063,13 @@ smb2_query_reparse_tag(const unsigned in
+       rqst[0].rq_iov = open_iov;
+       rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
+-      memset(&oparms, 0, sizeof(oparms));
+-      oparms.tcon = tcon;
+-      oparms.desired_access = FILE_READ_ATTRIBUTES;
+-      oparms.disposition = FILE_OPEN;
+-      oparms.create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT);
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = FILE_READ_ATTRIBUTES,
++              .disposition = FILE_OPEN,
++              .create_options = cifs_create_options(cifs_sb, OPEN_REPARSE_POINT),
++              .fid = &fid,
++      };
+       rc = SMB2_open_init(tcon, server,
+                           &rqst[0], &oplock, &oparms, utf16_path);
+@@ -3197,17 +3203,20 @@ get_smb2_acl_by_path(struct cifs_sb_info
+               return ERR_PTR(rc);
+       }
+-      oparms.tcon = tcon;
+-      oparms.desired_access = READ_CONTROL;
+-      oparms.disposition = FILE_OPEN;
+-      /*
+-       * When querying an ACL, even if the file is a symlink we want to open
+-       * the source not the target, and so the protocol requires that the
+-       * client specify this flag when opening a reparse point
+-       */
+-      oparms.create_options = cifs_create_options(cifs_sb, 0) | OPEN_REPARSE_POINT;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = READ_CONTROL,
++              .disposition = FILE_OPEN,
++              /*
++               * When querying an ACL, even if the file is a symlink
++               * we want to open the source not the target, and so
++               * the protocol requires that the client specify this
++               * flag when opening a reparse point
++               */
++              .create_options = cifs_create_options(cifs_sb, 0) |
++                                OPEN_REPARSE_POINT,
++              .fid = &fid,
++      };
+       if (info & SACL_SECINFO)
+               oparms.desired_access |= SYSTEM_SECURITY;
+@@ -3266,13 +3275,14 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, _
+               return rc;
+       }
+-      oparms.tcon = tcon;
+-      oparms.desired_access = access_flags;
+-      oparms.create_options = cifs_create_options(cifs_sb, 0);
+-      oparms.disposition = FILE_OPEN;
+-      oparms.path = path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .desired_access = access_flags,
++              .create_options = cifs_create_options(cifs_sb, 0),
++              .disposition = FILE_OPEN,
++              .path = path,
++              .fid = &fid,
++      };
+       rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL,
+                      NULL, NULL);
+@@ -5134,15 +5144,16 @@ smb2_make_node(unsigned int xid, struct
+       cifs_dbg(FYI, "sfu compat create special file\n");
+-      oparms.tcon = tcon;
+-      oparms.cifs_sb = cifs_sb;
+-      oparms.desired_access = GENERIC_WRITE;
+-      oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
+-                                                  CREATE_OPTION_SPECIAL);
+-      oparms.disposition = FILE_CREATE;
+-      oparms.path = full_path;
+-      oparms.fid = &fid;
+-      oparms.reconnect = false;
++      oparms = (struct cifs_open_parms) {
++              .tcon = tcon,
++              .cifs_sb = cifs_sb,
++              .desired_access = GENERIC_WRITE,
++              .create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
++                                                    CREATE_OPTION_SPECIAL),
++              .disposition = FILE_CREATE,
++              .path = full_path,
++              .fid = &fid,
++      };
+       if (tcon->ses->server->oplocks)
+               oplock = REQ_OPLOCK;
diff --git a/queue-6.1/cifs-introduce-cifs_io_parms-in-smb2_async_writev.patch b/queue-6.1/cifs-introduce-cifs_io_parms-in-smb2_async_writev.patch
new file mode 100644 (file)
index 0000000..09826d7
--- /dev/null
@@ -0,0 +1,138 @@
+From d643a8a446fc46c06837d08a056f69da2ff16025 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze@samba.org>
+Date: Wed, 1 Feb 2023 16:21:39 +0100
+Subject: cifs: introduce cifs_io_parms in smb2_async_writev()
+
+From: Stefan Metzmacher <metze@samba.org>
+
+commit d643a8a446fc46c06837d08a056f69da2ff16025 upstream.
+
+This will simplify the following changes and makes it easy to get
+in passed in from the caller in future.
+
+Signed-off-by: Stefan Metzmacher <metze@samba.org>
+Cc: Steve French <smfrench@gmail.com>
+Cc: Tom Talpey <tom@talpey.com>
+Cc: Long Li <longli@microsoft.com>
+Cc: Namjae Jeon <linkinjeon@kernel.org>
+Cc: David Howells <dhowells@redhat.com>
+Cc: linux-cifs@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2pdu.c |   53 +++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 39 insertions(+), 14 deletions(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -4504,10 +4504,27 @@ smb2_async_writev(struct cifs_writedata
+       struct kvec iov[1];
+       struct smb_rqst rqst = { };
+       unsigned int total_len;
++      struct cifs_io_parms _io_parms;
++      struct cifs_io_parms *io_parms = NULL;
+       if (!wdata->server)
+               server = wdata->server = cifs_pick_channel(tcon->ses);
++      /*
++       * in future we may get cifs_io_parms passed in from the caller,
++       * but for now we construct it here...
++       */
++      _io_parms = (struct cifs_io_parms) {
++              .tcon = tcon,
++              .server = server,
++              .offset = wdata->offset,
++              .length = wdata->bytes,
++              .persistent_fid = wdata->cfile->fid.persistent_fid,
++              .volatile_fid = wdata->cfile->fid.volatile_fid,
++              .pid = wdata->pid,
++      };
++      io_parms = &_io_parms;
++
+       rc = smb2_plain_req_init(SMB2_WRITE, tcon, server,
+                                (void **) &req, &total_len);
+       if (rc)
+@@ -4517,26 +4534,31 @@ smb2_async_writev(struct cifs_writedata
+               flags |= CIFS_TRANSFORM_REQ;
+       shdr = (struct smb2_hdr *)req;
+-      shdr->Id.SyncId.ProcessId = cpu_to_le32(wdata->cfile->pid);
++      shdr->Id.SyncId.ProcessId = cpu_to_le32(io_parms->pid);
+-      req->PersistentFileId = wdata->cfile->fid.persistent_fid;
+-      req->VolatileFileId = wdata->cfile->fid.volatile_fid;
++      req->PersistentFileId = io_parms->persistent_fid;
++      req->VolatileFileId = io_parms->volatile_fid;
+       req->WriteChannelInfoOffset = 0;
+       req->WriteChannelInfoLength = 0;
+       req->Channel = 0;
+-      req->Offset = cpu_to_le64(wdata->offset);
++      req->Offset = cpu_to_le64(io_parms->offset);
+       req->DataOffset = cpu_to_le16(
+                               offsetof(struct smb2_write_req, Buffer));
+       req->RemainingBytes = 0;
+-      trace_smb3_write_enter(0 /* xid */, wdata->cfile->fid.persistent_fid,
+-              tcon->tid, tcon->ses->Suid, wdata->offset, wdata->bytes);
++      trace_smb3_write_enter(0 /* xid */,
++                             io_parms->persistent_fid,
++                             io_parms->tcon->tid,
++                             io_parms->tcon->ses->Suid,
++                             io_parms->offset,
++                             io_parms->length);
++
+ #ifdef CONFIG_CIFS_SMB_DIRECT
+       /*
+        * If we want to do a server RDMA read, fill in and append
+        * smbd_buffer_descriptor_v1 to the end of write request
+        */
+-      if (server->rdma && !server->sign && wdata->bytes >=
++      if (server->rdma && !server->sign && io_parms->length >=
+               server->smbd_conn->rdma_readwrite_threshold) {
+               struct smbd_buffer_descriptor_v1 *v1;
+@@ -4590,14 +4612,14 @@ smb2_async_writev(struct cifs_writedata
+       }
+ #endif
+       cifs_dbg(FYI, "async write at %llu %u bytes\n",
+-               wdata->offset, wdata->bytes);
++               io_parms->offset, io_parms->length);
+ #ifdef CONFIG_CIFS_SMB_DIRECT
+       /* For RDMA read, I/O size is in RemainingBytes not in Length */
+       if (!wdata->mr)
+-              req->Length = cpu_to_le32(wdata->bytes);
++              req->Length = cpu_to_le32(io_parms->length);
+ #else
+-      req->Length = cpu_to_le32(wdata->bytes);
++      req->Length = cpu_to_le32(io_parms->length);
+ #endif
+       if (wdata->credits.value > 0) {
+@@ -4605,7 +4627,7 @@ smb2_async_writev(struct cifs_writedata
+                                                   SMB2_MAX_BUFFER_SIZE));
+               shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8);
+-              rc = adjust_credits(server, &wdata->credits, wdata->bytes);
++              rc = adjust_credits(server, &wdata->credits, io_parms->length);
+               if (rc)
+                       goto async_writev_out;
+@@ -4618,9 +4640,12 @@ smb2_async_writev(struct cifs_writedata
+       if (rc) {
+               trace_smb3_write_err(0 /* no xid */,
+-                                   req->PersistentFileId,
+-                                   tcon->tid, tcon->ses->Suid, wdata->offset,
+-                                   wdata->bytes, rc);
++                                   io_parms->persistent_fid,
++                                   io_parms->tcon->tid,
++                                   io_parms->tcon->ses->Suid,
++                                   io_parms->offset,
++                                   io_parms->length,
++                                   rc);
+               kref_put(&wdata->refcount, release);
+               cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
+       }
diff --git a/queue-6.1/cifs-return-a-single-use-cfid-if-we-did-not-get-a-lease.patch b/queue-6.1/cifs-return-a-single-use-cfid-if-we-did-not-get-a-lease.patch
new file mode 100644 (file)
index 0000000..89a6539
--- /dev/null
@@ -0,0 +1,95 @@
+From 8e843bf38f7be0766642a91523cfa65f2b021a8a Mon Sep 17 00:00:00 2001
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+Date: Fri, 17 Feb 2023 13:35:01 +1000
+Subject: cifs: return a single-use cfid if we did not get a lease
+
+From: Ronnie Sahlberg <lsahlber@redhat.com>
+
+commit 8e843bf38f7be0766642a91523cfa65f2b021a8a upstream.
+
+If we did not get a lease we can still return a single use cfid to the caller.
+The cfid will not have has_lease set and will thus not be shared with any
+other concurrent users and will be freed immediately when the caller
+drops the handle.
+
+This avoids extra roundtrips for servers that do not support directory leases
+where they would first fail to get a cfid with a lease and then fallback
+to try a normal SMB2_open()
+
+Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Bharath SM <bharathsm@microsoft.com>
+Reviewed-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 |   16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/fs/cifs/cached_dir.c
++++ b/fs/cifs/cached_dir.c
+@@ -14,6 +14,7 @@
+ static struct cached_fid *init_cached_dir(const char *path);
+ static void free_cached_dir(struct cached_fid *cfid);
++static void smb2_close_cached_fid(struct kref *ref);
+ static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
+                                                   const char *path,
+@@ -221,6 +222,7 @@ int open_cached_dir(unsigned int xid, st
+               }
+               goto oshr_free;
+       }
++      cfid->tcon = tcon;
+       cfid->is_open = true;
+       o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
+@@ -233,7 +235,6 @@ int open_cached_dir(unsigned int xid, st
+       if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE)
+               goto oshr_free;
+-
+       smb2_parse_contexts(server, o_rsp,
+                           &oparms.fid->epoch,
+                           oparms.fid->lease_key, &oplock,
+@@ -260,7 +261,6 @@ int open_cached_dir(unsigned int xid, st
+               }
+       }
+       cfid->dentry = dentry;
+-      cfid->tcon = tcon;
+       cfid->time = jiffies;
+       cfid->has_lease = true;
+@@ -271,7 +271,7 @@ oshr_free:
+       free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
+       free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
+       spin_lock(&cfids->cfid_list_lock);
+-      if (!cfid->has_lease) {
++      if (rc && !cfid->has_lease) {
+               if (cfid->on_list) {
+                       list_del(&cfid->entry);
+                       cfid->on_list = false;
+@@ -280,6 +280,15 @@ oshr_free:
+               rc = -ENOENT;
+       }
+       spin_unlock(&cfids->cfid_list_lock);
++      if (!rc && !cfid->has_lease) {
++              /*
++               * We are guaranteed to have two references at this point.
++               * One for the caller and one for a potential lease.
++               * Release the Lease-ref so that the directory will be closed
++               * when the caller closes the cached handle.
++               */
++              kref_put(&cfid->refcount, smb2_close_cached_fid);
++      }
+       if (rc) {
+               if (cfid->is_open)
+                       SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
+@@ -340,6 +349,7 @@ smb2_close_cached_fid(struct kref *ref)
+       if (cfid->is_open) {
+               SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
+                          cfid->fid.volatile_fid);
++              atomic_dec(&cfid->tcon->num_remote_opens);
+       }
+       free_cached_dir(cfid);
diff --git a/queue-6.1/cifs-split-out-smb3_use_rdma_offload-helper.patch b/queue-6.1/cifs-split-out-smb3_use_rdma_offload-helper.patch
new file mode 100644 (file)
index 0000000..c51078a
--- /dev/null
@@ -0,0 +1,83 @@
+From a6559cc1d35d3eeafb0296aca347b2f745a28a74 Mon Sep 17 00:00:00 2001
+From: Stefan Metzmacher <metze@samba.org>
+Date: Wed, 1 Feb 2023 16:21:40 +0100
+Subject: cifs: split out smb3_use_rdma_offload() helper
+
+From: Stefan Metzmacher <metze@samba.org>
+
+commit a6559cc1d35d3eeafb0296aca347b2f745a28a74 upstream.
+
+We should have the logic to decide if we want rdma offload
+in a single spot in order to advance it in future.
+
+Signed-off-by: Stefan Metzmacher <metze@samba.org>
+Cc: Steve French <smfrench@gmail.com>
+Cc: Tom Talpey <tom@talpey.com>
+Cc: Long Li <longli@microsoft.com>
+Cc: Namjae Jeon <linkinjeon@kernel.org>
+Cc: David Howells <dhowells@redhat.com>
+Cc: linux-cifs@vger.kernel.org
+Cc: stable@vger.kernel.org
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/cifs/smb2pdu.c |   34 ++++++++++++++++++++++++++++------
+ 1 file changed, 28 insertions(+), 6 deletions(-)
+
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -4063,6 +4063,32 @@ SMB2_flush(const unsigned int xid, struc
+       return rc;
+ }
++#ifdef CONFIG_CIFS_SMB_DIRECT
++static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)
++{
++      struct TCP_Server_Info *server = io_parms->server;
++      struct cifs_tcon *tcon = io_parms->tcon;
++
++      /* we can only offload if we're connected */
++      if (!server || !tcon)
++              return false;
++
++      /* we can only offload on an rdma connection */
++      if (!server->rdma || !server->smbd_conn)
++              return false;
++
++      /* we don't support signed offload yet */
++      if (server->sign)
++              return false;
++
++      /* offload also has its overhead, so only do it if desired */
++      if (io_parms->length < server->smbd_conn->rdma_readwrite_threshold)
++              return false;
++
++      return true;
++}
++#endif /* CONFIG_CIFS_SMB_DIRECT */
++
+ /*
+  * To form a chain of read requests, any read requests after the first should
+  * have the end_of_chain boolean set to true.
+@@ -4106,9 +4132,7 @@ smb2_new_read_req(void **buf, unsigned i
+        * If we want to do a RDMA write, fill in and append
+        * smbd_buffer_descriptor_v1 to the end of read request
+        */
+-      if (server->rdma && rdata && !server->sign &&
+-              rdata->bytes >= server->smbd_conn->rdma_readwrite_threshold) {
+-
++      if (smb3_use_rdma_offload(io_parms)) {
+               struct smbd_buffer_descriptor_v1 *v1;
+               bool need_invalidate = server->dialect == SMB30_PROT_ID;
+@@ -4558,9 +4582,7 @@ smb2_async_writev(struct cifs_writedata
+        * If we want to do a server RDMA read, fill in and append
+        * smbd_buffer_descriptor_v1 to the end of write request
+        */
+-      if (server->rdma && !server->sign && io_parms->length >=
+-              server->smbd_conn->rdma_readwrite_threshold) {
+-
++      if (smb3_use_rdma_offload(io_parms)) {
+               struct smbd_buffer_descriptor_v1 *v1;
+               bool need_invalidate = server->dialect == SMB30_PROT_ID;
diff --git a/queue-6.1/kvm-s390-disable-migration-mode-when-dirty-tracking-is-disabled.patch b/queue-6.1/kvm-s390-disable-migration-mode-when-dirty-tracking-is-disabled.patch
new file mode 100644 (file)
index 0000000..a232513
--- /dev/null
@@ -0,0 +1,158 @@
+From f2d3155e2a6bac44d16f04415a321e8707d895c6 Mon Sep 17 00:00:00 2001
+From: Nico Boehr <nrb@linux.ibm.com>
+Date: Fri, 27 Jan 2023 15:05:32 +0100
+Subject: KVM: s390: disable migration mode when dirty tracking is disabled
+
+From: Nico Boehr <nrb@linux.ibm.com>
+
+commit f2d3155e2a6bac44d16f04415a321e8707d895c6 upstream.
+
+Migration mode is a VM attribute which enables tracking of changes in
+storage attributes (PGSTE). It assumes dirty tracking is enabled on all
+memslots to keep a dirty bitmap of pages with changed storage attributes.
+
+When enabling migration mode, we currently check that dirty tracking is
+enabled for all memslots. However, userspace can disable dirty tracking
+without disabling migration mode.
+
+Since migration mode is pointless with dirty tracking disabled, disable
+migration mode whenever userspace disables dirty tracking on any slot.
+
+Also update the documentation to clarify that dirty tracking must be
+enabled when enabling migration mode, which is already enforced by the
+code in kvm_s390_vm_start_migration().
+
+Also highlight in the documentation for KVM_S390_GET_CMMA_BITS that it
+can now fail with -EINVAL when dirty tracking is disabled while
+migration mode is on. Move all the error codes to a table so this stays
+readable.
+
+To disable migration mode, slots_lock should be held, which is taken
+in kvm_set_memory_region() and thus held in
+kvm_arch_prepare_memory_region().
+
+Restructure the prepare code a bit so all the sanity checking is done
+before disabling migration mode. This ensures migration mode isn't
+disabled when some sanity check fails.
+
+Cc: stable@vger.kernel.org
+Fixes: 190df4a212a7 ("KVM: s390: CMMA tracking, ESSA emulation, migration mode")
+Signed-off-by: Nico Boehr <nrb@linux.ibm.com>
+Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
+Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
+Link: https://lore.kernel.org/r/20230127140532.230651-2-nrb@linux.ibm.com
+Message-Id: <20230127140532.230651-2-nrb@linux.ibm.com>
+[frankja@linux.ibm.com: fixed commit message typo, moved api.rst error table upwards]
+Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/virt/kvm/api.rst        |   18 ++++++++-----
+ Documentation/virt/kvm/devices/vm.rst |    4 ++
+ arch/s390/kvm/kvm-s390.c              |   47 +++++++++++++++++++++++-----------
+ 3 files changed, 48 insertions(+), 21 deletions(-)
+
+--- a/Documentation/virt/kvm/api.rst
++++ b/Documentation/virt/kvm/api.rst
+@@ -4483,6 +4483,18 @@ not holding a previously reported uncorr
+ :Parameters: struct kvm_s390_cmma_log (in, out)
+ :Returns: 0 on success, a negative value on error
++Errors:
++
++  ======     =============================================================
++  ENOMEM     not enough memory can be allocated to complete the task
++  ENXIO      if CMMA is not enabled
++  EINVAL     if KVM_S390_CMMA_PEEK is not set but migration mode was not enabled
++  EINVAL     if KVM_S390_CMMA_PEEK is not set but dirty tracking has been
++             disabled (and thus migration mode was automatically disabled)
++  EFAULT     if the userspace address is invalid or if no page table is
++             present for the addresses (e.g. when using hugepages).
++  ======     =============================================================
++
+ This ioctl is used to get the values of the CMMA bits on the s390
+ architecture. It is meant to be used in two scenarios:
+@@ -4563,12 +4575,6 @@ mask is unused.
+ values points to the userspace buffer where the result will be stored.
+-This ioctl can fail with -ENOMEM if not enough memory can be allocated to
+-complete the task, with -ENXIO if CMMA is not enabled, with -EINVAL if
+-KVM_S390_CMMA_PEEK is not set but migration mode was not enabled, with
+--EFAULT if the userspace address is invalid or if no page table is
+-present for the addresses (e.g. when using hugepages).
+-
+ 4.108 KVM_S390_SET_CMMA_BITS
+ ----------------------------
+--- a/Documentation/virt/kvm/devices/vm.rst
++++ b/Documentation/virt/kvm/devices/vm.rst
+@@ -302,6 +302,10 @@ Allows userspace to start migration mode
+ Setting this attribute when migration mode is already active will have
+ no effects.
++Dirty tracking must be enabled on all memslots, else -EINVAL is returned. When
++dirty tracking is disabled on any memslot, migration mode is automatically
++stopped.
++
+ :Parameters: none
+ :Returns:   -ENOMEM if there is not enough free memory to start migration mode;
+           -EINVAL if the state of the VM is invalid (e.g. no memory defined);
+--- a/arch/s390/kvm/kvm-s390.c
++++ b/arch/s390/kvm/kvm-s390.c
+@@ -5579,23 +5579,40 @@ int kvm_arch_prepare_memory_region(struc
+       if (kvm_s390_pv_get_handle(kvm))
+               return -EINVAL;
+-      if (change == KVM_MR_DELETE || change == KVM_MR_FLAGS_ONLY)
+-              return 0;
+-
+-      /* A few sanity checks. We can have memory slots which have to be
+-         located/ended at a segment boundary (1MB). The memory in userland is
+-         ok to be fragmented into various different vmas. It is okay to mmap()
+-         and munmap() stuff in this slot after doing this call at any time */
+-
+-      if (new->userspace_addr & 0xffffful)
+-              return -EINVAL;
++      if (change != KVM_MR_DELETE && change != KVM_MR_FLAGS_ONLY) {
++              /*
++               * A few sanity checks. We can have memory slots which have to be
++               * located/ended at a segment boundary (1MB). The memory in userland is
++               * ok to be fragmented into various different vmas. It is okay to mmap()
++               * and munmap() stuff in this slot after doing this call at any time
++               */
++
++              if (new->userspace_addr & 0xffffful)
++                      return -EINVAL;
++
++              size = new->npages * PAGE_SIZE;
++              if (size & 0xffffful)
++                      return -EINVAL;
++
++              if ((new->base_gfn * PAGE_SIZE) + size > kvm->arch.mem_limit)
++                      return -EINVAL;
++      }
+-      size = new->npages * PAGE_SIZE;
+-      if (size & 0xffffful)
+-              return -EINVAL;
++      if (!kvm->arch.migration_mode)
++              return 0;
+-      if ((new->base_gfn * PAGE_SIZE) + size > kvm->arch.mem_limit)
+-              return -EINVAL;
++      /*
++       * Turn off migration mode when:
++       * - userspace creates a new memslot with dirty logging off,
++       * - userspace modifies an existing memslot (MOVE or FLAGS_ONLY) and
++       *   dirty logging is turned off.
++       * Migration mode expects dirty page logging being enabled to store
++       * its dirty bitmap.
++       */
++      if (change != KVM_MR_DELETE &&
++          !(new->flags & KVM_MEM_LOG_DIRTY_PAGES))
++              WARN(kvm_s390_vm_stop_migration(kvm),
++                   "Failed to stop migration mode");
+       return 0;
+ }
diff --git a/queue-6.1/s390-discard-.interp-section.patch b/queue-6.1/s390-discard-.interp-section.patch
new file mode 100644 (file)
index 0000000..fbd13d4
--- /dev/null
@@ -0,0 +1,48 @@
+From e9c9cb90e76ffaabcc7ca8f275d9e82195fd6367 Mon Sep 17 00:00:00 2001
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+Date: Mon, 23 Jan 2023 22:50:32 +0100
+Subject: s390: discard .interp section
+
+From: Ilya Leoshkevich <iii@linux.ibm.com>
+
+commit e9c9cb90e76ffaabcc7ca8f275d9e82195fd6367 upstream.
+
+When debugging vmlinux with QEMU + GDB, the following GDB error may
+occur:
+
+    (gdb) c
+    Continuing.
+    Warning:
+    Cannot insert breakpoint -1.
+    Cannot access memory at address 0xffffffffffff95c0
+
+    Command aborted.
+    (gdb)
+
+The reason is that, when .interp section is present, GDB tries to
+locate the file specified in it in memory and put a number of
+breakpoints there (see enable_break() function in gdb/solib-svr4.c).
+Sometimes GDB finds a bogus location that matches its heuristics,
+fails to set a breakpoint and stops. This makes further debugging
+impossible.
+
+The .interp section contains misleading information anyway (vmlinux
+does not need ld.so), so fix by discarding it.
+
+Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/vmlinux.lds.S |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/s390/kernel/vmlinux.lds.S
++++ b/arch/s390/kernel/vmlinux.lds.S
+@@ -228,5 +228,6 @@ SECTIONS
+       DISCARDS
+       /DISCARD/ : {
+               *(.eh_frame)
++              *(.interp)
+       }
+ }
diff --git a/queue-6.1/s390-extmem-return-correct-segment-type-in-__segment_load.patch b/queue-6.1/s390-extmem-return-correct-segment-type-in-__segment_load.patch
new file mode 100644 (file)
index 0000000..ac526d0
--- /dev/null
@@ -0,0 +1,76 @@
+From 8c42dd78df148c90e48efff204cce38743906a79 Mon Sep 17 00:00:00 2001
+From: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Date: Mon, 27 Feb 2023 20:03:00 +0100
+Subject: s390/extmem: return correct segment type in __segment_load()
+
+From: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+
+commit 8c42dd78df148c90e48efff204cce38743906a79 upstream.
+
+Commit f05f62d04271f ("s390/vmem: get rid of memory segment list")
+reshuffled the call to vmem_add_mapping() in __segment_load(), which now
+overwrites rc after it was set to contain the segment type code.
+
+As result, __segment_load() will now always return 0 on success, which
+corresponds to the segment type code SEG_TYPE_SW, i.e. a writeable
+segment. This results in a kernel crash when loading a read-only segment
+as dcssblk block device, and trying to write to it.
+
+Instead of reshuffling code again, make sure to return the segment type
+on success, and also describe this rather delicate and unexpected logic
+in the function comment. Also initialize new segtype variable with
+invalid value, to prevent possible future confusion.
+
+Fixes: f05f62d04271 ("s390/vmem: get rid of memory segment list")
+Cc: <stable@vger.kernel.org> # 5.9+
+Signed-off-by: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/mm/extmem.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/arch/s390/mm/extmem.c
++++ b/arch/s390/mm/extmem.c
+@@ -289,15 +289,17 @@ segment_overlaps_others (struct dcss_seg
+ /*
+  * real segment loading function, called from segment_load
++ * Must return either an error code < 0, or the segment type code >= 0
+  */
+ static int
+ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long *end)
+ {
+       unsigned long start_addr, end_addr, dummy;
+       struct dcss_segment *seg;
+-      int rc, diag_cc;
++      int rc, diag_cc, segtype;
+       start_addr = end_addr = 0;
++      segtype = -1;
+       seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA);
+       if (seg == NULL) {
+               rc = -ENOMEM;
+@@ -326,9 +328,9 @@ __segment_load (char *name, int do_nonsh
+       seg->res_name[8] = '\0';
+       strlcat(seg->res_name, " (DCSS)", sizeof(seg->res_name));
+       seg->res->name = seg->res_name;
+-      rc = seg->vm_segtype;
+-      if (rc == SEG_TYPE_SC ||
+-          ((rc == SEG_TYPE_SR || rc == SEG_TYPE_ER) && !do_nonshared))
++      segtype = seg->vm_segtype;
++      if (segtype == SEG_TYPE_SC ||
++          ((segtype == SEG_TYPE_SR || segtype == SEG_TYPE_ER) && !do_nonshared))
+               seg->res->flags |= IORESOURCE_READONLY;
+       /* Check for overlapping resources before adding the mapping. */
+@@ -386,7 +388,7 @@ __segment_load (char *name, int do_nonsh
+  out_free:
+       kfree(seg);
+  out:
+-      return rc;
++      return rc < 0 ? rc : segtype;
+ }
+ /*
diff --git a/queue-6.1/s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch b/queue-6.1/s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch
new file mode 100644 (file)
index 0000000..5dd0f07
--- /dev/null
@@ -0,0 +1,54 @@
+From cd57953936f2213dfaccce10d20f396956222c7d Mon Sep 17 00:00:00 2001
+From: Vasily Gorbik <gor@linux.ibm.com>
+Date: Wed, 1 Mar 2023 17:58:06 +0100
+Subject: s390/kprobes: fix current_kprobe never cleared after kprobes reenter
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+commit cd57953936f2213dfaccce10d20f396956222c7d upstream.
+
+Recent test_kprobe_missed kprobes kunit test uncovers the following
+problem. Once kprobe is triggered from another kprobe (kprobe reenter),
+all future kprobes on this cpu are considered as kprobe reenter, thus
+pre_handler and post_handler are not being called and kprobes are counted
+as "missed".
+
+Commit b9599798f953 ("[S390] kprobes: activation and deactivation")
+introduced a simpler scheme for kprobes (de)activation and status
+tracking by using push_kprobe/pop_kprobe, which supposed to work for
+both initial kprobe entry as well as kprobe reentry and helps to avoid
+handling those two cases differently. The problem is that a sequence of
+calls in case of kprobes reenter:
+push_kprobe() <- NULL (current_kprobe)
+push_kprobe() <- kprobe1 (current_kprobe)
+pop_kprobe() -> kprobe1 (current_kprobe)
+pop_kprobe() -> kprobe1 (current_kprobe)
+leaves "kprobe1" as "current_kprobe" on this cpu, instead of setting it
+to NULL. In fact push_kprobe/pop_kprobe can only store a single state
+(there is just one prev_kprobe in kprobe_ctlblk). Which is a hack but
+sufficient, there is no need to have another prev_kprobe just to store
+NULL. To make a simple and backportable fix simply reset "prev_kprobe"
+when kprobe is poped from this "stack". No need to worry about
+"kprobe_status" in this case, because its value is only checked when
+current_kprobe != NULL.
+
+Cc: stable@vger.kernel.org
+Fixes: b9599798f953 ("[S390] kprobes: activation and deactivation")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/kprobes.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/s390/kernel/kprobes.c
++++ b/arch/s390/kernel/kprobes.c
+@@ -279,6 +279,7 @@ static void pop_kprobe(struct kprobe_ctl
+ {
+       __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
+       kcb->kprobe_status = kcb->prev_kprobe.status;
++      kcb->prev_kprobe.kp = NULL;
+ }
+ NOKPROBE_SYMBOL(pop_kprobe);
diff --git a/queue-6.1/s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch b/queue-6.1/s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch
new file mode 100644 (file)
index 0000000..e48104d
--- /dev/null
@@ -0,0 +1,80 @@
+From 42e19e6f04984088b6f9f0507c4c89a8152d9730 Mon Sep 17 00:00:00 2001
+From: Vasily Gorbik <gor@linux.ibm.com>
+Date: Wed, 1 Mar 2023 02:23:08 +0100
+Subject: s390/kprobes: fix irq mask clobbering on kprobe reenter from post_handler
+
+From: Vasily Gorbik <gor@linux.ibm.com>
+
+commit 42e19e6f04984088b6f9f0507c4c89a8152d9730 upstream.
+
+Recent test_kprobe_missed kprobes kunit test uncovers the following error
+(reported when CONFIG_DEBUG_ATOMIC_SLEEP is enabled):
+
+BUG: sleeping function called from invalid context at kernel/locking/mutex.c:580
+in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 662, name: kunit_try_catch
+preempt_count: 0, expected: 0
+RCU nest depth: 0, expected: 0
+no locks held by kunit_try_catch/662.
+irq event stamp: 280
+hardirqs last  enabled at (279): [<00000003e60a3d42>] __do_pgm_check+0x17a/0x1c0
+hardirqs last disabled at (280): [<00000003e3bd774a>] kprobe_exceptions_notify+0x27a/0x318
+softirqs last  enabled at (0): [<00000003e3c5c890>] copy_process+0x14a8/0x4c80
+softirqs last disabled at (0): [<0000000000000000>] 0x0
+CPU: 46 PID: 662 Comm: kunit_try_catch Tainted: G                 N 6.2.0-173644-g44c18d77f0c0 #2
+Hardware name: IBM 3931 A01 704 (LPAR)
+Call Trace:
+ [<00000003e60a3a00>] dump_stack_lvl+0x120/0x198
+ [<00000003e3d02e82>] __might_resched+0x60a/0x668
+ [<00000003e60b9908>] __mutex_lock+0xc0/0x14e0
+ [<00000003e60bad5a>] mutex_lock_nested+0x32/0x40
+ [<00000003e3f7b460>] unregister_kprobe+0x30/0xd8
+ [<00000003e51b2602>] test_kprobe_missed+0xf2/0x268
+ [<00000003e51b5406>] kunit_try_run_case+0x10e/0x290
+ [<00000003e51b7dfa>] kunit_generic_run_threadfn_adapter+0x62/0xb8
+ [<00000003e3ce30f8>] kthread+0x2d0/0x398
+ [<00000003e3b96afa>] __ret_from_fork+0x8a/0xe8
+ [<00000003e60ccada>] ret_from_fork+0xa/0x40
+
+The reason for this error report is that kprobes handling code failed
+to restore irqs.
+
+The problem is that when kprobe is triggered from another kprobe
+post_handler current sequence of enable_singlestep / disable_singlestep
+is the following:
+enable_singlestep  <- original kprobe (saves kprobe_saved_imask)
+enable_singlestep  <- kprobe triggered from post_handler (clobbers kprobe_saved_imask)
+disable_singlestep <- kprobe triggered from post_handler (restores kprobe_saved_imask)
+disable_singlestep <- original kprobe (restores wrong clobbered kprobe_saved_imask)
+
+There is just one kprobe_ctlblk per cpu and both calls saves and
+loads irq mask to kprobe_saved_imask. To fix the problem simply move
+resume_execution (which calls disable_singlestep) before calling
+post_handler. This also fixes the problem that post_handler is called
+with pt_regs which were not yet adjusted after single-stepping.
+
+Cc: stable@vger.kernel.org
+Fixes: 4ba069b802c2 ("[S390] add kprobes support.")
+Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/s390/kernel/kprobes.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/arch/s390/kernel/kprobes.c
++++ b/arch/s390/kernel/kprobes.c
+@@ -433,12 +433,11 @@ static int post_kprobe_handler(struct pt
+       if (!p)
+               return 0;
++      resume_execution(p, regs);
+       if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) {
+               kcb->kprobe_status = KPROBE_HIT_SSDONE;
+               p->post_handler(p, regs, 0);
+       }
+-
+-      resume_execution(p, regs);
+       pop_kprobe(kcb);
+       preempt_enable_no_resched();
diff --git a/queue-6.1/scsi-mpi3mr-fix-issues-in-mpi3mr_get_all_tgt_info.patch b/queue-6.1/scsi-mpi3mr-fix-issues-in-mpi3mr_get_all_tgt_info.patch
new file mode 100644 (file)
index 0000000..bc12270
--- /dev/null
@@ -0,0 +1,95 @@
+From fb428a2005fc1260d18b989cc5199f281617f44d Mon Sep 17 00:00:00 2001
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Date: Tue, 14 Feb 2023 09:50:16 +0900
+Subject: scsi: mpi3mr: Fix issues in mpi3mr_get_all_tgt_info()
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+commit fb428a2005fc1260d18b989cc5199f281617f44d upstream.
+
+The function mpi3mr_get_all_tgt_info() has four issues:
+
+1) It calculates valid entry length in alltgt_info assuming the header part
+   of the struct mpi3mr_device_map_info would equal to sizeof(u32).  The
+   correct size is sizeof(u64).
+
+2) When it calculates the valid entry length kern_entrylen, it excludes one
+   entry by subtracting 1 from num_devices.
+
+3) It copies num_device by calling memcpy(). Substitution is enough.
+
+4) It does not specify the calculated length to sg_copy_from_buffer().
+   Instead, it specifies the payload length which is larger than the
+   alltgt_info size. It causes "BUG: KASAN: slab-out-of-bounds".
+
+Fix the issues by using the correct header size, removing the subtraction
+from num_devices, replacing the memcpy() with substitution and specifying
+the correct length to sg_copy_from_buffer().
+
+Link: https://lore.kernel.org/r/20230214005019.1897251-2-shinichiro.kawasaki@wdc.com
+Cc: stable@vger.kernel.org
+Fixes: f5e6d5a34376 ("scsi: mpi3mr: Add support for driver commands")
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Acked-by: Sathya Prakash Veerichetty <sathya.prakash@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_app.c | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
+index 9baac224b213..72054e3a26cb 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
+@@ -312,7 +312,7 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
+               num_devices++;
+       spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
+-      if ((job->request_payload.payload_len == sizeof(u32)) ||
++      if ((job->request_payload.payload_len <= sizeof(u64)) ||
+               list_empty(&mrioc->tgtdev_list)) {
+               sg_copy_from_buffer(job->request_payload.sg_list,
+                                   job->request_payload.sg_cnt,
+@@ -320,14 +320,14 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
+               return 0;
+       }
+-      kern_entrylen = (num_devices - 1) * sizeof(*devmap_info);
+-      size = sizeof(*alltgt_info) + kern_entrylen;
++      kern_entrylen = num_devices * sizeof(*devmap_info);
++      size = sizeof(u64) + kern_entrylen;
+       alltgt_info = kzalloc(size, GFP_KERNEL);
+       if (!alltgt_info)
+               return -ENOMEM;
+       devmap_info = alltgt_info->dmi;
+-      memset((u8 *)devmap_info, 0xFF, (kern_entrylen + sizeof(*devmap_info)));
++      memset((u8 *)devmap_info, 0xFF, kern_entrylen);
+       spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
+       list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) {
+               if (i < num_devices) {
+@@ -344,9 +344,10 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
+       num_devices = i;
+       spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
+-      memcpy(&alltgt_info->num_devices, &num_devices, sizeof(num_devices));
++      alltgt_info->num_devices = num_devices;
+-      usr_entrylen = (job->request_payload.payload_len - sizeof(u32)) / sizeof(*devmap_info);
++      usr_entrylen = (job->request_payload.payload_len - sizeof(u64)) /
++              sizeof(*devmap_info);
+       usr_entrylen *= sizeof(*devmap_info);
+       min_entrylen = min(usr_entrylen, kern_entrylen);
+       if (min_entrylen && (!memcpy(&alltgt_info->dmi, devmap_info, min_entrylen))) {
+@@ -358,7 +359,7 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
+       sg_copy_from_buffer(job->request_payload.sg_list,
+                           job->request_payload.sg_cnt,
+-                          alltgt_info, job->request_payload.payload_len);
++                          alltgt_info, (min_entrylen + sizeof(u64)));
+       rval = 0;
+ out:
+       kfree(alltgt_info);
+-- 
+2.39.2
+
diff --git a/queue-6.1/scsi-mpi3mr-fix-missing-mrioc-evtack_cmds-initialization.patch b/queue-6.1/scsi-mpi3mr-fix-missing-mrioc-evtack_cmds-initialization.patch
new file mode 100644 (file)
index 0000000..6c900ed
--- /dev/null
@@ -0,0 +1,44 @@
+From e39ea831ebad4ab15c4748cb62a397a8abcca36e Mon Sep 17 00:00:00 2001
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Date: Tue, 14 Feb 2023 09:50:19 +0900
+Subject: scsi: mpi3mr: Fix missing mrioc->evtack_cmds initialization
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+commit e39ea831ebad4ab15c4748cb62a397a8abcca36e upstream.
+
+Commit c1af985d27da ("scsi: mpi3mr: Add Event acknowledgment logic")
+introduced an array mrioc->evtack_cmds but initialization of the array
+elements was missed. They are just zero cleared. The function
+mpi3mr_complete_evt_ack() refers host_tag field of the elements. Due to the
+zero value of the host_tag field, the function calls clear_bit() for
+mrico->evtack_cmds_bitmap with wrong bit index. This results in memory
+access to invalid address and "BUG: KASAN: use-after-free". This BUG was
+observed at eHBA-9600 firmware update to version 8.3.1.0. To fix it, add
+the missing initialization of mrioc->evtack_cmds.
+
+Link: https://lore.kernel.org/r/20230214005019.1897251-5-shinichiro.kawasaki@wdc.com
+Cc: stable@vger.kernel.org
+Fixes: c1af985d27da ("scsi: mpi3mr: Add Event acknowledgment logic")
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Acked-by: Sathya Prakash Veerichetty <sathya.prakash@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_os.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/scsi/mpi3mr/mpi3mr_os.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
+@@ -4952,6 +4952,10 @@ mpi3mr_probe(struct pci_dev *pdev, const
+               mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i],
+                   MPI3MR_HOSTTAG_DEVRMCMD_MIN + i);
++      for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
++              mpi3mr_init_drv_cmd(&mrioc->evtack_cmds[i],
++                                  MPI3MR_HOSTTAG_EVTACKCMD_MIN + i);
++
+       if (pdev->revision)
+               mrioc->enable_segqueue = true;
diff --git a/queue-6.1/scsi-mpi3mr-remove-unnecessary-memcpy-to-alltgt_info-dmi.patch b/queue-6.1/scsi-mpi3mr-remove-unnecessary-memcpy-to-alltgt_info-dmi.patch
new file mode 100644 (file)
index 0000000..a6b23ee
--- /dev/null
@@ -0,0 +1,71 @@
+From eeb270aee3e085411399f129fc14fa04bd6d83cf Mon Sep 17 00:00:00 2001
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Date: Tue, 14 Feb 2023 09:50:17 +0900
+Subject: scsi: mpi3mr: Remove unnecessary memcpy() to alltgt_info->dmi
+
+From: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+
+commit eeb270aee3e085411399f129fc14fa04bd6d83cf upstream.
+
+In the function mpi3mr_get_all_tgt_info(), devmap_info points to
+alltgt_info->dmi then there is no need to memcpy() data from devmap_info to
+alltgt_info->dmi. Remove the unnecessary memcpy(). This also allows to
+remove the local variable 'rval' and the goto label 'out'.
+
+Link: https://lore.kernel.org/r/20230214005019.1897251-3-shinichiro.kawasaki@wdc.com
+Cc: stable@vger.kernel.org
+Fixes: f5e6d5a34376 ("scsi: mpi3mr: Add support for driver commands")
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Acked-by: Sathya Prakash Veerichetty <sathya.prakash@broadcom.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/mpi3mr/mpi3mr_app.c | 13 ++-----------
+ 1 file changed, 2 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
+index 72054e3a26cb..bff637702397 100644
+--- a/drivers/scsi/mpi3mr/mpi3mr_app.c
++++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
+@@ -293,7 +293,6 @@ static long mpi3mr_bsg_pel_enable(struct mpi3mr_ioc *mrioc,
+ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
+       struct bsg_job *job)
+ {
+-      long rval = -EINVAL;
+       u16 num_devices = 0, i = 0, size;
+       unsigned long flags;
+       struct mpi3mr_tgt_dev *tgtdev;
+@@ -304,7 +303,7 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
+       if (job->request_payload.payload_len < sizeof(u32)) {
+               dprint_bsg_err(mrioc, "%s: invalid size argument\n",
+                   __func__);
+-              return rval;
++              return -EINVAL;
+       }
+       spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
+@@ -350,20 +349,12 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
+               sizeof(*devmap_info);
+       usr_entrylen *= sizeof(*devmap_info);
+       min_entrylen = min(usr_entrylen, kern_entrylen);
+-      if (min_entrylen && (!memcpy(&alltgt_info->dmi, devmap_info, min_entrylen))) {
+-              dprint_bsg_err(mrioc, "%s:%d: device map info copy failed\n",
+-                  __func__, __LINE__);
+-              rval = -EFAULT;
+-              goto out;
+-      }
+       sg_copy_from_buffer(job->request_payload.sg_list,
+                           job->request_payload.sg_cnt,
+                           alltgt_info, (min_entrylen + sizeof(u64)));
+-      rval = 0;
+-out:
+       kfree(alltgt_info);
+-      return rval;
++      return 0;
+ }
+ /**
+  * mpi3mr_get_change_count - Get topology change count
+-- 
+2.39.2
+
index 3ff52428dbf18bb651c84069b5109e53d175929f..539e1e010f1b1fd69b591180789efbe5abdb4514 100644 (file)
@@ -666,3 +666,19 @@ io_uring-add-reschedule-point-to-handle_tw_list.patch
 io_uring-rsrc-disallow-multi-source-reg-buffers.patch
 io_uring-remove-msg_nosignal-from-recvmsg.patch
 io_uring-fix-fget-leak-when-fs-don-t-support-nowait-buffered-read.patch
+s390-extmem-return-correct-segment-type-in-__segment_load.patch
+s390-discard-.interp-section.patch
+s390-kprobes-fix-irq-mask-clobbering-on-kprobe-reenter-from-post_handler.patch
+s390-kprobes-fix-current_kprobe-never-cleared-after-kprobes-reenter.patch
+kvm-s390-disable-migration-mode-when-dirty-tracking-is-disabled.patch
+cifs-fix-uninitialized-memory-read-in-smb3_qfs_tcon.patch
+cifs-fix-uninitialized-memory-reads-for-oparms.mode.patch
+cifs-fix-mount-on-old-smb-servers.patch
+cifs-introduce-cifs_io_parms-in-smb2_async_writev.patch
+cifs-split-out-smb3_use_rdma_offload-helper.patch
+cifs-don-t-try-to-use-rdma-offload-on-encrypted-connections.patch
+cifs-check-the-lease-context-if-we-actually-got-a-lease.patch
+cifs-return-a-single-use-cfid-if-we-did-not-get-a-lease.patch
+scsi-mpi3mr-fix-missing-mrioc-evtack_cmds-initialization.patch
+scsi-mpi3mr-fix-issues-in-mpi3mr_get_all_tgt_info.patch
+scsi-mpi3mr-remove-unnecessary-memcpy-to-alltgt_info-dmi.patch