--- /dev/null
+From 18daa52418e7e4629ed1703b64777294209d2622 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 10 Mar 2025 22:24:16 -0700
+Subject: driver core: fix potential NULL pointer dereference in dev_uevent()
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 18daa52418e7e4629ed1703b64777294209d2622 upstream.
+
+If userspace reads "uevent" device attribute at the same time as another
+threads unbinds the device from its driver, change to dev->driver from a
+valid pointer to NULL may result in crash. Fix this by using READ_ONCE()
+when fetching the pointer, and take bus' drivers klist lock to make sure
+driver instance will not disappear while we access it.
+
+Use WRITE_ONCE() when setting the driver pointer to ensure there is no
+tearing.
+
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20250311052417.1846985-3-dmitry.torokhov@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/base.h | 13 ++++++++++++-
+ drivers/base/bus.c | 2 +-
+ drivers/base/core.c | 33 +++++++++++++++++++++++++++++++--
+ 3 files changed, 44 insertions(+), 4 deletions(-)
+
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -73,6 +73,7 @@ static inline void subsys_put(struct sub
+ kset_put(&sp->subsys);
+ }
+
++struct subsys_private *bus_to_subsys(const struct bus_type *bus);
+ struct subsys_private *class_to_subsys(const struct class *class);
+
+ struct driver_private {
+@@ -181,8 +182,18 @@ void device_driver_detach(struct device
+
+ static inline void device_set_driver(struct device *dev, const struct device_driver *drv)
+ {
++ /*
++ * Majority (all?) read accesses to dev->driver happens either
++ * while holding device lock or in bus/driver code that is only
++ * invoked when the device is bound to a driver and there is no
++ * concern of the pointer being changed while it is being read.
++ * However when reading device's uevent file we read driver pointer
++ * without taking device lock (so we do not block there for
++ * arbitrary amount of time). We use WRITE_ONCE() here to prevent
++ * tearing so that READ_ONCE() can safely be used in uevent code.
++ */
+ // FIXME - this cast should not be needed "soon"
+- dev->driver = (struct device_driver *)drv;
++ WRITE_ONCE(dev->driver, (struct device_driver *)drv);
+ }
+
+ int devres_release_all(struct device *dev);
+--- a/drivers/base/bus.c
++++ b/drivers/base/bus.c
+@@ -57,7 +57,7 @@ static int __must_check bus_rescan_devic
+ * NULL. A call to subsys_put() must be done when finished with the pointer in
+ * order for it to be properly freed.
+ */
+-static struct subsys_private *bus_to_subsys(const struct bus_type *bus)
++struct subsys_private *bus_to_subsys(const struct bus_type *bus)
+ {
+ struct subsys_private *sp = NULL;
+ struct kobject *kobj;
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -2570,6 +2570,35 @@ static const char *dev_uevent_name(const
+ return NULL;
+ }
+
++/*
++ * Try filling "DRIVER=<name>" uevent variable for a device. Because this
++ * function may race with binding and unbinding the device from a driver,
++ * we need to be careful. Binding is generally safe, at worst we miss the
++ * fact that the device is already bound to a driver (but the driver
++ * information that is delivered through uevents is best-effort, it may
++ * become obsolete as soon as it is generated anyways). Unbinding is more
++ * risky as driver pointer is transitioning to NULL, so READ_ONCE() should
++ * be used to make sure we are dealing with the same pointer, and to
++ * ensure that driver structure is not going to disappear from under us
++ * we take bus' drivers klist lock. The assumption that only registered
++ * driver can be bound to a device, and to unregister a driver bus code
++ * will take the same lock.
++ */
++static void dev_driver_uevent(const struct device *dev, struct kobj_uevent_env *env)
++{
++ struct subsys_private *sp = bus_to_subsys(dev->bus);
++
++ if (sp) {
++ scoped_guard(spinlock, &sp->klist_drivers.k_lock) {
++ struct device_driver *drv = READ_ONCE(dev->driver);
++ if (drv)
++ add_uevent_var(env, "DRIVER=%s", drv->name);
++ }
++
++ subsys_put(sp);
++ }
++}
++
+ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env)
+ {
+ const struct device *dev = kobj_to_dev(kobj);
+@@ -2601,8 +2630,8 @@ static int dev_uevent(const struct kobje
+ if (dev->type && dev->type->name)
+ add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
+
+- if (dev->driver)
+- add_uevent_var(env, "DRIVER=%s", dev->driver->name);
++ /* Add "DRIVER=%s" variable if the device is bound to a driver */
++ dev_driver_uevent(dev, env);
+
+ /* Add common DT information about the device */
+ of_device_uevent(dev, env);
--- /dev/null
+From 04d3e5461c1f5cf8eec964ab64948ebed826e95e Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 10 Mar 2025 22:24:15 -0700
+Subject: driver core: introduce device_set_driver() helper
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit 04d3e5461c1f5cf8eec964ab64948ebed826e95e upstream.
+
+In preparation to closing a race when reading driver pointer in
+dev_uevent() code, instead of setting device->driver pointer directly
+introduce device_set_driver() helper.
+
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20250311052417.1846985-2-dmitry.torokhov@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/base.h | 6 ++++++
+ drivers/base/core.c | 2 +-
+ drivers/base/dd.c | 6 +++---
+ 3 files changed, 10 insertions(+), 4 deletions(-)
+
+--- a/drivers/base/base.h
++++ b/drivers/base/base.h
+@@ -179,6 +179,12 @@ int driver_add_groups(struct device_driv
+ void driver_remove_groups(struct device_driver *drv, const struct attribute_group **groups);
+ void device_driver_detach(struct device *dev);
+
++static inline void device_set_driver(struct device *dev, const struct device_driver *drv)
++{
++ // FIXME - this cast should not be needed "soon"
++ dev->driver = (struct device_driver *)drv;
++}
++
+ int devres_release_all(struct device *dev);
+ void device_block_probing(void);
+ void device_unblock_probing(void);
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -3688,7 +3688,7 @@ done:
+ device_pm_remove(dev);
+ dpm_sysfs_remove(dev);
+ DPMError:
+- dev->driver = NULL;
++ device_set_driver(dev, NULL);
+ bus_remove_device(dev);
+ BusError:
+ device_remove_attrs(dev);
+--- a/drivers/base/dd.c
++++ b/drivers/base/dd.c
+@@ -550,7 +550,7 @@ static void device_unbind_cleanup(struct
+ arch_teardown_dma_ops(dev);
+ kfree(dev->dma_range_map);
+ dev->dma_range_map = NULL;
+- dev->driver = NULL;
++ device_set_driver(dev, NULL);
+ dev_set_drvdata(dev, NULL);
+ if (dev->pm_domain && dev->pm_domain->dismiss)
+ dev->pm_domain->dismiss(dev);
+@@ -629,7 +629,7 @@ static int really_probe(struct device *d
+ }
+
+ re_probe:
+- dev->driver = drv;
++ device_set_driver(dev, drv);
+
+ /* If using pinctrl, bind pins now before probing */
+ ret = pinctrl_bind_pins(dev);
+@@ -1014,7 +1014,7 @@ static int __device_attach(struct device
+ if (ret == 0)
+ ret = 1;
+ else {
+- dev->driver = NULL;
++ device_set_driver(dev, NULL);
+ ret = 0;
+ }
+ } else {
--- /dev/null
+From dc1771f718548f7d4b93991b174c6e7b5e1ba410 Mon Sep 17 00:00:00 2001
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Date: Mon, 10 Mar 2025 22:24:14 -0700
+Subject: Revert "drivers: core: synchronize really_probe() and dev_uevent()"
+
+From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+commit dc1771f718548f7d4b93991b174c6e7b5e1ba410 upstream.
+
+This reverts commit c0a40097f0bc81deafc15f9195d1fb54595cd6d0.
+
+Probing a device can take arbitrary long time. In the field we observed
+that, for example, probing a bad micro-SD cards in an external USB card
+reader (or maybe cards were good but cables were flaky) sometimes takes
+longer than 2 minutes due to multiple retries at various levels of the
+stack. We can not block uevent_show() method for that long because udev
+is reading that attribute very often and that blocks udev and interferes
+with booting of the system.
+
+The change that introduced locking was concerned with dev_uevent()
+racing with unbinding the driver. However we can handle it without
+locking (which will be done in subsequent patch).
+
+There was also claim that synchronization with probe() is needed to
+properly load USB drivers, however this is a red herring: the change
+adding the lock was introduced in May of last year and USB loading and
+probing worked properly for many years before that.
+
+Revert the harmful locking.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20250311052417.1846985-1-dmitry.torokhov@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/core.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -2672,11 +2672,8 @@ static ssize_t uevent_show(struct device
+ if (!env)
+ return -ENOMEM;
+
+- /* Synchronize with really_probe() */
+- device_lock(dev);
+ /* let the kset specific function add its keys */
+ retval = kset->uevent_ops->uevent(&dev->kobj, env);
+- device_unlock(dev);
+ if (retval)
+ goto out;
+
x86-cpu-add-cpu-model-number-for-bartlett-lake-cpus-.patch
md-raid1-add-check-for-missing-source-disk-in-proces.patch
spi-spi-imx-add-check-for-spi_imx_setupxfer.patch
+x86-pvh-call-c-code-via-the-kernel-virtual-mapping.patch
+revert-drivers-core-synchronize-really_probe-and-dev_uevent.patch
+driver-core-introduce-device_set_driver-helper.patch
+driver-core-fix-potential-null-pointer-dereference-in-dev_uevent.patch
--- /dev/null
+From e8fbc0d9cab6c1ee6403f42c0991b0c1d5dbc092 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Wed, 9 Oct 2024 18:04:40 +0200
+Subject: x86/pvh: Call C code via the kernel virtual mapping
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit e8fbc0d9cab6c1ee6403f42c0991b0c1d5dbc092 upstream.
+
+Calling C code via a different mapping than it was linked at is
+problematic, because the compiler assumes that RIP-relative and absolute
+symbol references are interchangeable. GCC in particular may use
+RIP-relative per-CPU variable references even when not using -fpic.
+
+So call xen_prepare_pvh() via its kernel virtual mapping on x86_64, so
+that those RIP-relative references produce the correct values. This
+matches the pre-existing behavior for i386, which also invokes
+xen_prepare_pvh() via the kernel virtual mapping before invoking
+startup_32 with paging disabled again.
+
+Fixes: 7243b93345f7 ("xen/pvh: Bootstrap PVH guest")
+Tested-by: Jason Andryuk <jason.andryuk@amd.com>
+Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Message-ID: <20241009160438.3884381-8-ardb+git@google.com>
+Signed-off-by: Juergen Gross <jgross@suse.com>
+[ Stable context update ]
+Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/platform/pvh/head.S | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/platform/pvh/head.S
++++ b/arch/x86/platform/pvh/head.S
+@@ -100,7 +100,12 @@ SYM_CODE_START_LOCAL(pvh_start_xen)
+ xor %edx, %edx
+ wrmsr
+
+- call xen_prepare_pvh
++ /* Call xen_prepare_pvh() via the kernel virtual mapping */
++ leaq xen_prepare_pvh(%rip), %rax
++ subq phys_base(%rip), %rax
++ addq $__START_KERNEL_map, %rax
++ ANNOTATE_RETPOLINE_SAFE
++ call *%rax
+
+ /* startup_64 expects boot_params in %rsi. */
+ mov $_pa(pvh_bootparams), %rsi