--- /dev/null
+From a6862e6708c15995bc10614b2ef34ca35b4b9078 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Tue, 1 Jun 2021 08:13:38 -0400
+Subject: ceph: add some lockdep assertions around snaprealm handling
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit a6862e6708c15995bc10614b2ef34ca35b4b9078 upstream.
+
+Turn some comments into lockdep asserts.
+
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/snap.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/fs/ceph/snap.c
++++ b/fs/ceph/snap.c
+@@ -65,6 +65,8 @@
+ void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+ {
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ dout("get_realm %p %d -> %d\n", realm,
+ atomic_read(&realm->nref), atomic_read(&realm->nref)+1);
+ /*
+@@ -113,6 +115,8 @@ static struct ceph_snap_realm *ceph_crea
+ {
+ struct ceph_snap_realm *realm;
+
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ realm = kzalloc(sizeof(*realm), GFP_NOFS);
+ if (!realm)
+ return ERR_PTR(-ENOMEM);
+@@ -143,6 +147,8 @@ static struct ceph_snap_realm *__lookup_
+ struct rb_node *n = mdsc->snap_realms.rb_node;
+ struct ceph_snap_realm *r;
+
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ while (n) {
+ r = rb_entry(n, struct ceph_snap_realm, node);
+ if (ino < r->ino)
+@@ -176,6 +182,8 @@ static void __put_snap_realm(struct ceph
+ static void __destroy_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+ {
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ dout("__destroy_snap_realm %p %llx\n", realm, realm->ino);
+
+ rb_erase(&realm->node, &mdsc->snap_realms);
+@@ -198,6 +206,8 @@ static void __destroy_snap_realm(struct
+ static void __put_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+ {
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+ atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+ if (atomic_dec_and_test(&realm->nref))
+@@ -236,6 +246,8 @@ static void __cleanup_empty_realms(struc
+ {
+ struct ceph_snap_realm *realm;
+
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ spin_lock(&mdsc->snap_empty_lock);
+ while (!list_empty(&mdsc->snap_empty)) {
+ realm = list_first_entry(&mdsc->snap_empty,
+@@ -269,6 +281,8 @@ static int adjust_snap_realm_parent(stru
+ {
+ struct ceph_snap_realm *parent;
+
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ if (realm->parent_ino == parentino)
+ return 0;
+
+@@ -686,6 +700,8 @@ int ceph_update_snap_trace(struct ceph_m
+ int err = -ENOMEM;
+ LIST_HEAD(dirty_realms);
+
++ lockdep_assert_held_write(&mdsc->snap_rwsem);
++
+ dout("update_snap_trace deletion=%d\n", deletion);
+ more:
+ ceph_decode_need(&p, e, sizeof(*ri), bad);
--- /dev/null
+From df2c0cb7f8e8c83e495260ad86df8c5da947f2a7 Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Tue, 1 Jun 2021 09:24:38 -0400
+Subject: ceph: clean up locking annotation for ceph_get_snap_realm and __lookup_snap_realm
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit df2c0cb7f8e8c83e495260ad86df8c5da947f2a7 upstream.
+
+They both say that the snap_rwsem must be held for write, but I don't
+see any real reason for it, and it's not currently always called that
+way.
+
+The lookup is just walking the rbtree, so holding it for read should be
+fine there. The "get" is bumping the refcount and (possibly) removing
+it from the empty list. I see no need to hold the snap_rwsem for write
+for that.
+
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/snap.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/fs/ceph/snap.c
++++ b/fs/ceph/snap.c
+@@ -60,12 +60,12 @@
+ /*
+ * increase ref count for the realm
+ *
+- * caller must hold snap_rwsem for write.
++ * caller must hold snap_rwsem.
+ */
+ void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+ {
+- lockdep_assert_held_write(&mdsc->snap_rwsem);
++ lockdep_assert_held(&mdsc->snap_rwsem);
+
+ dout("get_realm %p %d -> %d\n", realm,
+ atomic_read(&realm->nref), atomic_read(&realm->nref)+1);
+@@ -139,7 +139,7 @@ static struct ceph_snap_realm *ceph_crea
+ /*
+ * lookup the realm rooted at @ino.
+ *
+- * caller must hold snap_rwsem for write.
++ * caller must hold snap_rwsem.
+ */
+ static struct ceph_snap_realm *__lookup_snap_realm(struct ceph_mds_client *mdsc,
+ u64 ino)
+@@ -147,7 +147,7 @@ static struct ceph_snap_realm *__lookup_
+ struct rb_node *n = mdsc->snap_realms.rb_node;
+ struct ceph_snap_realm *r;
+
+- lockdep_assert_held_write(&mdsc->snap_rwsem);
++ lockdep_assert_held(&mdsc->snap_rwsem);
+
+ while (n) {
+ r = rb_entry(n, struct ceph_snap_realm, node);
--- /dev/null
+From 8434ffe71c874b9c4e184b88d25de98c2bf5fe3f Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@kernel.org>
+Date: Tue, 3 Aug 2021 12:47:34 -0400
+Subject: ceph: take snap_empty_lock atomically with snaprealm refcount change
+
+From: Jeff Layton <jlayton@kernel.org>
+
+commit 8434ffe71c874b9c4e184b88d25de98c2bf5fe3f upstream.
+
+There is a race in ceph_put_snap_realm. The change to the nref and the
+spinlock acquisition are not done atomically, so you could decrement
+nref, and before you take the spinlock, the nref is incremented again.
+At that point, you end up putting it on the empty list when it
+shouldn't be there. Eventually __cleanup_empty_realms runs and frees
+it when it's still in-use.
+
+Fix this by protecting the 1->0 transition with atomic_dec_and_lock,
+and just drop the spinlock if we can get the rwsem.
+
+Because these objects can also undergo a 0->1 refcount transition, we
+must protect that change as well with the spinlock. Increment locklessly
+unless the value is at 0, in which case we take the spinlock, increment
+and then take it off the empty list if it did the 0->1 transition.
+
+With these changes, I'm removing the dout() messages from these
+functions, as well as in __put_snap_realm. They've always been racy, and
+it's better to not print values that may be misleading.
+
+Cc: stable@vger.kernel.org
+URL: https://tracker.ceph.com/issues/46419
+Reported-by: Mark Nelson <mnelson@redhat.com>
+Signed-off-by: Jeff Layton <jlayton@kernel.org>
+Reviewed-by: Luis Henriques <lhenriques@suse.de>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/snap.c | 34 +++++++++++++++++-----------------
+ 1 file changed, 17 insertions(+), 17 deletions(-)
+
+--- a/fs/ceph/snap.c
++++ b/fs/ceph/snap.c
+@@ -67,19 +67,19 @@ void ceph_get_snap_realm(struct ceph_mds
+ {
+ lockdep_assert_held(&mdsc->snap_rwsem);
+
+- dout("get_realm %p %d -> %d\n", realm,
+- atomic_read(&realm->nref), atomic_read(&realm->nref)+1);
+ /*
+- * since we _only_ increment realm refs or empty the empty
+- * list with snap_rwsem held, adjusting the empty list here is
+- * safe. we do need to protect against concurrent empty list
+- * additions, however.
++ * The 0->1 and 1->0 transitions must take the snap_empty_lock
++ * atomically with the refcount change. Go ahead and bump the
++ * nref here, unless it's 0, in which case we take the spinlock
++ * and then do the increment and remove it from the list.
+ */
+- if (atomic_inc_return(&realm->nref) == 1) {
+- spin_lock(&mdsc->snap_empty_lock);
++ if (atomic_inc_not_zero(&realm->nref))
++ return;
++
++ spin_lock(&mdsc->snap_empty_lock);
++ if (atomic_inc_return(&realm->nref) == 1)
+ list_del_init(&realm->empty_item);
+- spin_unlock(&mdsc->snap_empty_lock);
+- }
++ spin_unlock(&mdsc->snap_empty_lock);
+ }
+
+ static void __insert_snap_realm(struct rb_root *root,
+@@ -208,28 +208,28 @@ static void __put_snap_realm(struct ceph
+ {
+ lockdep_assert_held_write(&mdsc->snap_rwsem);
+
+- dout("__put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+- atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
++ /*
++ * We do not require the snap_empty_lock here, as any caller that
++ * increments the value must hold the snap_rwsem.
++ */
+ if (atomic_dec_and_test(&realm->nref))
+ __destroy_snap_realm(mdsc, realm);
+ }
+
+ /*
+- * caller needn't hold any locks
++ * See comments in ceph_get_snap_realm. Caller needn't hold any locks.
+ */
+ void ceph_put_snap_realm(struct ceph_mds_client *mdsc,
+ struct ceph_snap_realm *realm)
+ {
+- dout("put_snap_realm %llx %p %d -> %d\n", realm->ino, realm,
+- atomic_read(&realm->nref), atomic_read(&realm->nref)-1);
+- if (!atomic_dec_and_test(&realm->nref))
++ if (!atomic_dec_and_lock(&realm->nref, &mdsc->snap_empty_lock))
+ return;
+
+ if (down_write_trylock(&mdsc->snap_rwsem)) {
++ spin_unlock(&mdsc->snap_empty_lock);
+ __destroy_snap_realm(mdsc, realm);
+ up_write(&mdsc->snap_rwsem);
+ } else {
+- spin_lock(&mdsc->snap_empty_lock);
+ list_add(&realm->empty_item, &mdsc->snap_empty);
+ spin_unlock(&mdsc->snap_empty_lock);
+ }
efi-libstub-arm64-double-check-image-alignment-at-entry.patch
kvm-vmx-use-current-vmcs-to-query-waitpkg-support-for-msr-emulation.patch
kvm-nvmx-use-vmx_need_pf_intercept-when-deciding-if-l0-wants-a-pf.patch
+vboxsf-add-vboxsf__sf_handle-helpers.patch
+vboxsf-add-support-for-the-atomic_open-directory-inode-op.patch
+ceph-add-some-lockdep-assertions-around-snaprealm-handling.patch
+ceph-clean-up-locking-annotation-for-ceph_get_snap_realm-and-__lookup_snap_realm.patch
+ceph-take-snap_empty_lock-atomically-with-snaprealm-refcount-change.patch
+vmlinux.lds.h-handle-clang-s-module.-c-d-tor-sections.patch
--- /dev/null
+From 52dfd86aa568e433b24357bb5fc725560f1e22d8 Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 21 Jan 2021 12:54:18 +0100
+Subject: vboxsf: Add support for the atomic_open directory-inode op
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 52dfd86aa568e433b24357bb5fc725560f1e22d8 upstream.
+
+Opening a new file is done in 2 steps on regular filesystems:
+
+1. Call the create inode-op on the parent-dir to create an inode
+to hold the meta-data related to the file.
+2. Call the open file-op to get a handle for the file.
+
+vboxsf however does not really use disk-backed inodes because it
+is based on passing through file-related system-calls through to
+the hypervisor. So both steps translate to an open(2) call being
+passed through to the hypervisor. With the handle returned by
+the first call immediately being closed again.
+
+Making 2 open calls for a single open(..., O_CREATE, ...) calls
+has 2 problems:
+
+a) It is not really efficient.
+b) It actually breaks some apps.
+
+An example of b) is doing a git clone inside a vboxsf mount.
+When git clone tries to create a tempfile to store the pak
+files which is downloading the following happens:
+
+1. vboxsf_dir_mkfile() gets called with a mode of 0444 and succeeds.
+2. vboxsf_file_open() gets called with file->f_flags containing
+O_RDWR. When the host is a Linux machine this fails because doing
+a open(..., O_RDWR) on a file which exists and has mode 0444 results
+in an -EPERM error.
+
+Other network-filesystems and fuse avoid the problem of needing to
+pass 2 open() calls to the other side by using the atomic_open
+directory-inode op.
+
+This commit fixes git clone not working inside a vboxsf mount,
+by adding support for the atomic_open directory-inode op.
+As an added bonus this should also make opening new files faster.
+
+The atomic_open implementation is modelled after the atomic_open
+implementations from the 9p and fuse code.
+
+Fixes: 0fd169576648 ("fs: Add VirtualBox guest shared folder (vboxsf) support")
+Reported-by: Ludovic Pouzenc <bugreports@pouzenc.fr>
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/vboxsf/dir.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 48 insertions(+)
+
+--- a/fs/vboxsf/dir.c
++++ b/fs/vboxsf/dir.c
+@@ -306,6 +306,53 @@ static int vboxsf_dir_mkdir(struct inode
+ return vboxsf_dir_create(parent, dentry, mode, true, true, NULL);
+ }
+
++static int vboxsf_dir_atomic_open(struct inode *parent, struct dentry *dentry,
++ struct file *file, unsigned int flags, umode_t mode)
++{
++ struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
++ struct vboxsf_handle *sf_handle;
++ struct dentry *res = NULL;
++ u64 handle;
++ int err;
++
++ if (d_in_lookup(dentry)) {
++ res = vboxsf_dir_lookup(parent, dentry, 0);
++ if (IS_ERR(res))
++ return PTR_ERR(res);
++
++ if (res)
++ dentry = res;
++ }
++
++ /* Only creates */
++ if (!(flags & O_CREAT) || d_really_is_positive(dentry))
++ return finish_no_open(file, res);
++
++ err = vboxsf_dir_create(parent, dentry, mode, false, flags & O_EXCL, &handle);
++ if (err)
++ goto out;
++
++ sf_handle = vboxsf_create_sf_handle(d_inode(dentry), handle, SHFL_CF_ACCESS_READWRITE);
++ if (IS_ERR(sf_handle)) {
++ vboxsf_close(sbi->root, handle);
++ err = PTR_ERR(sf_handle);
++ goto out;
++ }
++
++ err = finish_open(file, dentry, generic_file_open);
++ if (err) {
++ /* This also closes the handle passed to vboxsf_create_sf_handle() */
++ vboxsf_release_sf_handle(d_inode(dentry), sf_handle);
++ goto out;
++ }
++
++ file->private_data = sf_handle;
++ file->f_mode |= FMODE_CREATED;
++out:
++ dput(res);
++ return err;
++}
++
+ static int vboxsf_dir_unlink(struct inode *parent, struct dentry *dentry)
+ {
+ struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
+@@ -424,6 +471,7 @@ const struct inode_operations vboxsf_dir
+ .lookup = vboxsf_dir_lookup,
+ .create = vboxsf_dir_mkfile,
+ .mkdir = vboxsf_dir_mkdir,
++ .atomic_open = vboxsf_dir_atomic_open,
+ .rmdir = vboxsf_dir_unlink,
+ .unlink = vboxsf_dir_unlink,
+ .rename = vboxsf_dir_rename,
--- /dev/null
+From 02f840f90764f22f5c898901849bdbf0cee752ba Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 21 Jan 2021 10:55:03 +0100
+Subject: vboxsf: Add vboxsf_[create|release]_sf_handle() helpers
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit 02f840f90764f22f5c898901849bdbf0cee752ba upstream.
+
+Factor out the code to create / release a struct vboxsf_handle into
+2 new helper functions.
+
+This is a preparation patch for adding atomic_open support.
+
+Fixes: 0fd169576648 ("fs: Add VirtualBox guest shared folder (vboxsf) support")
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/vboxsf/file.c | 71 ++++++++++++++++++++++++++++++++---------------------
+ fs/vboxsf/vfsmod.h | 7 +++++
+ 2 files changed, 51 insertions(+), 27 deletions(-)
+
+--- a/fs/vboxsf/file.c
++++ b/fs/vboxsf/file.c
+@@ -20,17 +20,39 @@ struct vboxsf_handle {
+ struct list_head head;
+ };
+
+-static int vboxsf_file_open(struct inode *inode, struct file *file)
++struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode,
++ u64 handle, u32 access_flags)
+ {
+ struct vboxsf_inode *sf_i = VBOXSF_I(inode);
+- struct shfl_createparms params = {};
+ struct vboxsf_handle *sf_handle;
+- u32 access_flags = 0;
+- int err;
+
+ sf_handle = kmalloc(sizeof(*sf_handle), GFP_KERNEL);
+ if (!sf_handle)
+- return -ENOMEM;
++ return ERR_PTR(-ENOMEM);
++
++ /* the host may have given us different attr then requested */
++ sf_i->force_restat = 1;
++
++ /* init our handle struct and add it to the inode's handles list */
++ sf_handle->handle = handle;
++ sf_handle->root = VBOXSF_SBI(inode->i_sb)->root;
++ sf_handle->access_flags = access_flags;
++ kref_init(&sf_handle->refcount);
++
++ mutex_lock(&sf_i->handle_list_mutex);
++ list_add(&sf_handle->head, &sf_i->handle_list);
++ mutex_unlock(&sf_i->handle_list_mutex);
++
++ return sf_handle;
++}
++
++static int vboxsf_file_open(struct inode *inode, struct file *file)
++{
++ struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
++ struct shfl_createparms params = {};
++ struct vboxsf_handle *sf_handle;
++ u32 access_flags = 0;
++ int err;
+
+ /*
+ * We check the value of params.handle afterwards to find out if
+@@ -83,23 +105,14 @@ static int vboxsf_file_open(struct inode
+ err = vboxsf_create_at_dentry(file_dentry(file), ¶ms);
+ if (err == 0 && params.handle == SHFL_HANDLE_NIL)
+ err = (params.result == SHFL_FILE_EXISTS) ? -EEXIST : -ENOENT;
+- if (err) {
+- kfree(sf_handle);
++ if (err)
+ return err;
+- }
+
+- /* the host may have given us different attr then requested */
+- sf_i->force_restat = 1;
+-
+- /* init our handle struct and add it to the inode's handles list */
+- sf_handle->handle = params.handle;
+- sf_handle->root = VBOXSF_SBI(inode->i_sb)->root;
+- sf_handle->access_flags = access_flags;
+- kref_init(&sf_handle->refcount);
+-
+- mutex_lock(&sf_i->handle_list_mutex);
+- list_add(&sf_handle->head, &sf_i->handle_list);
+- mutex_unlock(&sf_i->handle_list_mutex);
++ sf_handle = vboxsf_create_sf_handle(inode, params.handle, access_flags);
++ if (IS_ERR(sf_handle)) {
++ vboxsf_close(sbi->root, params.handle);
++ return PTR_ERR(sf_handle);
++ }
+
+ file->private_data = sf_handle;
+ return 0;
+@@ -114,22 +127,26 @@ static void vboxsf_handle_release(struct
+ kfree(sf_handle);
+ }
+
+-static int vboxsf_file_release(struct inode *inode, struct file *file)
++void vboxsf_release_sf_handle(struct inode *inode, struct vboxsf_handle *sf_handle)
+ {
+ struct vboxsf_inode *sf_i = VBOXSF_I(inode);
+- struct vboxsf_handle *sf_handle = file->private_data;
+
++ mutex_lock(&sf_i->handle_list_mutex);
++ list_del(&sf_handle->head);
++ mutex_unlock(&sf_i->handle_list_mutex);
++
++ kref_put(&sf_handle->refcount, vboxsf_handle_release);
++}
++
++static int vboxsf_file_release(struct inode *inode, struct file *file)
++{
+ /*
+ * When a file is closed on our (the guest) side, we want any subsequent
+ * accesses done on the host side to see all changes done from our side.
+ */
+ filemap_write_and_wait(inode->i_mapping);
+
+- mutex_lock(&sf_i->handle_list_mutex);
+- list_del(&sf_handle->head);
+- mutex_unlock(&sf_i->handle_list_mutex);
+-
+- kref_put(&sf_handle->refcount, vboxsf_handle_release);
++ vboxsf_release_sf_handle(inode, file->private_data);
+ return 0;
+ }
+
+--- a/fs/vboxsf/vfsmod.h
++++ b/fs/vboxsf/vfsmod.h
+@@ -18,6 +18,8 @@
+ #define VBOXSF_SBI(sb) ((struct vboxsf_sbi *)(sb)->s_fs_info)
+ #define VBOXSF_I(i) container_of(i, struct vboxsf_inode, vfs_inode)
+
++struct vboxsf_handle;
++
+ struct vboxsf_options {
+ unsigned long ttl;
+ kuid_t uid;
+@@ -80,6 +82,11 @@ extern const struct file_operations vbox
+ extern const struct address_space_operations vboxsf_reg_aops;
+ extern const struct dentry_operations vboxsf_dentry_ops;
+
++/* from file.c */
++struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode,
++ u64 handle, u32 access_flags);
++void vboxsf_release_sf_handle(struct inode *inode, struct vboxsf_handle *sf_handle);
++
+ /* from utils.c */
+ struct inode *vboxsf_new_inode(struct super_block *sb);
+ void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
--- /dev/null
+From foo@baz Mon Aug 16 10:53:15 AM CEST 2021
+From: Nathan Chancellor <nathan@kernel.org>
+Date: Fri, 30 Jul 2021 19:31:08 -0700
+Subject: vmlinux.lds.h: Handle clang's module.{c,d}tor sections
+
+From: Nathan Chancellor <nathan@kernel.org>
+
+commit 848378812e40152abe9b9baf58ce2004f76fb988 upstream.
+
+A recent change in LLVM causes module_{c,d}tor sections to appear when
+CONFIG_K{A,C}SAN are enabled, which results in orphan section warnings
+because these are not handled anywhere:
+
+ld.lld: warning: arch/x86/pci/built-in.a(legacy.o):(.text.asan.module_ctor) is being placed in '.text.asan.module_ctor'
+ld.lld: warning: arch/x86/pci/built-in.a(legacy.o):(.text.asan.module_dtor) is being placed in '.text.asan.module_dtor'
+ld.lld: warning: arch/x86/pci/built-in.a(legacy.o):(.text.tsan.module_ctor) is being placed in '.text.tsan.module_ctor'
+
+Fangrui explains: "the function asan.module_ctor has the SHF_GNU_RETAIN
+flag, so it is in a separate section even with -fno-function-sections
+(default)".
+
+Place them in the TEXT_TEXT section so that these technologies continue
+to work with the newer compiler versions. All of the KASAN and KCSAN
+KUnit tests continue to pass after this change.
+
+Cc: stable@vger.kernel.org
+Link: https://github.com/ClangBuiltLinux/linux/issues/1432
+Link: https://github.com/llvm/llvm-project/commit/7b789562244ee941b7bf2cefeb3fc08a59a01865
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
+Reviewed-by: Fangrui Song <maskray@google.com>
+Acked-by: Marco Elver <elver@google.com>
+Signed-off-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20210731023107.1932981-1-nathan@kernel.org
+[nc: Resolve conflict due to lack of cf68fffb66d60]
+Signed-off-by: Nathan Chancellor <nathan@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/asm-generic/vmlinux.lds.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -599,6 +599,7 @@
+ NOINSTR_TEXT \
+ *(.text..refcount) \
+ *(.ref.text) \
++ *(.text.asan.* .text.tsan.*) \
+ MEM_KEEP(init.text*) \
+ MEM_KEEP(exit.text*) \
+