Skip to contentSkip to conversation

6.7.3-rc1 review

PATCH In review Greg Kroah-Hartman 14 participants 362 messages Jan 29, 2024 – Feb 3, 2024 Page 1 of 3

Subsystems (6)
lore
Share & tools
lore
author maintainer
#1 lore raw

PATCH 1/346 soundwire: bus: introduce controller_id

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Pierre-Louis Bossart <[email protected]>

[ Upstream commit 6543ac13c623f906200dfd3f1c407d8d333b6995 ]

The existing SoundWire support misses a clear Controller/Manager hiearchical definition to deal with all variants across SOC vendors.

a) Intel platforms have one controller with 4 or more Managers.
b) AMD platforms have two controllers with one Manager each, but due to BIOS issues use two different link_id values within the scope of a single controller.
c) QCOM platforms have one or more controller with one Manager each.

This patch adds a 'controller_id' which can be set by higher levels. If assigned to -1, the controller_id will be set to the system-unique IDA-assigned bus->id.

The main change is that the bus->id is no longer used for any device name, which makes the definition completely predictable and not dependent on any enumeration order. The bus->id is only used to insert the Managers in the stream rt context.

Stable-dep-of: 8a8a9ac8a497 ("soundwire: fix initializing sysfs for same devices on different buses")

---
 drivers/soundwire/amd_manager.c     | 8 ++++++++
 drivers/soundwire/bus.c             | 4 ++++
 drivers/soundwire/debugfs.c         | 2 +-
 drivers/soundwire/intel_auxdevice.c | 3 +++
 drivers/soundwire/master.c          | 2 +-
 drivers/soundwire/qcom.c            | 3 +++
 include/linux/soundwire/sdw.h       | 4 +++-
 7 files changed, 23 insertions(+), 3 deletions(-)
drivers/soundwire/amd_manager.c +8 -0
index 3a99f6dcdfaf..a3b1f4e6f0f9 100644
@@ -927,6 +927,14 @@ static int amd_sdw_manager_probe(struct platform_device *pdev)
 	amd_manager->bus.clk_stop_timeout = 200;
 	amd_manager->bus.link_id = amd_manager->instance;
 
+	/*
+	 * Due to BIOS compatibility, the two links are exposed within
+	 * the scope of a single controller. If this changes, the
+	 * controller_id will have to be updated with drv_data
+	 * information.
+	 */
+	amd_manager->bus.controller_id = 0;
+
 	switch (amd_manager->instance) {
 	case ACP_SDW0:
 		amd_manager->num_dout_ports = AMD_SDW0_MAX_TX_PORTS;
drivers/soundwire/bus.c +4 -0
index 41b0d9adf68e..f3fec15c3112 100644
@@ -22,6 +22,10 @@ static int sdw_get_id(struct sdw_bus *bus)
 		return rc;
 
 	bus->id = rc;
+
+	if (bus->controller_id == -1)
+		bus->controller_id = rc;
+
 	return 0;
 }
 
drivers/soundwire/debugfs.c +1 -1
index d1553cb77187..67abd7e52f09 100644
@@ -20,7 +20,7 @@ void sdw_bus_debugfs_init(struct sdw_bus *bus)
 		return;
 
 	/* create the debugfs master-N */
-	snprintf(name, sizeof(name), "master-%d-%d", bus->id, bus->link_id);
+	snprintf(name, sizeof(name), "master-%d-%d", bus->controller_id, bus->link_id);
 	bus->debugfs = debugfs_create_dir(name, sdw_debugfs_root);
 }
 
drivers/soundwire/intel_auxdevice.c +3 -0
index 7f15e3549e53..93698532deac 100644
@@ -234,6 +234,9 @@ static int intel_link_probe(struct auxiliary_device *auxdev,
 	cdns->instance = sdw->instance;
 	cdns->msg_count = 0;
 
+	/* single controller for all SoundWire links */
+	bus->controller_id = 0;
+
 	bus->link_id = auxdev->id;
 	bus->clk_stop_timeout = 1;
 
drivers/soundwire/master.c +1 -1
index 9b05c9e25ebe..51abedbbaa66 100644
@@ -145,7 +145,7 @@ int sdw_master_device_add(struct sdw_bus *bus, struct device *parent,
 	md->dev.fwnode = fwnode;
 	md->dev.dma_mask = parent->dma_mask;
 
-	dev_set_name(&md->dev, "sdw-master-%d", bus->id);
+	dev_set_name(&md->dev, "sdw-master-%d-%d", bus->controller_id, bus->link_id);
 
 	ret = device_register(&md->dev);
 	if (ret) {
drivers/soundwire/qcom.c +3 -0
index a1e2d6c98186..8e027eee8b73 100644
@@ -1624,6 +1624,9 @@ static int qcom_swrm_probe(struct platform_device *pdev)
 		}
 	}
 
+	/* FIXME: is there a DT-defined value to use ? */
+	ctrl->bus.controller_id = -1;
+
 	ret = sdw_bus_master_add(&ctrl->bus, dev, dev->fwnode);
 	if (ret) {
 		dev_err(dev, "Failed to register Soundwire controller (%d)\n",
include/linux/soundwire/sdw.h +3 -1
index 4f3d14bb1538..c383579a008b 100644
@@ -886,7 +886,8 @@ struct sdw_master_ops {
  * struct sdw_bus - SoundWire bus
  * @dev: Shortcut to &bus->md->dev to avoid changing the entire code.
  * @md: Master device
- * @link_id: Link id number, can be 0 to N, unique for each Master
+ * @controller_id: system-unique controller ID. If set to -1, the bus @id will be used.
+ * @link_id: Link id number, can be 0 to N, unique for each Controller
  * @id: bus system-wide unique id
  * @slaves: list of Slaves on this bus
  * @assigned: Bitmap for Slave device numbers.
@@ -918,6 +919,7 @@ struct sdw_master_ops {
 struct sdw_bus {
 	struct device *dev;
 	struct sdw_master_device *md;
+	int controller_id;
 	unsigned int link_id;
 	int id;
 	struct list_head slaves;
Signature · 1 line
2.43.0
author maintainer
#10 lore raw

PATCH 10/346 PM: sleep: Fix possible deadlocks in core system-wide PM code

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rafael J. Wysocki <[email protected]>

commit 7839d0078e0d5e6cc2fa0b0dfbee71de74f1e557 upstream.

It is reported that in low-memory situations the system-wide resume core code deadlocks, because async_schedule_dev() executes its argument function synchronously if it cannot allocate memory (and not only in that case) and that function attempts to acquire a mutex that is already held. Executing the argument function synchronously from within dpm_async_fn() may also be problematic for ordering reasons (it may cause a consumer device's resume callback to be invoked before a requisite supplier device's one, for example).

Address this by changing the code in question to use async_schedule_dev_nocall() for scheduling the asynchronous execution of device suspend and resume functions and to directly run them synchronously if async_schedule_dev_nocall() returns false.

Cc 5.7+ <[email protected]> # 5.7+: 6aa09a5bccd8 async: Split async_schedule_node_domain()
Cc 5.7+ <[email protected]> # 5.7+: 7d4b5d7a37bd async: Introduce async_schedule_dev_nocall()
Cc 5.7+ <[email protected]> # 5.7+
---
 drivers/base/power/main.c |  148 +++++++++++++++++++++-------------------------
 1 file changed, 68 insertions(+), 80 deletions(-)
drivers/base/power/main.c +68 -80
@@ -579,7 +579,7 @@ bool dev_pm_skip_resume(struct device *d
 }
 
 /**
- * device_resume_noirq - Execute a "noirq resume" callback for given device.
+ * __device_resume_noirq - Execute a "noirq resume" callback for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
  * @async: If true, the device is being resumed asynchronously.
@@ -587,7 +587,7 @@ bool dev_pm_skip_resume(struct device *d
  * The driver of @dev will not receive interrupts while this function is being
  * executed.
  */
-static int device_resume_noirq(struct device *dev, pm_message_t state, bool async)
+static void __device_resume_noirq(struct device *dev, pm_message_t state, bool async)
 {
 	pm_callback_t callback = NULL;
 	const char *info = NULL;
@@ -655,7 +655,13 @@ Skip:
 Out:
 	complete_all(&dev->power.completion);
 	TRACE_RESUME(error);
-	return error;
+
+	if (error) {
+		suspend_stats.failed_resume_noirq++;
+		dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
+		dpm_save_failed_dev(dev_name(dev));
+		pm_dev_err(dev, state, async ? " async noirq" : " noirq", error);
+	}
 }
 
 static bool is_async(struct device *dev)
@@ -668,11 +674,15 @@ static bool dpm_async_fn(struct device *
 {
 	reinit_completion(&dev->power.completion);
 
-	if (is_async(dev)) {
-		get_device(dev);
-		async_schedule_dev(func, dev);
+	if (!is_async(dev))
+		return false;
+
+	get_device(dev);
+
+	if (async_schedule_dev_nocall(func, dev))
 		return true;
-	}
+
+	put_device(dev);
 
 	return false;
 }
@@ -680,15 +690,19 @@ static bool dpm_async_fn(struct device *
 static void async_resume_noirq(void *data, async_cookie_t cookie)
 {
 	struct device *dev = data;
-	int error;
-
-	error = device_resume_noirq(dev, pm_transition, true);
-	if (error)
-		pm_dev_err(dev, pm_transition, " async", error);
 
+	__device_resume_noirq(dev, pm_transition, true);
 	put_device(dev);
 }
 
+static void device_resume_noirq(struct device *dev)
+{
+	if (dpm_async_fn(dev, async_resume_noirq))
+		return;
+
+	__device_resume_noirq(dev, pm_transition, false);
+}
+
 static void dpm_noirq_resume_devices(pm_message_t state)
 {
 	struct device *dev;
@@ -698,14 +712,6 @@ static void dpm_noirq_resume_devices(pm_
 	mutex_lock(&dpm_list_mtx);
 	pm_transition = state;
 
-	/*
-	 * Advanced the async threads upfront,
-	 * in case the starting of async threads is
-	 * delayed by non-async resuming devices.
-	 */
-	list_for_each_entry(dev, &dpm_noirq_list, power.entry)
-		dpm_async_fn(dev, async_resume_noirq);
-
 	while (!list_empty(&dpm_noirq_list)) {
 		dev = to_device(dpm_noirq_list.next);
 		get_device(dev);
@@ -713,17 +719,7 @@ static void dpm_noirq_resume_devices(pm_
 
 		mutex_unlock(&dpm_list_mtx);
 
-		if (!is_async(dev)) {
-			int error;
-
-			error = device_resume_noirq(dev, state, false);
-			if (error) {
-				suspend_stats.failed_resume_noirq++;
-				dpm_save_failed_step(SUSPEND_RESUME_NOIRQ);
-				dpm_save_failed_dev(dev_name(dev));
-				pm_dev_err(dev, state, " noirq", error);
-			}
-		}
+		device_resume_noirq(dev);
 
 		put_device(dev);
 
@@ -751,14 +747,14 @@ void dpm_resume_noirq(pm_message_t state
 }
 
 /**
- * device_resume_early - Execute an "early resume" callback for given device.
+ * __device_resume_early - Execute an "early resume" callback for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
  * @async: If true, the device is being resumed asynchronously.
  *
  * Runtime PM is disabled for @dev while this function is being executed.
  */
-static int device_resume_early(struct device *dev, pm_message_t state, bool async)
+static void __device_resume_early(struct device *dev, pm_message_t state, bool async)
 {
 	pm_callback_t callback = NULL;
 	const char *info = NULL;
@@ -811,21 +807,31 @@ Out:
 
 	pm_runtime_enable(dev);
 	complete_all(&dev->power.completion);
-	return error;
+
+	if (error) {
+		suspend_stats.failed_resume_early++;
+		dpm_save_failed_step(SUSPEND_RESUME_EARLY);
+		dpm_save_failed_dev(dev_name(dev));
+		pm_dev_err(dev, state, async ? " async early" : " early", error);
+	}
 }
 
 static void async_resume_early(void *data, async_cookie_t cookie)
 {
 	struct device *dev = data;
-	int error;
-
-	error = device_resume_early(dev, pm_transition, true);
-	if (error)
-		pm_dev_err(dev, pm_transition, " async", error);
 
+	__device_resume_early(dev, pm_transition, true);
 	put_device(dev);
 }
 
+static void device_resume_early(struct device *dev)
+{
+	if (dpm_async_fn(dev, async_resume_early))
+		return;
+
+	__device_resume_early(dev, pm_transition, false);
+}
+
 /**
  * dpm_resume_early - Execute "early resume" callbacks for all devices.
  * @state: PM transition of the system being carried out.
@@ -839,14 +845,6 @@ void dpm_resume_early(pm_message_t state
 	mutex_lock(&dpm_list_mtx);
 	pm_transition = state;
 
-	/*
-	 * Advanced the async threads upfront,
-	 * in case the starting of async threads is
-	 * delayed by non-async resuming devices.
-	 */
-	list_for_each_entry(dev, &dpm_late_early_list, power.entry)
-		dpm_async_fn(dev, async_resume_early);
-
 	while (!list_empty(&dpm_late_early_list)) {
 		dev = to_device(dpm_late_early_list.next);
 		get_device(dev);
@@ -854,17 +852,7 @@ void dpm_resume_early(pm_message_t state
 
 		mutex_unlock(&dpm_list_mtx);
 
-		if (!is_async(dev)) {
-			int error;
-
-			error = device_resume_early(dev, state, false);
-			if (error) {
-				suspend_stats.failed_resume_early++;
-				dpm_save_failed_step(SUSPEND_RESUME_EARLY);
-				dpm_save_failed_dev(dev_name(dev));
-				pm_dev_err(dev, state, " early", error);
-			}
-		}
+		device_resume_early(dev);
 
 		put_device(dev);
 
@@ -888,12 +876,12 @@ void dpm_resume_start(pm_message_t state
 EXPORT_SYMBOL_GPL(dpm_resume_start);
 
 /**
- * device_resume - Execute "resume" callbacks for given device.
+ * __device_resume - Execute "resume" callbacks for given device.
  * @dev: Device to handle.
  * @state: PM transition of the system being carried out.
  * @async: If true, the device is being resumed asynchronously.
  */
-static int device_resume(struct device *dev, pm_message_t state, bool async)
+static void __device_resume(struct device *dev, pm_message_t state, bool async)
 {
 	pm_callback_t callback = NULL;
 	const char *info = NULL;
@@ -975,20 +963,30 @@ static int device_resume(struct device *
 
 	TRACE_RESUME(error);
 
-	return error;
+	if (error) {
+		suspend_stats.failed_resume++;
+		dpm_save_failed_step(SUSPEND_RESUME);
+		dpm_save_failed_dev(dev_name(dev));
+		pm_dev_err(dev, state, async ? " async" : "", error);
+	}
 }
 
 static void async_resume(void *data, async_cookie_t cookie)
 {
 	struct device *dev = data;
-	int error;
 
-	error = device_resume(dev, pm_transition, true);
-	if (error)
-		pm_dev_err(dev, pm_transition, " async", error);
+	__device_resume(dev, pm_transition, true);
 	put_device(dev);
 }
 
+static void device_resume(struct device *dev)
+{
+	if (dpm_async_fn(dev, async_resume))
+		return;
+
+	__device_resume(dev, pm_transition, false);
+}
+
 /**
  * dpm_resume - Execute "resume" callbacks for non-sysdev devices.
  * @state: PM transition of the system being carried out.
@@ -1008,27 +1006,17 @@ void dpm_resume(pm_message_t state)
 	pm_transition = state;
 	async_error = 0;
 
-	list_for_each_entry(dev, &dpm_suspended_list, power.entry)
-		dpm_async_fn(dev, async_resume);
-
 	while (!list_empty(&dpm_suspended_list)) {
 		dev = to_device(dpm_suspended_list.next);
+
 		get_device(dev);
-		if (!is_async(dev)) {
-			int error;
 
-			mutex_unlock(&dpm_list_mtx);
+		mutex_unlock(&dpm_list_mtx);
 
-			error = device_resume(dev, state, false);
-			if (error) {
-				suspend_stats.failed_resume++;
-				dpm_save_failed_step(SUSPEND_RESUME);
-				dpm_save_failed_dev(dev_name(dev));
-				pm_dev_err(dev, state, "", error);
-			}
+		device_resume(dev);
+
+		mutex_lock(&dpm_list_mtx);
 
-			mutex_lock(&dpm_list_mtx);
-		}
 		if (!list_empty(&dev->power.entry))
 			list_move_tail(&dev->power.entry, &dpm_prepared_list);
 
author maintainer
#11 lore raw

PATCH 11/346 arm64: properly install vmlinuz.efi

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Josef Bacik <[email protected]>

commit 7b21ed7d119dc06b0ed2ba3e406a02cafe3a8d03 upstream.

If you select CONFIG_EFI_ZBOOT, we will generate vmlinuz.efi, and then when we go to install the kernel we'll install the vmlinux instead because install.sh only recognizes Image.gz as wanting the compressed install image. With CONFIG_EFI_ZBOOT we don't get the proper kernel installed, which means it doesn't boot, which makes for a very confused and subsequently angry kernel developer.

Fix this by properly installing our compressed kernel if we've enabled CONFIG_EFI_ZBOOT.

---
 arch/arm64/boot/install.sh |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/boot/install.sh +2 -1
@@ -17,7 +17,8 @@
 #   $3 - kernel map file
 #   $4 - default install path (blank if root directory)
 
-if [ "$(basename $2)" = "Image.gz" ]; then
+if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ]
+then
 # Compressed install
   echo "Installing compressed kernel"
   base=vmlinuz
author maintainer
#12 lore raw

PATCH 12/346 OPP: Pass rounded rate to _set_opp()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Viresh Kumar <[email protected]>

commit 7269c250db1b89cda72ca419b7bd5e37997309d6 upstream.

The OPP core finds the eventual frequency to set with the help of clk_round_rate() and the same was earlier getting passed to _set_opp() and that's what would get configured.

The commit 1efae8d2e777 ("OPP: Make dev_pm_opp_set_opp() independent of frequency") mistakenly changed that. Fix it.

Fixes 1efae8d2e777 ("OPP: Make dev_pm_opp_set_opp() independent of frequency")
Cc v5.18+ <[email protected]> # v6.0+
---
 drivers/opp/core.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/opp/core.c +3 -3
@@ -1378,12 +1378,12 @@ int dev_pm_opp_set_rate(struct device *d
 		 * value of the frequency. In such a case, do not abort but
 		 * configure the hardware to the desired frequency forcefully.
 		 */
-		forced = opp_table->rate_clk_single != target_freq;
+		forced = opp_table->rate_clk_single != freq;
 	}
 
-	ret = _set_opp(dev, opp_table, opp, &target_freq, forced);
+	ret = _set_opp(dev, opp_table, opp, &freq, forced);
 
-	if (target_freq)
+	if (freq)
 		dev_pm_opp_put(opp);
 
 put_opp_table:
author maintainer
#13 lore raw

PATCH 13/346 btrfs: sysfs: validate scrub_speed_max value

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: David Disseldorp <[email protected]>

commit 2b0122aaa800b021e36027d7f29e206f87c761d6 upstream.

The value set as scrub_speed_max accepts size with suffixes (k/m/g/t/p/e) but we should still validate it for trailing characters, similar to what we do with chunk_size_store.

---
 fs/btrfs/sysfs.c |    4 ++++
 1 file changed, 4 insertions(+)
fs/btrfs/sysfs.c +4 -0
@@ -1783,6 +1783,10 @@ static ssize_t btrfs_devinfo_scrub_speed
 	unsigned long long limit;
 
 	limit = memparse(buf, &endptr);
+	/* There could be trailing '\n', also catch any typos after the value. */
+	endptr = skip_spaces(endptr);
+	if (*endptr != 0)
+		return -EINVAL;
 	WRITE_ONCE(device->scrub_speed_max, limit);
 	return len;
 }
author maintainer
#14 lore raw

PATCH 14/346 crypto: lib/mpi - Fix unexpected pointer access in mpi_ec_init

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tianjia Zhang <[email protected]>

commit ba3c5574203034781ac4231acf117da917efcd2a upstream.

When the mpi_ec_ctx structure is initialized, some fields are not cleared, causing a crash when referencing the field when the structure was released. Initially, this issue was ignored because memory for mpi_ec_ctx is allocated with the __GFP_ZERO flag. For example, this error will be triggered when calculating the Za value for SM2 separately.

Fixes d58bb7e55a8a ("lib/mpi: Introduce ec implementation to MPI library")
---
 lib/crypto/mpi/ec.c |    3 +++
 1 file changed, 3 insertions(+)
lib/crypto/mpi/ec.c +3 -0
@@ -584,6 +584,9 @@ void mpi_ec_init(struct mpi_ec_ctx *ctx,
 	ctx->a = mpi_copy(a);
 	ctx->b = mpi_copy(b);
 
+	ctx->d = NULL;
+	ctx->t.two_inv_p = NULL;
+
 	ctx->t.p_barrett = use_barrett > 0 ? mpi_barrett_init(ctx->p, 0) : NULL;
 
 	mpi_ec_get_reset(ctx);
author maintainer
#15 lore raw

PATCH 15/346 erofs: fix lz4 inplace decompression

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Gao Xiang <[email protected]>

commit 3c12466b6b7bf1e56f9b32c366a3d83d87afb4de upstream.

Currently EROFS can map another compressed buffer for inplace decompression, that was used to handle the cases that some pages of compressed data are actually not in-place I/O.

However, like most simple LZ77 algorithms, LZ4 expects the compressed data is arranged at the end of the decompressed buffer and it explicitly uses memmove() to handle overlapping:
__________________________________________________________
|_ direction of decompression --> ____ |_ compressed data _|

Although EROFS arranges compressed data like this, it typically maps two individual virtual buffers so the relative order is uncertain. Previously, it was hardly observed since LZ4 only uses memmove() for short overlapped literals and x86/arm64 memmove implementations seem to completely cover it up and they don't have this issue. Juhyung reported that EROFS data corruption can be found on a new Intel x86 processor. After some analysis, it seems that recent x86 processors with the new FSRM feature expose this issue with "rep movsb".

Let's strictly use the decompressed buffer for lz4 inplace decompression for now. Later, as an useful improvement, we could try to tie up these two buffers together in the correct order.

Reported-and-tested-by Juhyung Park <[email protected]>
Fixes 0ffd71bcc3a0 ("staging: erofs: introduce LZ4 decompression inplace")
Fixes 598162d05080 ("erofs: support decompress big pcluster for lz4 backend")
Cc stable <[email protected]> # 5.4+
---
 fs/erofs/decompressor.c |   31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)
fs/erofs/decompressor.c +16 -15
@@ -121,11 +121,11 @@ static int z_erofs_lz4_prepare_dstpages(
 }
 
 static void *z_erofs_lz4_handle_overlap(struct z_erofs_lz4_decompress_ctx *ctx,
-			void *inpage, unsigned int *inputmargin, int *maptype,
-			bool may_inplace)
+			void *inpage, void *out, unsigned int *inputmargin,
+			int *maptype, bool may_inplace)
 {
 	struct z_erofs_decompress_req *rq = ctx->rq;
-	unsigned int omargin, total, i, j;
+	unsigned int omargin, total, i;
 	struct page **in;
 	void *src, *tmp;
 
@@ -135,12 +135,13 @@ static void *z_erofs_lz4_handle_overlap(
 		    omargin < LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize))
 			goto docopy;
 
-		for (i = 0; i < ctx->inpages; ++i) {
-			DBG_BUGON(rq->in[i] == NULL);
-			for (j = 0; j < ctx->outpages - ctx->inpages + i; ++j)
-				if (rq->out[j] == rq->in[i])
-					goto docopy;
-		}
+		for (i = 0; i < ctx->inpages; ++i)
+			if (rq->out[ctx->outpages - ctx->inpages + i] !=
+			    rq->in[i])
+				goto docopy;
+		kunmap_local(inpage);
+		*maptype = 3;
+		return out + ((ctx->outpages - ctx->inpages) << PAGE_SHIFT);
 	}
 
 	if (ctx->inpages <= 1) {
@@ -148,7 +149,6 @@ static void *z_erofs_lz4_handle_overlap(
 		return inpage;
 	}
 	kunmap_local(inpage);
-	might_sleep();
 	src = erofs_vm_map_ram(rq->in, ctx->inpages);
 	if (!src)
 		return ERR_PTR(-ENOMEM);
@@ -204,12 +204,12 @@ int z_erofs_fixup_insize(struct z_erofs_
 }
 
 static int z_erofs_lz4_decompress_mem(struct z_erofs_lz4_decompress_ctx *ctx,
-				      u8 *out)
+				      u8 *dst)
 {
 	struct z_erofs_decompress_req *rq = ctx->rq;
 	bool support_0padding = false, may_inplace = false;
 	unsigned int inputmargin;
-	u8 *headpage, *src;
+	u8 *out, *headpage, *src;
 	int ret, maptype;
 
 	DBG_BUGON(*rq->in == NULL);
@@ -230,11 +230,12 @@ static int z_erofs_lz4_decompress_mem(st
 	}
 
 	inputmargin = rq->pageofs_in;
-	src = z_erofs_lz4_handle_overlap(ctx, headpage, &inputmargin,
+	src = z_erofs_lz4_handle_overlap(ctx, headpage, dst, &inputmargin,
 					 &maptype, may_inplace);
 	if (IS_ERR(src))
 		return PTR_ERR(src);
 
+	out = dst + rq->pageofs_out;
 	/* legacy format could compress extra data in a pcluster. */
 	if (rq->partial_decoding || !support_0padding)
 		ret = LZ4_decompress_safe_partial(src + inputmargin, out,
@@ -265,7 +266,7 @@ static int z_erofs_lz4_decompress_mem(st
 		vm_unmap_ram(src, ctx->inpages);
 	} else if (maptype == 2) {
 		erofs_put_pcpubuf(src);
-	} else {
+	} else if (maptype != 3) {
 		DBG_BUGON(1);
 		return -EFAULT;
 	}
@@ -308,7 +309,7 @@ static int z_erofs_lz4_decompress(struct
 	}
 
 dstmap_out:
-	ret = z_erofs_lz4_decompress_mem(&ctx, dst + rq->pageofs_out);
+	ret = z_erofs_lz4_decompress_mem(&ctx, dst);
 	if (!dst_maptype)
 		kunmap_local(dst);
 	else if (dst_maptype == 2)
author maintainer
#16 lore raw

PATCH 16/346 crypto: api - Disallow identical driver names

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herbert Xu <[email protected]>

commit 27016f75f5ed47e2d8e0ca75a8ff1f40bc1a5e27 upstream.

Disallow registration of two algorithms with identical driver names.

---
 crypto/algapi.c |    1 +
 1 file changed, 1 insertion(+)
crypto/algapi.c +1 -0
@@ -341,6 +341,7 @@ __crypto_register_alg(struct crypto_alg
 		}
 
 		if (!strcmp(q->cra_driver_name, alg->cra_name) ||
+		    !strcmp(q->cra_driver_name, alg->cra_driver_name) ||
 		    !strcmp(q->cra_name, alg->cra_driver_name))
 			goto err;
 	}
author maintainer
#17 lore raw

PATCH 17/346 PM: hibernate: Enforce ordering during image compression/decompression

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hongchen Zhang <[email protected]>

commit 71cd7e80cfde548959952eac7063aeaea1f2e1c6 upstream.

An S4 (suspend to disk) test on the LoongArch 3A6000 platform sometimes fails with the following error messaged in the dmesg log:

Invalid LZO compressed length

That happens because when compressing/decompressing the image, the synchronization between the control thread and the compress/decompress/crc thread is based on a relaxed ordering interface, which is unreliable, and the following situation may occur:

CPU 0 CPU 1
save_image_lzo lzo_compress_threadfn

					  atomic_set(&d->stop, 1);

atomic_read(&data[thr].stop)
data[thr].cmp = data[thr].cmp_len;
WRITE data[thr].cmp_len

Then CPU0 gets a stale cmp_len and writes it to disk. During resume from S4, wrong cmp_len is loaded.

To maintain data consistency between the two threads, use the acquire/release variants of atomic set and read operations.

Fixes 081a9d043c98 ("PM / Hibernate: Improve performance of LZO/plain hibernation, checksum image")
Cc All applicable <[email protected]>
[ rjw: Subject rewrite and changelog edits ]
---
 kernel/power/swap.c |   38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)
kernel/power/swap.c +19 -19
@@ -606,11 +606,11 @@ static int crc32_threadfn(void *data)
 	unsigned i;
 
 	while (1) {
-		wait_event(d->go, atomic_read(&d->ready) ||
+		wait_event(d->go, atomic_read_acquire(&d->ready) ||
 		                  kthread_should_stop());
 		if (kthread_should_stop()) {
 			d->thr = NULL;
-			atomic_set(&d->stop, 1);
+			atomic_set_release(&d->stop, 1);
 			wake_up(&d->done);
 			break;
 		}
@@ -619,7 +619,7 @@ static int crc32_threadfn(void *data)
 		for (i = 0; i < d->run_threads; i++)
 			*d->crc32 = crc32_le(*d->crc32,
 			                     d->unc[i], *d->unc_len[i]);
-		atomic_set(&d->stop, 1);
+		atomic_set_release(&d->stop, 1);
 		wake_up(&d->done);
 	}
 	return 0;
@@ -649,12 +649,12 @@ static int lzo_compress_threadfn(void *d
 	struct cmp_data *d = data;
 
 	while (1) {
-		wait_event(d->go, atomic_read(&d->ready) ||
+		wait_event(d->go, atomic_read_acquire(&d->ready) ||
 		                  kthread_should_stop());
 		if (kthread_should_stop()) {
 			d->thr = NULL;
 			d->ret = -1;
-			atomic_set(&d->stop, 1);
+			atomic_set_release(&d->stop, 1);
 			wake_up(&d->done);
 			break;
 		}
@@ -663,7 +663,7 @@ static int lzo_compress_threadfn(void *d
 		d->ret = lzo1x_1_compress(d->unc, d->unc_len,
 		                          d->cmp + LZO_HEADER, &d->cmp_len,
 		                          d->wrk);
-		atomic_set(&d->stop, 1);
+		atomic_set_release(&d->stop, 1);
 		wake_up(&d->done);
 	}
 	return 0;
@@ -798,7 +798,7 @@ static int save_image_lzo(struct swap_ma
 
 			data[thr].unc_len = off;
 
-			atomic_set(&data[thr].ready, 1);
+			atomic_set_release(&data[thr].ready, 1);
 			wake_up(&data[thr].go);
 		}
 
@@ -806,12 +806,12 @@ static int save_image_lzo(struct swap_ma
 			break;
 
 		crc->run_threads = thr;
-		atomic_set(&crc->ready, 1);
+		atomic_set_release(&crc->ready, 1);
 		wake_up(&crc->go);
 
 		for (run_threads = thr, thr = 0; thr < run_threads; thr++) {
 			wait_event(data[thr].done,
-			           atomic_read(&data[thr].stop));
+				atomic_read_acquire(&data[thr].stop));
 			atomic_set(&data[thr].stop, 0);
 
 			ret = data[thr].ret;
@@ -850,7 +850,7 @@ static int save_image_lzo(struct swap_ma
 			}
 		}
 
-		wait_event(crc->done, atomic_read(&crc->stop));
+		wait_event(crc->done, atomic_read_acquire(&crc->stop));
 		atomic_set(&crc->stop, 0);
 	}
 
@@ -1132,12 +1132,12 @@ static int lzo_decompress_threadfn(void
 	struct dec_data *d = data;
 
 	while (1) {
-		wait_event(d->go, atomic_read(&d->ready) ||
+		wait_event(d->go, atomic_read_acquire(&d->ready) ||
 		                  kthread_should_stop());
 		if (kthread_should_stop()) {
 			d->thr = NULL;
 			d->ret = -1;
-			atomic_set(&d->stop, 1);
+			atomic_set_release(&d->stop, 1);
 			wake_up(&d->done);
 			break;
 		}
@@ -1150,7 +1150,7 @@ static int lzo_decompress_threadfn(void
 			flush_icache_range((unsigned long)d->unc,
 					   (unsigned long)d->unc + d->unc_len);
 
-		atomic_set(&d->stop, 1);
+		atomic_set_release(&d->stop, 1);
 		wake_up(&d->done);
 	}
 	return 0;
@@ -1335,7 +1335,7 @@ static int load_image_lzo(struct swap_ma
 		}
 
 		if (crc->run_threads) {
-			wait_event(crc->done, atomic_read(&crc->stop));
+			wait_event(crc->done, atomic_read_acquire(&crc->stop));
 			atomic_set(&crc->stop, 0);
 			crc->run_threads = 0;
 		}
@@ -1371,7 +1371,7 @@ static int load_image_lzo(struct swap_ma
 					pg = 0;
 			}
 
-			atomic_set(&data[thr].ready, 1);
+			atomic_set_release(&data[thr].ready, 1);
 			wake_up(&data[thr].go);
 		}
 
@@ -1390,7 +1390,7 @@ static int load_image_lzo(struct swap_ma
 
 		for (run_threads = thr, thr = 0; thr < run_threads; thr++) {
 			wait_event(data[thr].done,
-			           atomic_read(&data[thr].stop));
+				atomic_read_acquire(&data[thr].stop));
 			atomic_set(&data[thr].stop, 0);
 
 			ret = data[thr].ret;
@@ -1421,7 +1421,7 @@ static int load_image_lzo(struct swap_ma
 				ret = snapshot_write_next(snapshot);
 				if (ret <= 0) {
 					crc->run_threads = thr + 1;
-					atomic_set(&crc->ready, 1);
+					atomic_set_release(&crc->ready, 1);
 					wake_up(&crc->go);
 					goto out_finish;
 				}
@@ -1429,13 +1429,13 @@ static int load_image_lzo(struct swap_ma
 		}
 
 		crc->run_threads = thr;
-		atomic_set(&crc->ready, 1);
+		atomic_set_release(&crc->ready, 1);
 		wake_up(&crc->go);
 	}
 
 out_finish:
 	if (crc->run_threads) {
-		wait_event(crc->done, atomic_read(&crc->stop));
+		wait_event(crc->done, atomic_read_acquire(&crc->stop));
 		atomic_set(&crc->stop, 0);
 	}
 	stop = ktime_get();
author maintainer
#18 lore raw

PATCH 18/346 hwrng: core - Fix page fault dead lock on mmap-ed hwrng

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herbert Xu <[email protected]>

commit 78aafb3884f6bc6636efcc1760c891c8500b9922 upstream.

There is a dead-lock in the hwrng device read path. This triggers when the user reads from /dev/hwrng into memory also mmap-ed from /dev/hwrng. The resulting page fault triggers a recursive read which then dead-locks.

Fix this by using a stack buffer when calling copy_to_user.

Reported-by [email protected]
Fixes 9996508b3353 ("hwrng: core - Replace u32 in driver API with byte array")
---
 drivers/char/hw_random/core.c |   34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)
drivers/char/hw_random/core.c +21 -13
@@ -23,10 +23,13 @@
 #include <linux/sched.h>
 #include <linux/sched/signal.h>
 #include <linux/slab.h>
+#include <linux/string.h>
 #include <linux/uaccess.h>
 
 #define RNG_MODULE_NAME		"hw_random"
 
+#define RNG_BUFFER_SIZE (SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES)
+
 static struct hwrng *current_rng;
 /* the current rng has been explicitly chosen by user via sysfs */
 static int cur_rng_set_by_user;
@@ -58,7 +61,7 @@ static inline int rng_get_data(struct hw
 
 static size_t rng_buffer_size(void)
 {
-	return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES;
+	return RNG_BUFFER_SIZE;
 }
 
 static void add_early_randomness(struct hwrng *rng)
@@ -209,6 +212,7 @@ static inline int rng_get_data(struct hw
 static ssize_t rng_dev_read(struct file *filp, char __user *buf,
 			    size_t size, loff_t *offp)
 {
+	u8 buffer[RNG_BUFFER_SIZE];
 	ssize_t ret = 0;
 	int err = 0;
 	int bytes_read, len;
@@ -236,34 +240,37 @@ static ssize_t rng_dev_read(struct file
 			if (bytes_read < 0) {
 				err = bytes_read;
 				goto out_unlock_reading;
+			} else if (bytes_read == 0 &&
+				   (filp->f_flags & O_NONBLOCK)) {
+				err = -EAGAIN;
+				goto out_unlock_reading;
 			}
+
 			data_avail = bytes_read;
 		}
 
-		if (!data_avail) {
-			if (filp->f_flags & O_NONBLOCK) {
-				err = -EAGAIN;
-				goto out_unlock_reading;
-			}
-		} else {
-			len = data_avail;
+		len = data_avail;
+		if (len) {
 			if (len > size)
 				len = size;
 
 			data_avail -= len;
 
-			if (copy_to_user(buf + ret, rng_buffer + data_avail,
-								len)) {
+			memcpy(buffer, rng_buffer + data_avail, len);
+		}
+		mutex_unlock(&reading_mutex);
+		put_rng(rng);
+
+		if (len) {
+			if (copy_to_user(buf + ret, buffer, len)) {
 				err = -EFAULT;
-				goto out_unlock_reading;
+				goto out;
 			}
 
 			size -= len;
 			ret += len;
 		}
 
-		mutex_unlock(&reading_mutex);
-		put_rng(rng);
 
 		if (need_resched())
 			schedule_timeout_interruptible(1);
@@ -274,6 +281,7 @@ static ssize_t rng_dev_read(struct file
 		}
 	}
 out:
+	memzero_explicit(buffer, sizeof(buffer));
 	return ret ? : err;
 
 out_unlock_reading:
author maintainer
#19 lore raw

PATCH 19/346 crypto: s390/aes - Fix buffer overread in CTR mode

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herbert Xu <[email protected]>

commit d07f951903fa9922c375b8ab1ce81b18a0034e3b upstream.

When processing the last block, the s390 ctr code will always read a whole block, even if there isn't a whole block of data left. Fix this by using the actual length left and copy it into a buffer first for processing.

Fixes 0200f3ecc196 ("crypto: s390 - add System z hardware support for CTR mode")
---
 arch/s390/crypto/aes_s390.c  |    4 +++-
 arch/s390/crypto/paes_s390.c |    4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)
arch/s390/crypto/aes_s390.c +3 -1
@@ -597,7 +597,9 @@ static int ctr_aes_crypt(struct skcipher
 	 * final block may be < AES_BLOCK_SIZE, copy only nbytes
 	 */
 	if (nbytes) {
-		cpacf_kmctr(sctx->fc, sctx->key, buf, walk.src.virt.addr,
+		memset(buf, 0, AES_BLOCK_SIZE);
+		memcpy(buf, walk.src.virt.addr, nbytes);
+		cpacf_kmctr(sctx->fc, sctx->key, buf, buf,
 			    AES_BLOCK_SIZE, walk.iv);
 		memcpy(walk.dst.virt.addr, buf, nbytes);
 		crypto_inc(walk.iv, AES_BLOCK_SIZE);
arch/s390/crypto/paes_s390.c +3 -1
@@ -693,9 +693,11 @@ static int ctr_paes_crypt(struct skciphe
 	 * final block may be < AES_BLOCK_SIZE, copy only nbytes
 	 */
 	if (nbytes) {
+		memset(buf, 0, AES_BLOCK_SIZE);
+		memcpy(buf, walk.src.virt.addr, nbytes);
 		while (1) {
 			if (cpacf_kmctr(ctx->fc, &param, buf,
-					walk.src.virt.addr, AES_BLOCK_SIZE,
+					buf, AES_BLOCK_SIZE,
 					walk.iv) == AES_BLOCK_SIZE)
 				break;
 			if (__paes_convert_key(ctx))
author maintainer
#2 lore raw

PATCH 2/346 soundwire: fix initializing sysfs for same devices on different buses

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Krzysztof Kozlowski <[email protected]>

[ Upstream commit 8a8a9ac8a4972ee69d3dd3d1ae43963ae39cee18 ]

If same devices with same device IDs are present on different soundwire buses, the probe fails due to conflicting device names and sysfs entries:

sysfs: cannot create duplicate filename '/bus/soundwire/devices/sdw:0:0217:0204:00:0'

The link ID is 0 for both devices, so they should be differentiated by the controller ID. Add the controller ID so, the device names and sysfs entries look like:

sdw:1:0:0217:0204:00:0 -> ../../../devices/platform/soc@0/6ab0000.soundwire-controller/sdw-master-1-0/sdw:1:0:0217:0204:00:0 sdw:3:0:0217:0204:00:0 -> ../../../devices/platform/soc@0/6b10000.soundwire-controller/sdw-master-3-0/sdw:3:0:0217:0204:00:0

[PLB changes: use bus->controller_id instead of bus->id]

---
 drivers/soundwire/slave.c        | 12 ++++++------
 sound/soc/intel/boards/sof_sdw.c |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/soundwire/slave.c +6 -6
index c1c1a2ac293a..060c2982e26b 100644
@@ -39,14 +39,14 @@ int sdw_slave_add(struct sdw_bus *bus,
 	slave->dev.fwnode = fwnode;
 
 	if (id->unique_id == SDW_IGNORED_UNIQUE_ID) {
-		/* name shall be sdw:link:mfg:part:class */
-		dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x",
-			     bus->link_id, id->mfg_id, id->part_id,
+		/* name shall be sdw:ctrl:link:mfg:part:class */
+		dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x",
+			     bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
 			     id->class_id);
 	} else {
-		/* name shall be sdw:link:mfg:part:class:unique */
-		dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x:%01x",
-			     bus->link_id, id->mfg_id, id->part_id,
+		/* name shall be sdw:ctrl:link:mfg:part:class:unique */
+		dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x:%01x",
+			     bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
 			     id->class_id, id->unique_id);
 	}
 
sound/soc/intel/boards/sof_sdw.c +2 -2
index 4e4284729773..1e788859c863 100644
@@ -1232,11 +1232,11 @@ static int fill_sdw_codec_dlc(struct device *dev,
 	else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id,
 				  class_id, adr_index))
 		codec->name = devm_kasprintf(dev, GFP_KERNEL,
-					     "sdw:%01x:%04x:%04x:%02x", link_id,
+					     "sdw:0:%01x:%04x:%04x:%02x", link_id,
 					     mfg_id, part_id, class_id);
 	else
 		codec->name = devm_kasprintf(dev, GFP_KERNEL,
-					     "sdw:%01x:%04x:%04x:%02x:%01x", link_id,
+					     "sdw:0:%01x:%04x:%04x:%02x:%01x", link_id,
 					     mfg_id, part_id, class_id, unique_id);
 
 	if (!codec->name)
Signature · 1 line
2.43.0
author maintainer
#20 lore raw

PATCH 20/346 s390/vfio-ap: unpin pages on gisc registration failure

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Anthony Krowiak <[email protected]>

commit 7b2d039da622daa9ba259ac6f38701d542b237c3 upstream.

In the vfio_ap_irq_enable function, after the page containing the notification indicator byte (NIB) is pinned, the function attempts to register the guest ISC. If registration fails, the function sets the status response code and returns without unpinning the page containing the NIB. In order to avoid a memory leak, the NIB should be unpinned before returning from the vfio_ap_irq_enable function.

---
 drivers/s390/crypto/vfio_ap_ops.c |    1 +
 1 file changed, 1 insertion(+)
drivers/s390/crypto/vfio_ap_ops.c +1 -0
@@ -457,6 +457,7 @@ static struct ap_queue_status vfio_ap_ir
 		VFIO_AP_DBF_WARN("%s: gisc registration failed: nisc=%d, isc=%d, apqn=%#04x\n",
 				 __func__, nisc, isc, q->apqn);
 
+		vfio_unpin_pages(&q->matrix_mdev->vdev, nib, 1);
 		status.response_code = AP_RESPONSE_INVALID_GISA;
 		return status;
 	}
author maintainer
#21 lore raw

PATCH 21/346 PM / devfreq: Fix buffer overflow in trans_stat_show

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Christian Marangi <[email protected]>

commit 08e23d05fa6dc4fc13da0ccf09defdd4bbc92ff4 upstream.

Fix buffer overflow in trans_stat_show().

Convert simple snprintf to the more secure scnprintf with size of PAGE_SIZE.

Add condition checking if we are exceeding PAGE_SIZE and exit early from loop. Also add at the end a warning that we exceeded PAGE_SIZE and that stats is disabled.

Return -EFBIG in the case where we don't have enough space to write the full transition table.

Also document in the ABI that this function can return -EFBIG error.

Fixes e552bbaf5b98 ("PM / devfreq: Add sysfs node for representing frequency transition information.")
---
 Documentation/ABI/testing/sysfs-class-devfreq |    3 +
 drivers/devfreq/devfreq.c                     |   59 +++++++++++++++++---------
 2 files changed, 43 insertions(+), 19 deletions(-)
Documentation/ABI/testing/sysfs-class-devfreq +3 -0
@@ -52,6 +52,9 @@ Description:
 
 			echo 0 > /sys/class/devfreq/.../trans_stat
 
+		If the transition table is bigger than PAGE_SIZE, reading
+		this will return an -EFBIG error.
+
 What:		/sys/class/devfreq/.../available_frequencies
 Date:		October 2012
 Contact:	Nishanth Menon <[email protected]>
drivers/devfreq/devfreq.c +40 -19

85 lines not on this page · raw message

author maintainer
#22 lore raw

PATCH 22/346 mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miquel Raynal <[email protected]>

commit a7d84a2e7663bbe12394cc771107e04668ea313a upstream.

While switching to ref counters for track mtd devices use, the vmu-flash driver was forgotten. The reason for reading the ref counter seems debatable, but let's just fix the build for now.

---
 drivers/mtd/maps/vmu-flash.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/maps/vmu-flash.c +1 -1
@@ -719,7 +719,7 @@ static int vmu_can_unload(struct maple_d
 	card = maple_get_drvdata(mdev);
 	for (x = 0; x < card->partitions; x++) {
 		mtd = &((card->mtd)[x]);
-		if (mtd->usecount > 0)
+		if (kref_read(&mtd->refcnt))
 			return 0;
 	}
 	return 1;
author maintainer
#23 lore raw

PATCH 23/346 mtd: rawnand: Prevent crossing LUN boundaries during sequential reads

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miquel Raynal <[email protected]>

commit bbcd80f53a5e8c27c2511f539fec8c373f500cf4 upstream.

The ONFI specification states that devices do not need to support sequential reads across LUN boundaries. In order to prevent such event from happening and possibly failing, let's introduce the concept of "pause" in the sequential read to handle these cases. The first/last pages remain the same but any time we cross a LUN boundary we will end and restart (if relevant) the sequential read operation.

---
 drivers/mtd/nand/raw/nand_base.c |   43 +++++++++++++++++++++++++++++++++------
 include/linux/mtd/rawnand.h      |    2 +
 2 files changed, 39 insertions(+), 6 deletions(-)
drivers/mtd/nand/raw/nand_base.c +37 -6
@@ -1207,6 +1207,23 @@ static int nand_lp_exec_read_page_op(str
 	return nand_exec_op(chip, &op);
 }
 
+static void rawnand_cap_cont_reads(struct nand_chip *chip)
+{
+	struct nand_memory_organization *memorg;
+	unsigned int pages_per_lun, first_lun, last_lun;
+
+	memorg = nanddev_get_memorg(&chip->base);
+	pages_per_lun = memorg->pages_per_eraseblock * memorg->eraseblocks_per_lun;
+	first_lun = chip->cont_read.first_page / pages_per_lun;
+	last_lun = chip->cont_read.last_page / pages_per_lun;
+
+	/* Prevent sequential cache reads across LUN boundaries */
+	if (first_lun != last_lun)
+		chip->cont_read.pause_page = first_lun * pages_per_lun + pages_per_lun - 1;
+	else
+		chip->cont_read.pause_page = chip->cont_read.last_page;
+}
+
 static int nand_lp_exec_cont_read_page_op(struct nand_chip *chip, unsigned int page,
 					  unsigned int offset_in_page, void *buf,
 					  unsigned int len, bool check_only)
@@ -1225,7 +1242,7 @@ static int nand_lp_exec_cont_read_page_o
 		NAND_OP_DATA_IN(len, buf, 0),
 	};
 	struct nand_op_instr cont_instrs[] = {
-		NAND_OP_CMD(page == chip->cont_read.last_page ?
+		NAND_OP_CMD(page == chip->cont_read.pause_page ?
 			    NAND_CMD_READCACHEEND : NAND_CMD_READCACHESEQ,
 			    NAND_COMMON_TIMING_NS(conf, tWB_max)),
 		NAND_OP_WAIT_RDY(NAND_COMMON_TIMING_MS(conf, tR_max),
@@ -1262,16 +1279,29 @@ static int nand_lp_exec_cont_read_page_o
 	}
 
 	if (page == chip->cont_read.first_page)
-		return nand_exec_op(chip, &start_op);
+		ret = nand_exec_op(chip, &start_op);
 	else
-		return nand_exec_op(chip, &cont_op);
+		ret = nand_exec_op(chip, &cont_op);
+	if (ret)
+		return ret;
+
+	if (!chip->cont_read.ongoing)
+		return 0;
+
+	if (page == chip->cont_read.pause_page &&
+	    page != chip->cont_read.last_page) {
+		chip->cont_read.first_page = chip->cont_read.pause_page + 1;
+		rawnand_cap_cont_reads(chip);
+	} else if (page == chip->cont_read.last_page) {
+		chip->cont_read.ongoing = false;
+	}
+
+	return 0;
 }
 
 static bool rawnand_cont_read_ongoing(struct nand_chip *chip, unsigned int page)
 {
-	return chip->cont_read.ongoing &&
-		page >= chip->cont_read.first_page &&
-		page <= chip->cont_read.last_page;
+	return chip->cont_read.ongoing && page >= chip->cont_read.first_page;
 }
 
 /**
@@ -3445,6 +3475,7 @@ static void rawnand_enable_cont_reads(st
 	if (col)
 		chip->cont_read.first_page++;
 	chip->cont_read.last_page = page + ((readlen >> chip->page_shift) & chip->pagemask);
+	rawnand_cap_cont_reads(chip);
 }
 
 /**
include/linux/mtd/rawnand.h +2 -0
@@ -1265,6 +1265,7 @@ struct nand_secure_region {
  * @cont_read: Sequential page read internals
  * @cont_read.ongoing: Whether a continuous read is ongoing or not
  * @cont_read.first_page: Start of the continuous read operation
+ * @cont_read.pause_page: End of the current sequential cache read operation
  * @cont_read.last_page: End of the continuous read operation
  * @controller: The hardware controller	structure which is shared among multiple
  *              independent devices
@@ -1321,6 +1322,7 @@ struct nand_chip {
 	struct {
 		bool ongoing;
 		unsigned int first_page;
+		unsigned int pause_page;
 		unsigned int last_page;
 	} cont_read;
 
author maintainer
#24 lore raw

PATCH 24/346 mtd: rawnand: Fix core interference with sequential reads

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miquel Raynal <[email protected]>

commit 7c9414c870c027737d0f2ed7b0ed10f26edb1c61 upstream.

A couple of reports pointed at some strange failures happening a bit randomly since the introduction of sequential page reads support. After investigation it turned out the most likely reason for these issues was the fact that sometimes a (longer) read might happen, starting at the same page that was read previously. This is optimized by the raw NAND core, by not sending the READ_PAGE command to the NAND device and just reading out the data in a local cache. When this page is also flagged as being the starting point for a sequential read, it means the page right next will be accessed without the right instructions. The NAND chip will be confused and will not output correct data. In order to avoid such situation from happening anymore, we can however handle this case with a bit of additional logic, to postpone the initialization of the read sequence by one page.

---
 drivers/mtd/nand/raw/nand_base.c |   14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/mtd/nand/raw/nand_base.c +14 -0
@@ -3478,6 +3478,18 @@ static void rawnand_enable_cont_reads(st
 	rawnand_cap_cont_reads(chip);
 }
 
+static void rawnand_cont_read_skip_first_page(struct nand_chip *chip, unsigned int page)
+{
+	if (!chip->cont_read.ongoing || page != chip->cont_read.first_page)
+		return;
+
+	chip->cont_read.first_page++;
+	if (chip->cont_read.first_page == chip->cont_read.pause_page)
+		chip->cont_read.first_page++;
+	if (chip->cont_read.first_page >= chip->cont_read.last_page)
+		chip->cont_read.ongoing = false;
+}
+
 /**
  * nand_setup_read_retry - [INTERN] Set the READ RETRY mode
  * @chip: NAND chip object
@@ -3652,6 +3664,8 @@ read_retry:
 			buf += bytes;
 			max_bitflips = max_t(unsigned int, max_bitflips,
 					     chip->pagecache.bitflips);
+
+			rawnand_cont_read_skip_first_page(chip, page);
 		}
 
 		readlen -= bytes;
author maintainer
#25 lore raw

PATCH 25/346 mtd: rawnand: Prevent sequential reads with on-die ECC engines

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miquel Raynal <[email protected]>

commit a62c4597953fe54c6af04166a5e2872efd0e1490 upstream.

Some devices support sequential reads when using the on-die ECC engines, some others do not. It is a bit hard to know which ones will break other than experimentally, so in order to avoid such a difficult and painful task, let's just pretend all devices should avoid using this optimization when configured like this.

---
 drivers/mtd/nand/raw/nand_base.c |    8 ++++++++
 1 file changed, 8 insertions(+)
drivers/mtd/nand/raw/nand_base.c +8 -0
@@ -5170,6 +5170,14 @@ static void rawnand_late_check_supported
 	/* The supported_op fields should not be set by individual drivers */
 	WARN_ON_ONCE(chip->controller->supported_op.cont_read);
 
+	/*
+	 * Too many devices do not support sequential cached reads with on-die
+	 * ECC correction enabled, so in this case refuse to perform the
+	 * automation.
+	 */
+	if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_DIE)
+		return;
+
 	if (!nand_has_exec_op(chip))
 		return;
 
author maintainer
#26 lore raw

PATCH 26/346 mtd: rawnand: Clarify conditions to enable continuous reads

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miquel Raynal <[email protected]>

commit 828f6df1bcba7f64729166efc7086ea657070445 upstream.

The current logic is probably fine but is a bit convoluted. Plus, we don't want partial pages to be part of the sequential operation just in case the core would optimize the page read with a subpage read (which would break the sequence). This may happen on the first and last page only, so if the start offset or the end offset is not aligned with a page boundary, better avoid them to prevent any risk.

---
 drivers/mtd/nand/raw/nand_base.c |   24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)
drivers/mtd/nand/raw/nand_base.c +16 -8
@@ -3460,21 +3460,29 @@ static void rawnand_enable_cont_reads(st
 				      u32 readlen, int col)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	unsigned int end_page, end_col;
+
+	chip->cont_read.ongoing = false;
 
 	if (!chip->controller->supported_op.cont_read)
 		return;
 
-	if ((col && col + readlen < (3 * mtd->writesize)) ||
-	    (!col && readlen < (2 * mtd->writesize))) {
-		chip->cont_read.ongoing = false;
+	end_page = DIV_ROUND_UP(col + readlen, mtd->writesize);
+	end_col = (col + readlen) % mtd->writesize;
+
+	if (col)
+		page++;
+
+	if (end_col && end_page)
+		end_page--;
+
+	if (page + 1 > end_page)
 		return;
-	}
 
-	chip->cont_read.ongoing = true;
 	chip->cont_read.first_page = page;
-	if (col)
-		chip->cont_read.first_page++;
-	chip->cont_read.last_page = page + ((readlen >> chip->page_shift) & chip->pagemask);
+	chip->cont_read.last_page = end_page;
+	chip->cont_read.ongoing = true;
+
 	rawnand_cap_cont_reads(chip);
 }
 
author maintainer
#27 lore raw

PATCH 27/346 soc: qcom: pmic_glink_altmode: fix port sanity check

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit c4fb7d2eac9ff9bfc35a2e4d40c7169a332416e0 upstream.

The PMIC GLINK altmode driver currently supports at most two ports.

Fix the incomplete port sanity check on notifications to avoid accessing and corrupting memory beyond the port array if we ever get a notification for an unsupported port.

---
 drivers/soc/qcom/pmic_glink_altmode.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/soc/qcom/pmic_glink_altmode.c +2 -2
@@ -285,7 +285,7 @@ static void pmic_glink_altmode_sc8180xp_
 
 	svid = mux == 2 ? USB_TYPEC_DP_SID : 0;
 
-	if (!altmode->ports[port].altmode) {
+	if (port >= ARRAY_SIZE(altmode->ports) || !altmode->ports[port].altmode) {
 		dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
 		return;
 	}
@@ -328,7 +328,7 @@ static void pmic_glink_altmode_sc8280xp_
 	hpd_state = FIELD_GET(SC8280XP_HPD_STATE_MASK, notify->payload[8]);
 	hpd_irq = FIELD_GET(SC8280XP_HPD_IRQ_MASK, notify->payload[8]);
 
-	if (!altmode->ports[port].altmode) {
+	if (port >= ARRAY_SIZE(altmode->ports) || !altmode->ports[port].altmode) {
 		dev_dbg(altmode->dev, "notification on undefined port %d\n", port);
 		return;
 	}
author maintainer
#3 lore raw

PATCH 3/346 iio: adc: ad7091r: Set alert bit in config register

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marcelo Schmitt <[email protected]>

[ Upstream commit 149694f5e79b0c7a36ceb76e7c0d590db8f151c1 ]

The ad7091r-base driver sets up an interrupt handler for firing events when inputs are either above or below a certain threshold. However, for the interrupt signal to come from the device it must be configured to enable the ALERT/BUSY/GPO pin to be used as ALERT, which was not being done until now.
Enable interrupt signals on the ALERT/BUSY/GPO pin by setting the proper bit in the configuration register.

Stable-dep-of: 020e71c7ffc2 ("iio: adc: ad7091r: Allow users to configure device events")

---
 drivers/iio/adc/ad7091r-base.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/iio/adc/ad7091r-base.c +6 -0
index 0e5d3d2e9c98..8aaa854f816f 100644
@@ -28,6 +28,7 @@
 #define AD7091R_REG_RESULT_CONV_RESULT(x)   ((x) & 0xfff)
 
 /* AD7091R_REG_CONF */
+#define AD7091R_REG_CONF_ALERT_EN   BIT(4)
 #define AD7091R_REG_CONF_AUTO   BIT(8)
 #define AD7091R_REG_CONF_CMD    BIT(10)
 
@@ -232,6 +233,11 @@ int ad7091r_probe(struct device *dev, const char *name,
 	iio_dev->channels = chip_info->channels;
 
 	if (irq) {
+		ret = regmap_update_bits(st->map, AD7091R_REG_CONF,
+					 AD7091R_REG_CONF_ALERT_EN, BIT(4));
+		if (ret)
+			return ret;
+
 		ret = devm_request_threaded_irq(dev, irq, NULL,
 				ad7091r_event_handler,
 				IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev);
Signature · 1 line
2.43.0
author maintainer
#4 lore raw

PATCH 4/346 iio: adc: ad7091r: Allow users to configure device events

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marcelo Schmitt <[email protected]>

[ Upstream commit 020e71c7ffc25dfe29ed9be6c2d39af7bd7f661f ]

AD7091R-5 devices are supported by the ad7091r-5 driver together with the ad7091r-base driver. Those drivers declared iio events for notifying user space when ADC readings fall bellow the thresholds of low limit registers or above the values set in high limit registers. However, to configure iio events and their thresholds, a set of callback functions must be implemented and those were not present until now. The consequence of trying to configure ad7091r-5 events without the proper callback functions was a null pointer dereference in the kernel because the pointers to the callback functions were not set.

Implement event configuration callbacks allowing users to read/write event thresholds and enable/disable event generation.

Since the event spec structs are generic to AD7091R devices, also move those from the ad7091r-5 driver the base driver so they can be reused when support for ad7091r-2/-4/-8 be added.

---
 drivers/iio/adc/ad7091r-base.c | 156 +++++++++++++++++++++++++++++++++
 drivers/iio/adc/ad7091r-base.h |   6 ++
 drivers/iio/adc/ad7091r5.c     |  28 +-----
 3 files changed, 166 insertions(+), 24 deletions(-)
drivers/iio/adc/ad7091r-base.c +156 -0
index 8aaa854f816f..3d36bcd26b0c 100644
@@ -6,6 +6,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/bitfield.h>
 #include <linux/iio/events.h>
 #include <linux/iio/iio.h>
 #include <linux/interrupt.h>
@@ -50,6 +51,27 @@ struct ad7091r_state {
 	struct mutex lock; /*lock to prevent concurent reads */
 };
 
+const struct iio_event_spec ad7091r_events[] = {
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_RISING,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+				 BIT(IIO_EV_INFO_ENABLE),
+	},
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_FALLING,
+		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
+				 BIT(IIO_EV_INFO_ENABLE),
+	},
+	{
+		.type = IIO_EV_TYPE_THRESH,
+		.dir = IIO_EV_DIR_EITHER,
+		.mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+	},
+};
+EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R);
+
 static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode)
 {
 	int ret, conf;
@@ -169,8 +191,142 @@ static int ad7091r_read_raw(struct iio_dev *iio_dev,
 	return ret;
 }
 
+static int ad7091r_read_event_config(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir)
+{
+	struct ad7091r_state *st = iio_priv(indio_dev);
+	int val, ret;
+
+	switch (dir) {
+	case IIO_EV_DIR_RISING:
+		ret = regmap_read(st->map,
+				  AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
+				  &val);
+		if (ret)
+			return ret;
+		return val != AD7091R_HIGH_LIMIT;
+	case IIO_EV_DIR_FALLING:
+		ret = regmap_read(st->map,
+				  AD7091R_REG_CH_LOW_LIMIT(chan->channel),
+				  &val);
+		if (ret)
+			return ret;
+		return val != AD7091R_LOW_LIMIT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ad7091r_write_event_config(struct iio_dev *indio_dev,
+				      const struct iio_chan_spec *chan,
+				      enum iio_event_type type,
+				      enum iio_event_direction dir, int state)
+{
+	struct ad7091r_state *st = iio_priv(indio_dev);
+
+	if (state) {
+		return regmap_set_bits(st->map, AD7091R_REG_CONF,
+				       AD7091R_REG_CONF_ALERT_EN);
+	} else {
+		/*
+		 * Set thresholds either to 0 or to 2^12 - 1 as appropriate to
+		 * prevent alerts and thus disable event generation.
+		 */
+		switch (dir) {
+		case IIO_EV_DIR_RISING:
+			return regmap_write(st->map,
+					    AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
+					    AD7091R_HIGH_LIMIT);
+		case IIO_EV_DIR_FALLING:
+			return regmap_write(st->map,
+					    AD7091R_REG_CH_LOW_LIMIT(chan->channel),
+					    AD7091R_LOW_LIMIT);
+		default:
+			return -EINVAL;
+		}
+	}
+}
+
+static int ad7091r_read_event_value(struct iio_dev *indio_dev,
+				    const struct iio_chan_spec *chan,
+				    enum iio_event_type type,
+				    enum iio_event_direction dir,
+				    enum iio_event_info info, int *val, int *val2)
+{
+	struct ad7091r_state *st = iio_priv(indio_dev);
+	int ret;
+
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		switch (dir) {
+		case IIO_EV_DIR_RISING:
+			ret = regmap_read(st->map,
+					  AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
+					  val);
+			if (ret)
+				return ret;
+			return IIO_VAL_INT;
+		case IIO_EV_DIR_FALLING:
+			ret = regmap_read(st->map,
+					  AD7091R_REG_CH_LOW_LIMIT(chan->channel),
+					  val);
+			if (ret)
+				return ret;
+			return IIO_VAL_INT;
+		default:
+			return -EINVAL;
+		}
+	case IIO_EV_INFO_HYSTERESIS:
+		ret = regmap_read(st->map,
+				  AD7091R_REG_CH_HYSTERESIS(chan->channel),
+				  val);
+		if (ret)
+			return ret;
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int ad7091r_write_event_value(struct iio_dev *indio_dev,
+				     const struct iio_chan_spec *chan,
+				     enum iio_event_type type,
+				     enum iio_event_direction dir,
+				     enum iio_event_info info, int val, int val2)
+{
+	struct ad7091r_state *st = iio_priv(indio_dev);
+
+	switch (info) {
+	case IIO_EV_INFO_VALUE:
+		switch (dir) {
+		case IIO_EV_DIR_RISING:
+			return regmap_write(st->map,
+					    AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
+					    val);
+		case IIO_EV_DIR_FALLING:
+			return regmap_write(st->map,
+					    AD7091R_REG_CH_LOW_LIMIT(chan->channel),
+					    val);
+		default:
+			return -EINVAL;
+		}
+	case IIO_EV_INFO_HYSTERESIS:
+		return regmap_write(st->map,
+				    AD7091R_REG_CH_HYSTERESIS(chan->channel),
+				    val);
+	default:
+		return -EINVAL;
+	}
+}
+
 static const struct iio_info ad7091r_info = {
 	.read_raw = ad7091r_read_raw,
+	.read_event_config = &ad7091r_read_event_config,
+	.write_event_config = &ad7091r_write_event_config,
+	.read_event_value = &ad7091r_read_event_value,
+	.write_event_value = &ad7091r_write_event_value,
 };
 
 static irqreturn_t ad7091r_event_handler(int irq, void *private)
drivers/iio/adc/ad7091r-base.h +6 -0
index 509748aef9b1..7a78976a2f80 100644
@@ -8,6 +8,10 @@
 #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
 #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
 
+/* AD7091R_REG_CH_LIMIT */
+#define AD7091R_HIGH_LIMIT		0xFFF
+#define AD7091R_LOW_LIMIT		0x0
+
 struct device;
 struct ad7091r_state;
 
@@ -17,6 +21,8 @@ struct ad7091r_chip_info {
 	unsigned int vref_mV;
 };
 
+extern const struct iio_event_spec ad7091r_events[3];
+
 extern const struct regmap_config ad7091r_regmap_config;
 
 int ad7091r_probe(struct device *dev, const char *name,
drivers/iio/adc/ad7091r5.c +4 -24
index 2f048527b7b7..dae98c95ebb8 100644
@@ -12,26 +12,6 @@
 
 #include "ad7091r-base.h"
 
-static const struct iio_event_spec ad7091r5_events[] = {
-	{
-		.type = IIO_EV_TYPE_THRESH,
-		.dir = IIO_EV_DIR_RISING,
-		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
-				 BIT(IIO_EV_INFO_ENABLE),
-	},
-	{
-		.type = IIO_EV_TYPE_THRESH,
-		.dir = IIO_EV_DIR_FALLING,
-		.mask_separate = BIT(IIO_EV_INFO_VALUE) |
-				 BIT(IIO_EV_INFO_ENABLE),
-	},
-	{
-		.type = IIO_EV_TYPE_THRESH,
-		.dir = IIO_EV_DIR_EITHER,
-		.mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
-	},
-};
-
 #define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \
 	.type = IIO_VOLTAGE, \
 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
@@ -44,10 +24,10 @@ static const struct iio_event_spec ad7091r5_events[] = {
 	.scan_type.realbits = bits, \
 }
 static const struct iio_chan_spec ad7091r5_channels_irq[] = {
-	AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
-	AD7091R_CHANNEL(1, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
-	AD7091R_CHANNEL(2, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
-	AD7091R_CHANNEL(3, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+	AD7091R_CHANNEL(0, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
+	AD7091R_CHANNEL(1, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
+	AD7091R_CHANNEL(2, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
+	AD7091R_CHANNEL(3, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
 };
 
 static const struct iio_chan_spec ad7091r5_channels_noirq[] = {
Signature · 1 line
2.43.0
author maintainer
#5 lore raw

PATCH 5/346 pipe: wakeup wr_wait after setting max_usage

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Lukas Schauer <[email protected]>

commit e95aada4cb93d42e25c30a0ef9eb2923d9711d4a upstream.

Commit c73be61cede5 ("pipe: Add general notification queue support") a regression was introduced that would lock up resized pipes under certain conditions. See the reproducer in [1].

The commit resizing the pipe ring size was moved to a different function, doing that moved the wakeup for pipe->wr_wait before actually raising pipe->max_usage. If a pipe was full before the resize occured it would result in the wakeup never actually triggering pipe_write.

Set @max_usage and @nr_accounted before waking writers if this isn't a watch queue.

---
 fs/pipe.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
fs/pipe.c +5 -2
@@ -1324,6 +1324,11 @@ int pipe_resize_ring(struct pipe_inode_i
 	pipe->tail = tail;
 	pipe->head = head;
 
+	if (!pipe_has_watch_queue(pipe)) {
+		pipe->max_usage = nr_slots;
+		pipe->nr_accounted = nr_slots;
+	}
+
 	spin_unlock_irq(&pipe->rd_wait.lock);
 
 	/* This might have made more room for writers */
@@ -1375,8 +1380,6 @@ static long pipe_set_size(struct pipe_in
 	if (ret < 0)
 		goto out_revert_acct;
 
-	pipe->max_usage = nr_slots;
-	pipe->nr_accounted = nr_slots;
 	return pipe->max_usage * PAGE_SIZE;
 
 out_revert_acct:
author maintainer
#6 lore raw

PATCH 6/346 powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Geoff Levand <[email protected]>

commit 482b718a84f08b6fc84879c3e90cc57dba11c115 upstream.

Commit 8c5fa3b5c4df ("powerpc/64: Make ELFv2 the default for big-endian builds"), merged in Linux-6.5-rc1 changes the calling ABI in a way that is incompatible with the current code for the PS3's LV1 hypervisor calls.

This change just adds the line '# CONFIG_PPC64_BIG_ENDIAN_ELF_ABI_V2 is not set' to the ps3_defconfig file so that the PPC64_ELF_ABI_V1 is used.

Fixes run time errors like these:

  BUG: Kernel NULL pointer dereference at 0x00000000
  Faulting instruction address: 0xc000000000047cf0
  Oops: Kernel access of bad area, sig: 11 [#1]
  Call Trace:
  [c0000000023039e0] [c00000000100ebfc] ps3_create_spu+0xc4/0x2b0 (unreliable)
  [c000000002303ab0] [c00000000100d4c4] create_spu+0xcc/0x3c4
  [c000000002303b40] [c00000000100eae4] ps3_enumerate_spus+0xa4/0xf8
Fixes 8c5fa3b5c4df ("powerpc/64: Make ELFv2 the default for big-endian builds")
---
 arch/powerpc/configs/ps3_defconfig |    1 +
 1 file changed, 1 insertion(+)
arch/powerpc/configs/ps3_defconfig +1 -0
@@ -24,6 +24,7 @@ CONFIG_PS3_VRAM=m
 CONFIG_PS3_LPM=m
 # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
 CONFIG_KEXEC=y
+# CONFIG_PPC64_BIG_ENDIAN_ELF_ABI_V2 is not set
 CONFIG_PPC_4K_PAGES=y
 CONFIG_SCHED_SMT=y
 CONFIG_PM=y
author maintainer
#7 lore raw

PATCH 7/346 ext4: allow for the last group to be marked as trimmed

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Suraj Jitindar Singh <[email protected]>

commit 7c784d624819acbeefb0018bac89e632467cca5a upstream.

The ext4 filesystem tracks the trim status of blocks at the group level. When an entire group has been trimmed then it is marked as such and subsequent trim invocations with the same minimum trim size will not be attempted on that group unless it is marked as able to be trimmed again such as when a block is freed.

Currently the last group can't be marked as trimmed due to incorrect logic in ext4_last_grp_cluster(). ext4_last_grp_cluster() is supposed to return the zero based index of the last cluster in a group. This is then used by ext4_try_to_trim_range() to determine if the trim operation spans the entire group and as such if the trim status of the group should be recorded.

ext4_last_grp_cluster() takes a 0 based group index, thus the valid values for grp are 0..(ext4_get_groups_count - 1). Any group index less than (ext4_get_groups_count - 1) is not the last group and must have EXT4_CLUSTERS_PER_GROUP(sb) clusters. For the last group we need to calculate the number of clusters based on the number of blocks in the group. Finally subtract 1 from the number of clusters as zero based indexing is expected. Rearrange the function slightly to make it clear what we are calculating and returning.

Reproducer:
// Create file system where the last group has fewer blocks than // blocks per group

$ mkfs.ext4 -b 4096 -g 8192 /dev/nvme0n1 8191
$ mount /dev/nvme0n1 /mnt

Before Patch:

$ fstrim -v /mnt
/mnt: 25.9 MiB (27156480 bytes) trimmed
// Group not marked as trimmed so second invocation still discards blocks
$ fstrim -v /mnt
/mnt: 25.9 MiB (27156480 bytes) trimmed

After Patch:
fstrim -v /mnt
/mnt: 25.9 MiB (27156480 bytes) trimmed
// Group marked as trimmed so second invocation DOESN'T discard any blocks fstrim -v /mnt
/mnt: 0 B (0 bytes) trimmed

Fixes 45e4ab320c9b ("ext4: move setting of trimmed bit into ext4_try_to_trim_range()")
Cc <[email protected]> # 4.19+
---
 fs/ext4/mballoc.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
fs/ext4/mballoc.c +10 -5
@@ -6735,11 +6735,16 @@ __acquires(bitlock)
 static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb,
 					   ext4_group_t grp)
 {
-	if (grp < ext4_get_groups_count(sb))
-		return EXT4_CLUSTERS_PER_GROUP(sb) - 1;
-	return (ext4_blocks_count(EXT4_SB(sb)->s_es) -
-		ext4_group_first_block_no(sb, grp) - 1) >>
-					EXT4_CLUSTER_BITS(sb);
+	unsigned long nr_clusters_in_group;
+
+	if (grp < (ext4_get_groups_count(sb) - 1))
+		nr_clusters_in_group = EXT4_CLUSTERS_PER_GROUP(sb);
+	else
+		nr_clusters_in_group = (ext4_blocks_count(EXT4_SB(sb)->s_es) -
+					ext4_group_first_block_no(sb, grp))
+				       >> EXT4_CLUSTER_BITS(sb);
+
+	return nr_clusters_in_group - 1;
 }
 
 static bool ext4_trim_interrupted(void)
author maintainer
#8 lore raw

PATCH 8/346 async: Split async_schedule_node_domain()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rafael J. Wysocki <[email protected]>

commit 6aa09a5bccd8e224d917afdb4c278fc66aacde4d upstream.

In preparation for subsequent changes, split async_schedule_node_domain() in two pieces so as to allow the bottom part of it to be called from a somewhat different code path.

No functional impact.

---
 kernel/async.c |   56 ++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 22 deletions(-)
kernel/async.c +34 -22
@@ -145,6 +145,39 @@ static void async_run_entry_fn(struct wo
 	wake_up(&async_done);
 }
 
+static async_cookie_t __async_schedule_node_domain(async_func_t func,
+						   void *data, int node,
+						   struct async_domain *domain,
+						   struct async_entry *entry)
+{
+	async_cookie_t newcookie;
+	unsigned long flags;
+
+	INIT_LIST_HEAD(&entry->domain_list);
+	INIT_LIST_HEAD(&entry->global_list);
+	INIT_WORK(&entry->work, async_run_entry_fn);
+	entry->func = func;
+	entry->data = data;
+	entry->domain = domain;
+
+	spin_lock_irqsave(&async_lock, flags);
+
+	/* allocate cookie and queue */
+	newcookie = entry->cookie = next_cookie++;
+
+	list_add_tail(&entry->domain_list, &domain->pending);
+	if (domain->registered)
+		list_add_tail(&entry->global_list, &async_global_pending);
+
+	atomic_inc(&entry_count);
+	spin_unlock_irqrestore(&async_lock, flags);
+
+	/* schedule for execution */
+	queue_work_node(node, system_unbound_wq, &entry->work);
+
+	return newcookie;
+}
+
 /**
  * async_schedule_node_domain - NUMA specific version of async_schedule_domain
  * @func: function to execute asynchronously
@@ -186,29 +219,8 @@ async_cookie_t async_schedule_node_domai
 		func(data, newcookie);
 		return newcookie;
 	}
-	INIT_LIST_HEAD(&entry->domain_list);
-	INIT_LIST_HEAD(&entry->global_list);
-	INIT_WORK(&entry->work, async_run_entry_fn);
-	entry->func = func;
-	entry->data = data;
-	entry->domain = domain;
-
-	spin_lock_irqsave(&async_lock, flags);
 
-	/* allocate cookie and queue */
-	newcookie = entry->cookie = next_cookie++;
-
-	list_add_tail(&entry->domain_list, &domain->pending);
-	if (domain->registered)
-		list_add_tail(&entry->global_list, &async_global_pending);
-
-	atomic_inc(&entry_count);
-	spin_unlock_irqrestore(&async_lock, flags);
-
-	/* schedule for execution */
-	queue_work_node(node, system_unbound_wq, &entry->work);
-
-	return newcookie;
+	return __async_schedule_node_domain(func, data, node, domain, entry);
 }
 EXPORT_SYMBOL_GPL(async_schedule_node_domain);
 

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 6.7.3-rc1 review

This is the start of the stable review cycle for the 6.7.3 release. There are 346 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.

Responses should be made by Wed, 31 Jan 2024 16:59:28 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.7.3-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.7.y
and the diffstat can be found below.

thanks,

greg k-h

-------------
Pseudo-Shortlog of commits:

Greg Kroah-Hartman <[email protected]>

    Linux 6.7.3-rc1

Richard Palethorpe <[email protected]>
x86/entry/ia32: Ensure s32 is sign extended to s64

Tim Chen <[email protected]>
tick/sched: Preserve number of idle sleeps across CPU hotplug events

Jiri Wiesner <[email protected]>
clocksource: Skip watchdog check for large watchdog intervals

Dawei Li <[email protected]>
genirq: Initialize resend_node hlist for all interrupt descriptors

Xi Ruoyao <[email protected]>
mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan

Quanquan Cao <[email protected]>
cxl/region:Fix overflow issue in alloc_hpa()

Jithu Joseph <[email protected]>
platform/x86/intel/ifs: Call release_firmware() when handling errors.

Michael Walle <[email protected]>
drm: bridge: samsung-dsim: Don't use FORCE_STOP_STATE

Inochi Amaoto <[email protected]>
riscv: dts: sophgo: separate sg2042 mtime and mtimecmp to fit aclint format

Aleksander Jan Bajkowski <[email protected]>
MIPS: lantiq: register smp_ops on non-smp platforms

Huacai Chen <[email protected]>
LoongArch/smp: Call rcutree_report_cpu_starting() at tlb_init()

David Lechner <[email protected]>
spi: fix finalize message on error return

Shyam Prasad N <[email protected]>
cifs: fix stray unlock in cifs_chan_skip_or_disable

Amit Kumar Mahapatra <[email protected]>
spi: spi-cadence: Reverse the order of interleaved write and read operations

Kamal Dasu <[email protected]>
spi: bcm-qspi: fix SFDP BFPT read by usig mspi read

Mario Limonciello <[email protected]>
cpufreq/amd-pstate: Fix setting scaling max/min freq values

Hsin-Yi Wang <[email protected]>
drm/bridge: anx7625: Ensure bridge is suspended in disable()

Li Lingfeng <[email protected]>
block: Move checking GENHD_FL_NO_PART to bdev_add_partition()

Mika Westerberg <[email protected]>
spi: intel-pci: Remove Meteor Lake-S SoC PCI ID from the list

Shravan Kumar Ramani <[email protected]>
platform/mellanox: mlxbf-pmc: Fix offset calculation for crspace events

Artur Weber <[email protected]>
ARM: dts: exynos4212-tab3: add samsung,invert-vclk flag to fimd

Wenhua Lin <[email protected]>
gpio: eic-sprd: Clear interrupt after set the interrupt type

Armin Wolf <[email protected]>
platform/x86: wmi: Fix error handling in legacy WMI notify handler functions

Cristian Marussi <[email protected]>
firmware: arm_ffa: Check xa_load() return value

Cristian Marussi <[email protected]>
firmware: arm_ffa: Add missing rwlock_init() for the driver partition

Cristian Marussi <[email protected]>
firmware: arm_ffa: Add missing rwlock_init() in ffa_setup_partitions()

Cristian Marussi <[email protected]>
firmware: arm_scmi: Fix the clock protocol version for v3.2

Cristian Marussi <[email protected]>
firmware: arm_scmi: Use xa_insert() when saving raw queues

Cristian Marussi <[email protected]>
firmware: arm_scmi: Use xa_insert() to store opps

Fedor Pchelkin <[email protected]>
drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume

Arnd Bergmann <[email protected]>
drm/exynos: fix accidental on-stack copy of exynos_drm_plane

Sebastian Andrzej Siewior <[email protected]>
futex: Prevent the reuse of stale pi_state

Yajun Deng <[email protected]>
memblock: fix crash when reserved memory is not added to memory

Douglas Anderson <[email protected]>
drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case

Pin-yen Lin <[email protected]>
drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable()

Tomi Valkeinen <[email protected]>
drm/bridge: sii902x: Fix audio codec unregistration

Tomi Valkeinen <[email protected]>
drm/bridge: sii902x: Fix probing race issue

Arnd Bergmann <[email protected]>
drm/panel/raydium-rm692e5: select CONFIG_DRM_DISPLAY_DP_HELPER

Artur Weber <[email protected]>
drm/panel: samsung-s6d7aa0: drop DRM_BUS_FLAG_DE_HIGH for lsl080al02

Markus Niebel <[email protected]>
drm: panel-simple: add missing bus flags for Tianma tm070jvhg[30/33]

Douglas Anderson <[email protected]>
drm/bridge: parade-ps8640: Wait for HPD when doing an AUX transfer

Alex Deucher <[email protected]>
drm/amdgpu/gfx11: set UNORD_DISPATCH in compute MQDs

Alex Deucher <[email protected]>
drm/amdgpu/gfx10: set UNORD_DISPATCH in compute MQDs

Friedrich Vock <[email protected]>
drm/amdgpu: Enable tunneling on high-priority compute queues

Dillon Varone <[email protected]>
drm/amd/display: Init link enc resources in dc_state only if res_pool presents

Wenjing Liu <[email protected]>
drm/amd/display: update pixel clock params after stream slice count change in context

Charlene Liu <[email protected]>
drm/amd/display: Add logging resource checks

Ilya Bakoulin <[email protected]>
drm/amd/display: Clear OPTC mem select on disable

George Shen <[email protected]>
drm/amd/display: Disconnect phantom pipe OPP from OPTC being disabled

Ilya Bakoulin <[email protected]>
drm/amd/display: Fix hang/underflow when transitioning to ODM4:1

Hsin-Yi Wang <[email protected]>
drm/panel-edp: drm/panel-edp: Fix AUO B116XTN02 name

Hsin-Yi Wang <[email protected]>
drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing

Sheng-Liang Pan <[email protected]>

    drm/panel-edp: Add AUO B116XTN02, BOE NT116WHM-N21,836X2, NV116WHM-N49 V8.0

Taimur Hassan <[email protected]>
drm/amd/display: Fix conversions between bytes and KB

Nicholas Kazlauskas <[email protected]>
drm/amd/display: Wake DMCUB before executing GPINT commands

Nicholas Kazlauskas <[email protected]>
drm/amd/display: Wake DMCUB before sending a command

Nicholas Kazlauskas <[email protected]>
drm/amd/display: Refactor DMCUB enter/exit idle interface

Samson Tam <[email protected]>
drm/amd/display: do not send commands to DMUB if DMUB is inactive from S3

Naohiro Aota <[email protected]>
btrfs: zoned: optimize hint byte for zoned allocator

Naohiro Aota <[email protected]>
btrfs: zoned: factor out prepare_allocation_zoned()

Alexander Stein <[email protected]>
media: i2c: imx290: Properly encode registers as little-endian

Alexander Stein <[email protected]>
media: v4l2-cci: Add support for little-endian encoded registers

Sakari Ailus <[email protected]>
media: v4l: cci: Add macros to obtain register width and address

Sakari Ailus <[email protected]>
media: v4l: cci: Include linux/bits.h

Ricardo Neri <[email protected]>
thermal: intel: hfi: Add syscore callbacks for system-wide PM

Ricardo Neri <[email protected]>
thermal: intel: hfi: Disable an HFI instance when all its CPUs go offline

Ricardo Neri <[email protected]>
thermal: intel: hfi: Refactor enabling code into helper functions

Srinivasan Shanmugam <[email protected]>
drm/amd/display: Fix uninitialized variable usage in core_link_ 'read_dpcd() & write_dpcd()' functions

Ma Jun <[email protected]>
drm/amdgpu/pm: Fix the power source flag error

Kenneth Feng <[email protected]>
drm/amd/pm: update the power cap setting

Lijo Lazar <[email protected]>
drm/amdgpu: Show vram vendor only if available

Lijo Lazar <[email protected]>
drm/amdgpu: Avoid fetching vram vendor information

Lijo Lazar <[email protected]>
drm/amd/pm: Fetch current power limit from FW

Tom St Denis <[email protected]>
drm/amd/amdgpu: Assign GART pages to AMD device mapping

Christophe JAILLET <[email protected]>
drm/amd/display: Fix a switch statement in populate_dml_output_cfg_from_stream_state()

Srinivasan Shanmugam <[email protected]>
drm/amd/display: Fix late derefrence 'dsc' check in 'link_set_dsc_pps_packet()'

Wayne Lin <[email protected]>
drm/amd/display: Align the returned error code with legacy DP

Nicholas Kazlauskas <[email protected]>
drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A

Ovidiu Bunea <[email protected]>
drm/amd/display: Fix DML2 watermark calculation

Srinivasan Shanmugam <[email protected]>
drm/amd/display: Fix variable deferencing before NULL check in edp_setup_replay()

Lijo Lazar <[email protected]>
drm/amd/pm: Add error log for smu v13.0.6 reset

Lijo Lazar <[email protected]>
drm/amd/pm: Fix smuv13.0.6 current clock reporting

Likun Gao <[email protected]>
drm/amdgpu: correct the cu count for gfx v11

Yifan Zhang <[email protected]>
drm/amdgpu: update regGL2C_CTRL4 value in golden setting

Alex Deucher <[email protected]>
drm/amdgpu: drop exp hw support check for GC 9.4.3

Ori Messinger <[email protected]>
drm/amdgpu: Enable GFXOFF for Compute on GFX11

Aurabindo Pillai <[email protected]>
drm/amd/display: Fix a debugfs null pointer error

Dan Carpenter <[email protected]>
drm/bridge: nxp-ptn3460: simplify some error checking

Ivan Lipski <[email protected]>
Revert "drm/amd/display: fix bandwidth validation failure on DCN 2.1"

Mario Limonciello <[email protected]>
drm/amd/display: Disable PSR-SU on Parade 0803 TCON again

Melissa Wen <[email protected]>
drm/amd/display: fix bandwidth validation failure on DCN 2.1

Javier Martinez Canillas <[email protected]>
drm: Allow drivers to indicate the damage helpers to ignore damage clips

Javier Martinez Canillas <[email protected]>
drm/virtio: Disable damage clipping if FB changed since last page-flip

Zack Rusin <[email protected]>
drm: Disable the cursor plane on atomic contexts with virtualized drivers

Tomi Valkeinen <[email protected]>
drm/tidss: Fix atomic_flush check

Thomas Zimmermann <[email protected]>
drm: Fix TODO list mentioning non-KMS drivers

Dan Carpenter <[email protected]>
drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking

Ville Syrjälä <[email protected]>
drm/i915/psr: Only allow PSR in LPSP mode on HSW non-ULT

Ville Syrjälä <[email protected]>
drm: Don't unref the same fb many times by mistake due to deadlock handling

Ville Syrjälä <[email protected]>
Revert "drm/i915/dsi: Do display on sequence later on icl+"

Dave Airlie <[email protected]>
Revert "nouveau: push event block/allowing out of the fence context"

Rafael J. Wysocki <[email protected]>
cpufreq: intel_pstate: Refine computation of P-state for given frequency

Mario Limonciello <[email protected]>
gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04

Dave Chinner <[email protected]>
xfs: read only mounts with fsopen mount API are busted

Ma Jun <[email protected]>
drm/amdgpu: Fix the null pointer when load rlc firmware

Thomas Zimmermann <[email protected]>
Revert "drivers/firmware: Move sysfb_init() from device_initcall to subsys_initcall_sync"

Cristian Marussi <[email protected]>
firmware: arm_scmi: Check mailbox/SMT channel for consistency

Lin Ma <[email protected]>
ksmbd: fix global oob in ksmbd_nl_policy

Shin'ichiro Kawasaki <[email protected]>
platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe

Nathan Chancellor <[email protected]>
platform/x86: intel-uncore-freq: Fix types in sysfs callbacks

Florian Westphal <[email protected]>
netfilter: nf_tables: reject QUEUE/DROP verdict parameters

Pablo Neira Ayuso <[email protected]>
netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress basechain

Michael Kelley <[email protected]>
hv_netvsc: Calculate correct ring size when PAGE_SIZE is not 4 Kbytes

Amir Goldstein <[email protected]>
ovl: mark xwhiteouts directory with overlay.opaque='x'

NeilBrown <[email protected]>
nfsd: fix RELEASE_LOCKOWNER

Emmanuel Grumbach <[email protected]>
wifi: iwlwifi: fix a memory corruption

Bernd Edlinger <[email protected]>
exec: Fix error handling in begin_new_exec()

Ilya Dryomov <[email protected]>
rbd: don't move requests to the running list on errors

Omar Sandoval <[email protected]>
btrfs: don't abort filesystem when attempting to snapshot deleted subvolume

Qu Wenruo <[email protected]>
btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args

David Sterba <[email protected]>
btrfs: don't warn if discard range is not aligned to sector

Chung-Chiang Cheng <[email protected]>
btrfs: tree-checker: fix inline ref size in error messages

Fedor Pchelkin <[email protected]>
btrfs: ref-verify: free ref cache before clearing mount opt

Omar Sandoval <[email protected]>
btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume being deleted

Naohiro Aota <[email protected]>
btrfs: zoned: fix lock ordering in btrfs_zone_activate()

Gerhard Engleder <[email protected]>
tsnep: Fix XDP_RING_NEED_WAKEUP for empty fill ring

Gerhard Engleder <[email protected]>
tsnep: Remove FCS for XDP data path

Shenwei Wang <[email protected]>
net: fec: fix the unhandled context fault from smmu

Hangbin Liu <[email protected]>
selftests: bonding: do not test arp/ns target with mode balance-alb/tlb

Zhipeng Lu <[email protected]>
fjes: fix memleaks in fjes_hw_setup

Maciej Fijalkowski <[email protected]>
i40e: update xdp_rxq_info::frag_size for ZC enabled Rx queue

Maciej Fijalkowski <[email protected]>
i40e: set xdp_rxq_info::frag_size

Maciej Fijalkowski <[email protected]>
xdp: reflect tail increase for MEM_TYPE_XSK_BUFF_POOL

Maciej Fijalkowski <[email protected]>
ice: update xdp_rxq_info::frag_size for ZC enabled Rx queue

Maciej Fijalkowski <[email protected]>
intel: xsk: initialize skb_frag_t::bv_offset in ZC drivers

Maciej Fijalkowski <[email protected]>
ice: remove redundant xdp_rxq_info registration

Tirthendu Sarkar <[email protected]>
i40e: handle multi-buffer packets that are shrunk by xdp prog

Maciej Fijalkowski <[email protected]>
ice: work on pre-XDP prog frag count

Maciej Fijalkowski <[email protected]>
xsk: fix usage of multi-buffer BPF helpers for ZC XDP

Maciej Fijalkowski <[email protected]>
xsk: make xsk_buff_pool responsible for clearing xdp_buff::flags

Maciej Fijalkowski <[email protected]>
xsk: recycle buffer in case Rx queue was full

Jakub Kicinski <[email protected]>
selftests: netdevsim: fix the udp_tunnel_nic test

Jakub Kicinski <[email protected]>
selftests: net: fix rps_default_mask with >32 CPUs

Jenishkumar Maheshbhai Patel <[email protected]>
net: mvpp2: clear BM pool before initialization

Bernd Edlinger <[email protected]>
net: stmmac: Wait a bit for the reset to take effect

Pablo Neira Ayuso <[email protected]>
netfilter: nf_tables: validate NFPROTO_* family

Florian Westphal <[email protected]>
netfilter: nf_tables: restrict anonymous set and map names to 16 bytes

Florian Westphal <[email protected]>
netfilter: nft_limit: reject configurations that cause integer overflow

Frederic Weisbecker <[email protected]>
rcu: Defer RCU kthreads wakeup when CPU is dying

Dinghao Liu <[email protected]>
net/mlx5e: fix a potential double-free in fs_any_create_groups

Zhipeng Lu <[email protected]>
net/mlx5e: fix a double-free in arfs_create_groups

Leon Romanovsky <[email protected]>
net/mlx5e: Ignore IPsec replay window values on sender side

Leon Romanovsky <[email protected]>
net/mlx5e: Allow software parsing when IPsec crypto is enabled

Rahul Rameshbabu <[email protected]>
net/mlx5: Use mlx5 device constant for selecting CQ period mode for ASO

Yevgeny Kliteynik <[email protected]>
net/mlx5: DR, Can't go to uplink vport on RX rule

Yevgeny Kliteynik <[email protected]>
net/mlx5: DR, Use the right GVMI number for drop action

Moshe Shemesh <[email protected]>
net/mlx5: Bridge, fix multicast packets sent to uplink

Yishai Hadas <[email protected]>
net/mlx5: Fix a WARN upon a callback command failure

Vlad Buslov <[email protected]>
net/mlx5e: Fix peer flow lists handling

Tariq Toukan <[email protected]>
net/mlx5e: Fix inconsistent hairpin RQT sizes

Rahul Rameshbabu <[email protected]>
net/mlx5e: Fix operation precedence bug in port timestamping napi_poll context

Ido Schimmel <[email protected]>
net/sched: flower: Fix chain template offload

Jakub Kicinski <[email protected]>
selftests: fill in some missing configs for net

Zhengchao Shao <[email protected]>
ipv6: init the accept_queue's spinlocks in inet6_create

Zhengchao Shao <[email protected]>
netlink: fix potential sleeping issue in mqueue_flush_file

Kuniyuki Iwashima <[email protected]>
selftest: Don't reuse port for SO_INCOMING_CPU test.

Salvatore Dipietro <[email protected]>
tcp: Add memory barrier to tcp_push()

David Howells <[email protected]>
afs: Fix error handling with lookup via FS.InlineBulkStatus

David Howells <[email protected]>
afs: Simplify error handling

David Howells <[email protected]>
afs: Don't put afs_call in afs_wait_for_call_to_complete()

David Howells <[email protected]>

    afs: Wrap most op->error accesses with inline funcs

David Howells <[email protected]>

    afs: Use op->nr_iterations=-1 to indicate to begin fileserver iteration

David Howells <[email protected]>
afs: Handle the VIO and UAEIO aborts explicitly

David Howells <[email protected]>
rxrpc, afs: Allow afs to pin rxrpc_peer objects

David Howells <[email protected]>
afs: Turn the afs_addr_list address array into an array of structs

David Howells <[email protected]>
afs: Add comments on abort handling

Oleg Nesterov <[email protected]>
afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*()

David Howells <[email protected]>
afs: Hide silly-rename files from userspace

Petr Pavlu <[email protected]>
tracing: Ensure visibility when inserting an element into tracing_map

Dan Carpenter <[email protected]>
netfs, fscache: Prevent Oops in fscache_put_cache()

Sharath Srinivasan <[email protected]>
net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv

Horatiu Vultur <[email protected]>
net: micrel: Fix PTP frame parsing for lan8814

Arkadiusz Kubalewski <[email protected]>
dpll: fix register pin with unregistered parent pin

Arkadiusz Kubalewski <[email protected]>
dpll: fix userspace availability of pins

Arkadiusz Kubalewski <[email protected]>
dpll: fix pin dump crash for rebound module

Arkadiusz Kubalewski <[email protected]>
dpll: fix broken error path in dpll_pin_alloc(..)

Yunjian Wang <[email protected]>
tun: add missing rx stats accounting in tun_xdp_act

Yunjian Wang <[email protected]>
tun: fix missing dropped counter in tun_xdp_act

Jakub Kicinski <[email protected]>
net: fix removing a namespace with conflicting altnames

Michal Schmidt <[email protected]>
idpf: distinguish vports by the dev_port attribute

Eric Dumazet <[email protected]>
udp: fix busy polling

Kuniyuki Iwashima <[email protected]>

    llc: Drop support for ETH_P_TR_802_2.

Eric Dumazet <[email protected]>
llc: make llc_ui_sendmsg() more robust against bonding changes

Lin Ma <[email protected]>
vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING

Michael Chan <[email protected]>
bnxt_en: Prevent kernel warning when running offline self test

Michael Chan <[email protected]>
bnxt_en: Wait for FLR to complete during probe

Zhengchao Shao <[email protected]>
tcp: make sure init the accept_queue's spinlocks once

Benjamin Poirier <[email protected]>
selftests: bonding: Increase timeout to 1200s

Wen Gu <[email protected]>
net/smc: fix illegal rmb_desc access in SMC-D connection dump

Qu Wenruo <[email protected]>
btrfs: scrub: avoid use-after-free when chunk length is not 64K aligned

Johannes Berg <[email protected]>
wifi: mac80211: fix potential sta-link leak

Lucas Stach <[email protected]>
SUNRPC: use request size to initialize bio_vec in svc_udp_sendto()

Namjae Jeon <[email protected]>
ksmbd: Add missing set_freezable() for freezable kthread

Namjae Jeon <[email protected]>
ksmbd: send lease break notification on FILE_RENAME_INFORMATION

Namjae Jeon <[email protected]>
ksmbd: don't increment epoch if current state and request state are same

Namjae Jeon <[email protected]>
ksmbd: fix potential circular locking issue in smb2_set_ea()

Jonathan Gray <[email protected]>
Revert "drm/amd: Enable PCIe PME from D3"

Benjamin Berg <[email protected]>
wifi: ath11k: rely on mac80211 debugfs handling for vif

Namjae Jeon <[email protected]>
ksmbd: set v2 lease version on lease upgrade

Charan Teja Kalla <[email protected]>
mm: page_alloc: unreserve highatomic page blocks before oom

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: improve do/while loop in sc16is7xx_irq()

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq()

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: fix invalid sc16is7xx_lines bitfield in case of probe error

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: fix unconditional activation of THRI interrupt

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: change EFR lock to operate on each channels

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove unused line structure member

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove global regmap from struct sc16is7xx_port

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name()

Hugo Villeneuve <[email protected]>
serial: sc16is7xx: improve regmap debugfs by using one regmap per port

Al Viro <[email protected]>
rename(): fix the locking of subdirectories

Charan Teja Kalla <[email protected]>

    mm/sparsemem: fix race in accessing memory_section->usage

Baolin Wang <[email protected]>
mm: migrate: fix getting incorrect page mapping during page migration

Steven Rostedt (Google) <[email protected]>
mm/rmap: fix misplaced parenthesis of a likely()

Donet Tom <[email protected]>
selftests: mm: hugepage-vmemmap fails on 64K page size systems

James Gowans <[email protected]>
kexec: do syscore_shutdown() in kernel_kexec

Muhammad Usama Anjum <[email protected]>
fs/proc/task_mmu: move mmu notification mechanism inside mm lock

Di Shen <[email protected]>
thermal: gov_power_allocator: avoid inability to reset a cdev

Zhihao Cheng <[email protected]>

    ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path

Huacai Chen <[email protected]>
kdump: defer the insertion of crashkernel resources

Ma Wupeng <[email protected]>
efi: disable mirror feature during crashkernel

Dave Airlie <[email protected]>
nouveau/gsp: handle engines in runl without nonstall interrupts.

Dave Airlie <[email protected]>
nouveau/vmm: don't set addr on the fail path to avoid warning

Mario Limonciello <[email protected]>
rtc: Extend timeout for waiting for UIP to clear to 1s

Mario Limonciello <[email protected]>
rtc: Add support for configuring the UIP timeout for RTC reads

Mario Limonciello <[email protected]>

    rtc: mc146818-lib: Adjust failure return code for mc146818_get_time()

Mario Limonciello <[email protected]>
rtc: Adjust failure return code for cmos_set_alarm()

Mario Limonciello <[email protected]>
rtc: cmos: Use ACPI alarm for non-Intel x86 systems too

Mark Rutland <[email protected]>
arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD

Mark Brown <[email protected]>
arm64/sme: Always exit sme_alloc() early with existing storage

Rob Herring <[email protected]>
arm64: errata: Add Cortex-A510 speculative unprivileged load workaround

Rob Herring <[email protected]>

    arm64: Rename ARM64_WORKAROUND_2966298

Andrew Jones <[email protected]>
RISC-V: selftests: cbo: Ensure asm operands match constraints

Guo Ren <[email protected]>
riscv: mm: Fixup compat mode boot failure

Guo Ren <[email protected]>
riscv: mm: Fixup compat arch_get_mmap_end

Zheng Wang <[email protected]>
media: mtk-jpeg: Fix use after free bug due to error path handling in mtk_jpeg_dec_device_run

Zheng Wang <[email protected]>
media: mtk-jpeg: Fix timeout schedule error in mtk_jpegdec_worker.

Alain Volmat <[email protected]>
media: i2c: st-mipid02: correct format propagation

Andy Shevchenko <[email protected]>
mmc: mmc_spi: remove custom DMA mapped buffers

Avri Altman <[email protected]>
mmc: core: Use mrq.sbc in close-ended ffu

Michael Grzeschik <[email protected]>
media: videobuf2-dma-sg: fix vmap callback

Vegard Nossum <[email protected]>
scripts/get_abi: fix source path leak

Vegard Nossum <[email protected]>
docs: kernel_abi.py: fix command injection

Jordan Rife <[email protected]>
dlm: use kernel_connect() and kernel_bind()

Alfred Piccioni <[email protected]>
lsm: new security_file_ioctl_compat() hook

Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix USB SS wakeup

Johan Hovold <[email protected]>
arm64: dts: qcom: sdm670: fix USB SS wakeup

Johan Hovold <[email protected]>
arm64: dts: qcom: sdm670: fix USB DP/DM HS PHY interrupts

Johan Hovold <[email protected]>

    arm64: dts: qcom: sc8180x: fix USB SS wakeup

Johan Hovold <[email protected]>

    arm64: dts: qcom: sc8180x: fix USB DP/DM HS PHY interrupts

Johan Hovold <[email protected]>
arm64: dts: qcom: sm8150: fix USB SS wakeup

Johan Hovold <[email protected]>
arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts

Johan Hovold <[email protected]>
arm64: dts: qcom: sdm845: fix USB SS wakeup

Johan Hovold <[email protected]>
arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts

Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix USB DP/DM HS PHY interrupts

Stephan Gerhold <[email protected]>
arm64: dts: qcom: Add missing vio-supply for AW2013

Johan Hovold <[email protected]>
arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types

Johan Hovold <[email protected]>

    arm64: dts: qcom: sc8180x: fix USB wakeup interrupt types

Johan Hovold <[email protected]>
arm64: dts: qcom: sm8150: fix USB wakeup interrupt types

Johan Hovold <[email protected]>
arm64: dts: qcom: sdm670: fix USB wakeup interrupt types

Johan Hovold <[email protected]>
arm64: dts: qcom: sdm845: fix USB wakeup interrupt types

Johan Hovold <[email protected]>
arm64: dts: qcom: sc7180: fix USB wakeup interrupt types

Stephan Gerhold <[email protected]>
arm64: dts: qcom: msm8939: Make blsp_dma controlled-remotely

Stephan Gerhold <[email protected]>
arm64: dts: qcom: msm8916: Make blsp_dma controlled-remotely

Sam Edwards <[email protected]>
arm64: dts: rockchip: Fix rk3588 USB power-domain clocks

Tianling Shen <[email protected]>
arm64: dts: rockchip: configure eth pad driver strength for orangepi r1 plus lts

Cixi Geng <[email protected]>
arm64: dts: sprd: fix the cpu node for UMS512

Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix pdc '#interrupt-cells'

Paul Cercueil <[email protected]>
ARM: dts: samsung: exynos4210-i9100: Unconditionally enable LDO12

Johan Hovold <[email protected]>
ARM: dts: qcom: sdx55: fix USB wakeup interrupt types

Johan Hovold <[email protected]>

    arm64: dts: qcom: sc8280xp-crd: fix eDP phy compatible

Andrejs Cainikovs <[email protected]>
ARM: dts: imx6q-apalis: add can power-up delay on ixora board

Shyam Prasad N <[email protected]>
cifs: update iface_last_update on each query-and-update

Shyam Prasad N <[email protected]>
cifs: handle servers that still advertise multichannel after disabling

Paulo Alcantara <[email protected]>
smb: client: fix parsing of SMB3.1.1 POSIX create context

Geert Uytterhoeven <[email protected]>
sh: ecovec24: Rename missed backlight field from fbdev to dev

Niklas Cassel <[email protected]>
scsi: core: Kick the requeue list after inserting when flushing

Christophe JAILLET <[email protected]>
riscv: Fix an off-by-one in get_early_cmdline()

Charlie Jenkins <[email protected]>
riscv: Fix relocation_hashtable size

Charlie Jenkins <[email protected]>
riscv: Correctly free relocation hashtable on error

Charlie Jenkins <[email protected]>
riscv: Fix module loading free order

Bart Van Assche <[email protected]>
scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan()

Miquel Raynal <[email protected]>
dmaengine: xilinx: xdma: Fix the count of elapsed periods in cyclic mode

Rex Zhang <[email protected]>
dmaengine: idxd: Move dma_free_coherent() out of spinlocked context

Amelie Delaunay <[email protected]>
dmaengine: fix NULL pointer in channel unregistration function

Frank Li <[email protected]>
dmaengine: fsl-edma: fix eDMAv4 channel allocation issue

Marcelo Schmitt <[email protected]>
iio: adc: ad7091r: Enable internal vref if external vref is not supplied

Helge Deller <[email protected]>
parisc/power: Fix power soft-off button emulation on qemu

Helge Deller <[email protected]>
parisc/firmware: Fix F-extend for PDC addresses

Bhaumik Bhatt <[email protected]>
bus: mhi: host: Add spinlock to protect WP access when queueing TREs

Qiang Yu <[email protected]>
bus: mhi: host: Drop chan lock before queuing buffers

Krishna chaitanya chundru <[email protected]>
bus: mhi: host: Add alignment check for event ring read pointer

Serge Semin <[email protected]>
mips: Fix max_mapnr being uninitialized on early stages

Eric Dumazet <[email protected]>
nbd: always initialize struct msghdr completely

Nathan Lynch <[email protected]>
seq_buf: Make DECLARE_SEQ_BUF() usable

Tony Krowiak <[email protected]>
s390/vfio-ap: do not reset queue removed from host config

Tony Krowiak <[email protected]>
s390/vfio-ap: reset queues associated with adapter for queue unbound from driver

Tony Krowiak <[email protected]>
s390/vfio-ap: reset queues filtered from the guest's AP config

Tony Krowiak <[email protected]>
s390/vfio-ap: let on_scan_complete() callback filter matrix and update guest's APCB

Tony Krowiak <[email protected]>
s390/vfio-ap: loop over the shadow APCB when filtering guest's AP configuration

Tony Krowiak <[email protected]>
s390/vfio-ap: always filter entire AP matrix

Herve Codina <[email protected]>
soc: fsl: cpm1: qmc: Fix rx channel reset

Herve Codina <[email protected]>
soc: fsl: cpm1: qmc: Fix __iomem addresses declaration

Herve Codina <[email protected]>
soc: fsl: cpm1: tsa: Fix __iomem addresses declaration

Bingbu Cao <[email protected]>
media: ov01a10: Enable runtime PM before registering async sub-device

Bingbu Cao <[email protected]>
media: ov13b10: Enable runtime PM before registering async sub-device

Bingbu Cao <[email protected]>
media: ov9734: Enable runtime PM before registering async sub-device

Xiaolei Wang <[email protected]>
rpmsg: virtio: Free driver_override when rpmsg_remove()

Bingbu Cao <[email protected]>
media: imx355: Enable runtime PM before registering async sub-device

Johan Hovold <[email protected]>
soc: qcom: pmic_glink_altmode: fix port sanity check

Miquel Raynal <[email protected]>
mtd: rawnand: Clarify conditions to enable continuous reads

Miquel Raynal <[email protected]>
mtd: rawnand: Prevent sequential reads with on-die ECC engines

Miquel Raynal <[email protected]>
mtd: rawnand: Fix core interference with sequential reads

Miquel Raynal <[email protected]>
mtd: rawnand: Prevent crossing LUN boundaries during sequential reads

Miquel Raynal <[email protected]>
mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters

Christian Marangi <[email protected]>
PM / devfreq: Fix buffer overflow in trans_stat_show

Anthony Krowiak <[email protected]>
s390/vfio-ap: unpin pages on gisc registration failure

Herbert Xu <[email protected]>
crypto: s390/aes - Fix buffer overread in CTR mode

Herbert Xu <[email protected]>
hwrng: core - Fix page fault dead lock on mmap-ed hwrng

Hongchen Zhang <[email protected]>
PM: hibernate: Enforce ordering during image compression/decompression

Herbert Xu <[email protected]>
crypto: api - Disallow identical driver names

Gao Xiang <[email protected]>
erofs: fix lz4 inplace decompression

Tianjia Zhang <[email protected]>
crypto: lib/mpi - Fix unexpected pointer access in mpi_ec_init

David Disseldorp <[email protected]>
btrfs: sysfs: validate scrub_speed_max value

Viresh Kumar <[email protected]>
OPP: Pass rounded rate to _set_opp()

Josef Bacik <[email protected]>
arm64: properly install vmlinuz.efi

Rafael J. Wysocki <[email protected]>
PM: sleep: Fix possible deadlocks in core system-wide PM code

Rafael J. Wysocki <[email protected]>
async: Introduce async_schedule_dev_nocall()

Rafael J. Wysocki <[email protected]>
async: Split async_schedule_node_domain()

Suraj Jitindar Singh <[email protected]>
ext4: allow for the last group to be marked as trimmed

Geoff Levand <[email protected]>
powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2

Lukas Schauer <[email protected]>
pipe: wakeup wr_wait after setting max_usage

Marcelo Schmitt <[email protected]>
iio: adc: ad7091r: Allow users to configure device events

Marcelo Schmitt <[email protected]>
iio: adc: ad7091r: Set alert bit in config register

Krzysztof Kozlowski <[email protected]>
soundwire: fix initializing sysfs for same devices on different buses

Pierre-Louis Bossart <[email protected]>
soundwire: bus: introduce controller_id

-------------

Diffstat:

 Documentation/ABI/testing/sysfs-class-devfreq      |   3 +
 Documentation/admin-guide/abi-obsolete.rst         |   2 +-
 Documentation/admin-guide/abi-removed.rst          |   2 +-
 Documentation/admin-guide/abi-stable.rst           |   2 +-
 Documentation/admin-guide/abi-testing.rst          |   2 +-
 Documentation/arch/arm64/silicon-errata.rst        |   2 +
 Documentation/filesystems/directory-locking.rst    |  29 +-
 Documentation/filesystems/locking.rst              |   5 +-
 Documentation/filesystems/overlayfs.rst            |  16 +-
 Documentation/filesystems/porting.rst              |  18 ++
 Documentation/gpu/drm-kms.rst                      |   2 +
 Documentation/gpu/todo.rst                         |   7 +-
 Documentation/sphinx/kernel_abi.py                 |  56 +---
 Makefile                                           |   4 +-
 arch/alpha/kernel/rtc.c                            |   2 +-
 .../boot/dts/nxp/imx/imx6q-apalis-ixora-v1.2.dts   |   2 +
 arch/arm/boot/dts/qcom/qcom-sdx55.dtsi             |  10 +-
 arch/arm/boot/dts/samsung/exynos4210-i9100.dts     |   8 +
 arch/arm/boot/dts/samsung/exynos4212-tab3.dtsi     |   1 +
 arch/arm64/Kconfig                                 |  18 ++
 .../boot/dts/qcom/msm8916-longcheer-l8150.dts      |   1 +
 .../boot/dts/qcom/msm8916-wingtech-wt88047.dts     |   1 +
 arch/arm64/boot/dts/qcom/msm8916.dtsi              |   1 +
 arch/arm64/boot/dts/qcom/msm8939.dtsi              |   1 +
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts   |   1 +
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts |   1 +
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts  |   1 +
 arch/arm64/boot/dts/qcom/sc7180.dtsi               |   4 +-
 arch/arm64/boot/dts/qcom/sc7280.dtsi               |   4 +-
 arch/arm64/boot/dts/qcom/sc8180x.dtsi              |  16 +-
 arch/arm64/boot/dts/qcom/sc8280xp-crd.dts          |   2 +
 arch/arm64/boot/dts/qcom/sdm670.dtsi               |   8 +-
 arch/arm64/boot/dts/qcom/sdm845.dtsi               |  16 +-
 arch/arm64/boot/dts/qcom/sm8150.dtsi               |  16 +-
 .../dts/rockchip/rk3328-orangepi-r1-plus-lts.dts   |   4 +-
 arch/arm64/boot/dts/rockchip/rk3588s.dtsi          |   1 +
 arch/arm64/boot/dts/sprd/ums512.dtsi               |   4 +-
 arch/arm64/boot/install.sh                         |   3 +-
 arch/arm64/kernel/cpu_errata.c                     |  21 +-
 arch/arm64/kernel/entry.S                          |  22 +-
 arch/arm64/kernel/fpsimd.c                         |   6 +-
 arch/arm64/tools/cpucaps                           |   2 +-
 arch/loongarch/kernel/smp.c                        |   1 -
 arch/loongarch/mm/tlb.c                            |  16 +-
 arch/mips/kernel/elf.c                             |   6 +
 arch/mips/lantiq/prom.c                            |   7 +-
 arch/mips/mm/init.c                                |  12 +-
 arch/parisc/kernel/firmware.c                      |   4 +-
 arch/powerpc/configs/ps3_defconfig                 |   1 +
 arch/riscv/boot/dts/sophgo/sg2042.dtsi             |  80 +++--
 arch/riscv/include/asm/pgtable.h                   |   2 +-
 arch/riscv/include/asm/processor.h                 |   2 +-
 arch/riscv/kernel/module.c                         |  14 +-
 arch/riscv/kernel/pi/cmdline_early.c               |   3 +-
 arch/s390/crypto/aes_s390.c                        |   4 +-
 arch/s390/crypto/paes_s390.c                       |   4 +-
 arch/sh/boards/mach-ecovec24/setup.c               |   2 +-
 arch/x86/include/asm/syscall_wrapper.h             |  25 +-
 arch/x86/kernel/hpet.c                             |   2 +-
 arch/x86/kernel/rtc.c                              |   2 +-
 block/ioctl.c                                      |   2 -
 block/partitions/core.c                            |   5 +
 crypto/algapi.c                                    |   1 +
 drivers/base/power/main.c                          | 148 ++++-----
 drivers/base/power/trace.c                         |   2 +-
 drivers/block/nbd.c                                |   6 +-
 drivers/block/rbd.c                                |  22 +-
 drivers/bus/mhi/host/main.c                        |  29 +-
 drivers/char/hw_random/core.c                      |  34 +-
 drivers/cpufreq/amd-pstate.c                       |   7 +-
 drivers/cpufreq/intel_pstate.c                     |  55 ++--
 drivers/cxl/core/region.c                          |   4 +-
 drivers/devfreq/devfreq.c                          |  57 ++--
 drivers/dma/dmaengine.c                            |   3 +
 drivers/dma/fsl-edma-main.c                        |   8 +
 drivers/dma/idxd/device.c                          |   9 +-
 drivers/dma/xilinx/xdma.c                          |   6 +-
 drivers/dpll/dpll_core.c                           |  68 +++-
 drivers/dpll/dpll_core.h                           |   4 +-
 drivers/dpll/dpll_netlink.c                        |  57 +++-
 drivers/firmware/arm_ffa/driver.c                  |  12 +
 drivers/firmware/arm_scmi/clock.c                  |   3 +-
 drivers/firmware/arm_scmi/common.h                 |   1 +
 drivers/firmware/arm_scmi/mailbox.c                |  14 +
 drivers/firmware/arm_scmi/perf.c                   |  23 +-
 drivers/firmware/arm_scmi/raw_mode.c               |  12 +-
 drivers/firmware/arm_scmi/shmem.c                  |   6 +
 drivers/firmware/sysfb.c                           |   2 +-
 drivers/gpio/gpio-eic-sprd.c                       |  32 +-
 drivers/gpio/gpiolib-acpi.c                        |  14 +
 drivers/gpu/drm/amd/amdgpu/amdgpu.h                |   1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c         |   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c      |   2 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c            |   5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c           |   8 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c           |  10 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c       |  17 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c             |  20 +-
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c             |  10 +-
 drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c              |   3 +-
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c   |   1 +
 drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c   |   1 +
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c  |   9 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c  |   6 +-
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c  |   5 +
 .../gpu/drm/amd/display/dc/bios/command_table2.c   |  12 +-
 .../amd/display/dc/clk_mgr/dcn31/dcn31_clk_mgr.c   |   2 +-
 .../amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c |  23 +-
 .../amd/display/dc/clk_mgr/dcn315/dcn315_clk_mgr.c |   2 +-
 .../amd/display/dc/clk_mgr/dcn316/dcn316_clk_mgr.c |   2 +-
 .../amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c   |   2 +-
 drivers/gpu/drm/amd/display/dc/core/dc.c           |  16 +-
 .../gpu/drm/amd/display/dc/core/dc_hw_sequencer.c  |   2 +-
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c  |  19 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c       | 176 ++++++++--
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.h       |  59 +++-
 drivers/gpu/drm/amd/display/dc/dc_helper.c         |   6 +-
 drivers/gpu/drm/amd/display/dc/dce/dmub_abm_lcd.c  |  14 +-
 .../gpu/drm/amd/display/dc/dce/dmub_hw_lock_mgr.c  |   2 +-
 drivers/gpu/drm/amd/display/dc/dce/dmub_outbox.c   |   2 +-
 drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c      |  33 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.c  |  16 +-
 .../gpu/drm/amd/display/dc/dcn20/dcn20_resource.h  |   1 +
 drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c  |   2 +-
 .../amd/display/dc/dcn31/dcn31_dio_link_encoder.c  |   4 +-
 .../drm/amd/display/dc/dcn31/dcn31_panel_cntl.c    |   4 +-
 drivers/gpu/drm/amd/display/dc/dcn32/dcn32_optc.c  |  17 +
 .../gpu/drm/amd/display/dc/dcn32/dcn32_resource.c  |   1 +
 .../drm/amd/display/dc/dcn321/dcn321_resource.c    |   1 +
 drivers/gpu/drm/amd/display/dc/dcn35/dcn35_optc.c  |  10 +
 .../gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c   |   6 +-
 .../drm/amd/display/dc/dml2/display_mode_core.c    |  30 +-
 .../amd/display/dc/dml2/dml2_translation_helper.c  |   2 +-
 .../drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c    |   4 +-
 .../drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c    |   8 +-
 .../drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c    |   4 +-
 .../drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c    |   6 +-
 .../drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c    |   8 +-
 drivers/gpu/drm/amd/display/dc/inc/core_types.h    |   1 +
 drivers/gpu/drm/amd/display/dc/link/link_dpms.c    |   8 +-
 .../display/dc/link/protocols/link_dp_capability.c |   2 +-
 .../amd/display/dc/link/protocols/link_dp_dpia.c   |   3 +-
 .../drm/amd/display/dc/link/protocols/link_dpcd.c  |   4 +-
 .../dc/link/protocols/link_edp_panel_control.c     |  11 +-
 drivers/gpu/drm/amd/display/dmub/dmub_srv.h        |  21 ++
 drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c    |  15 +
 .../drm/amd/display/modules/power/power_helpers.c  |   2 +
 drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c          |  14 +-
 drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c     |   2 +
 drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c     |   2 +
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c   |  54 +++-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c   |  15 +-
 .../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c   |  54 +++-
 drivers/gpu/drm/bridge/analogix/anx7625.c          |   7 +-
 drivers/gpu/drm/bridge/analogix/anx7625.h          |   2 +
 drivers/gpu/drm/bridge/nxp-ptn3460.c               |   6 +-
 drivers/gpu/drm/bridge/parade-ps8640.c             |  23 ++
 drivers/gpu/drm/bridge/samsung-dsim.c              |  32 +-
 drivers/gpu/drm/bridge/sii902x.c                   |  42 ++-
 drivers/gpu/drm/drm_damage_helper.c                |   3 +-
 drivers/gpu/drm/drm_plane.c                        |  14 +
 drivers/gpu/drm/exynos/exynos5433_drm_decon.c      |   4 +-
 drivers/gpu/drm/exynos/exynos_drm_fimd.c           |   4 +-
 drivers/gpu/drm/exynos/exynos_drm_gsc.c            |   2 +-
 drivers/gpu/drm/i915/display/icl_dsi.c             |   3 +-
 drivers/gpu/drm/i915/display/intel_psr.c           |  14 +-
 drivers/gpu/drm/nouveau/nouveau_fence.c            |  28 +-
 drivers/gpu/drm/nouveau/nouveau_fence.h            |   5 +-
 drivers/gpu/drm/nouveau/nouveau_vmm.c              |   3 +
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c   |   4 +
 drivers/gpu/drm/nouveau/nvkm/engine/fifo/r535.c    |   2 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c     |   8 +-
 drivers/gpu/drm/panel/Kconfig                      |   2 +
 drivers/gpu/drm/panel/panel-edp.c                  |   7 +-
 drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c      |   2 +-
 drivers/gpu/drm/panel/panel-simple.c               |   2 +
 drivers/gpu/drm/qxl/qxl_drv.c                      |   2 +-
 drivers/gpu/drm/tidss/tidss_crtc.c                 |  10 +-
 drivers/gpu/drm/vboxvideo/vbox_drv.c               |   2 +-
 drivers/gpu/drm/virtio/virtgpu_drv.c               |   2 +-
 drivers/gpu/drm/virtio/virtgpu_plane.c             |  10 +
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c                |   2 +-
 drivers/iio/adc/ad7091r-base.c                     | 169 ++++++++++
 drivers/iio/adc/ad7091r-base.h                     |   8 +
 drivers/iio/adc/ad7091r5.c                         |  28 +-
 drivers/media/common/videobuf2/videobuf2-dma-sg.c  |  10 +-
 drivers/media/i2c/imx290.c                         |  42 +--
 drivers/media/i2c/imx355.c                         |  12 +-
 drivers/media/i2c/ov01a10.c                        |  18 +-
 drivers/media/i2c/ov13b10.c                        |  14 +-
 drivers/media/i2c/ov9734.c                         |  19 +-
 drivers/media/i2c/st-mipid02.c                     |   9 +-
 .../media/platform/mediatek/jpeg/mtk_jpeg_core.c   |  12 +-
 drivers/media/v4l2-core/v4l2-cci.c                 |  52 ++-
 drivers/mmc/core/block.c                           |  46 ++-
 drivers/mmc/host/mmc_spi.c                         | 186 +----------
 drivers/mtd/maps/vmu-flash.c                       |   2 +-
 drivers/mtd/nand/raw/nand_base.c                   |  87 ++++-
 drivers/net/ethernet/broadcom/bnxt/bnxt.c          |   8 +
 drivers/net/ethernet/engleder/tsnep_main.c         |  17 +-
 drivers/net/ethernet/freescale/fec_main.c          |   2 +
 drivers/net/ethernet/intel/i40e/i40e_main.c        |  47 ++-
 drivers/net/ethernet/intel/i40e/i40e_txrx.c        |  49 ++-
 drivers/net/ethernet/intel/i40e/i40e_xsk.c         |   4 +-
 drivers/net/ethernet/intel/ice/ice_base.c          |  37 ++-
 drivers/net/ethernet/intel/ice/ice_txrx.c          |  19 +-
 drivers/net/ethernet/intel/ice/ice_txrx.h          |   1 +
 drivers/net/ethernet/intel/ice/ice_txrx_lib.h      |  31 +-
 drivers/net/ethernet/intel/ice/ice_xsk.c           |   4 +-
 drivers/net/ethernet/intel/idpf/idpf_lib.c         |   2 +
 drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c    |  27 +-
 drivers/net/ethernet/mellanox/mlx5/core/cmd.c      |   5 +-
 .../mellanox/mlx5/core/en/fs_tt_redirect.c         |   1 +
 .../net/ethernet/mellanox/mlx5/core/en/params.c    |   4 +-
 drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c   |   2 +-
 .../ethernet/mellanox/mlx5/core/en_accel/ipsec.c   |  10 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c  |  26 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c    |   5 +-
 .../ethernet/mellanox/mlx5/core/esw/bridge_mcast.c |   3 +
 drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c   |   2 +
 drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c  |   2 +-
 .../mellanox/mlx5/core/steering/dr_action.c        |  17 +-
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  |   3 +
 drivers/net/fjes/fjes_hw.c                         |  37 ++-
 drivers/net/hyperv/netvsc_drv.c                    |   4 +-
 drivers/net/phy/micrel.c                           |  11 +
 drivers/net/tun.c                                  |  10 +-
 drivers/net/wireless/ath/ath11k/core.h             |   4 -
 drivers/net/wireless/ath/ath11k/debugfs.c          |  25 +-
 drivers/net/wireless/ath/ath11k/debugfs.h          |  12 +-
 drivers/net/wireless/ath/ath11k/mac.c              |  12 +-
 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c   |   4 +-
 drivers/opp/core.c                                 |   6 +-
 drivers/parisc/power.c                             |   2 +-
 drivers/platform/mellanox/mlxbf-pmc.c              |   4 +-
 drivers/platform/x86/intel/ifs/load.c              |   3 +-
 .../uncore-frequency/uncore-frequency-common.c     |  82 ++---
 .../uncore-frequency/uncore-frequency-common.h     |  32 +-
 drivers/platform/x86/p2sb.c                        | 180 ++++++++---
 drivers/platform/x86/wmi.c                         |  16 +-
 drivers/rpmsg/virtio_rpmsg_bus.c                   |   1 +
 drivers/rtc/rtc-cmos.c                             |  28 +-
 drivers/rtc/rtc-mc146818-lib.c                     |  39 ++-
 drivers/s390/crypto/vfio_ap_ops.c                  | 269 ++++++++++------
 drivers/s390/crypto/vfio_ap_private.h              |   3 +
 drivers/scsi/scsi_error.c                          |   9 +-
 drivers/soc/fsl/qe/qmc.c                           |  35 +-
 drivers/soc/fsl/qe/tsa.c                           |  22 +-
 drivers/soc/qcom/pmic_glink_altmode.c              |   4 +-
 drivers/soundwire/amd_manager.c                    |   8 +
 drivers/soundwire/bus.c                            |   4 +
 drivers/soundwire/debugfs.c                        |   2 +-
 drivers/soundwire/intel_auxdevice.c                |   3 +
 drivers/soundwire/master.c                         |   2 +-
 drivers/soundwire/qcom.c                           |   3 +
 drivers/soundwire/slave.c                          |  12 +-
 drivers/spi/spi-bcm-qspi.c                         |   4 +-
 drivers/spi/spi-cadence.c                          |  17 +-
 drivers/spi/spi-intel-pci.c                        |   1 -
 drivers/spi/spi.c                                  |   4 +
 drivers/thermal/gov_power_allocator.c              |   2 +-
 drivers/thermal/intel/intel_hfi.c                  | 106 +++++--
 drivers/tty/serial/sc16is7xx.c                     | 353 +++++++++++----------
 drivers/ufs/core/ufshcd.c                          |   7 +-
 fs/afs/addr_list.c                                 | 133 ++++----
 fs/afs/cmservice.c                                 |   5 +-
 fs/afs/dir.c                                       |  70 ++--
 fs/afs/dir_silly.c                                 |   2 +-
 fs/afs/file.c                                      |   7 +-
 fs/afs/fs_operation.c                              |  54 ++--
 fs/afs/fs_probe.c                                  |  11 +-
 fs/afs/fsclient.c                                  |   8 +-
 fs/afs/inode.c                                     |   2 +-
 fs/afs/internal.h                                  |  88 +++--
 fs/afs/misc.c                                      |  10 +-
 fs/afs/proc.c                                      |   9 +-
 fs/afs/rotate.c                                    | 224 +++++++++----
 fs/afs/rxrpc.c                                     | 100 +++---
 fs/afs/server.c                                    |  53 +---
 fs/afs/vl_alias.c                                  |  57 +---
 fs/afs/vl_list.c                                   |  15 +-
 fs/afs/vl_probe.c                                  |  19 +-
 fs/afs/vl_rotate.c                                 |  98 +++---
 fs/afs/vlclient.c                                  |  98 ++++--
 fs/afs/write.c                                     |   6 +-
 fs/btrfs/extent-tree.c                             |  53 +++-
 fs/btrfs/inode.c                                   |  22 +-
 fs/btrfs/ioctl.c                                   |   7 +
 fs/btrfs/ref-verify.c                              |   6 +-
 fs/btrfs/scrub.c                                   |  29 +-
 fs/btrfs/sysfs.c                                   |   4 +
 fs/btrfs/tree-checker.c                            |   2 +-
 fs/btrfs/zoned.c                                   |   8 +-
 fs/dlm/lowcomms.c                                  |  14 +-
 fs/erofs/decompressor.c                            |  31 +-
 fs/exec.c                                          |   3 +
 fs/ext4/mballoc.c                                  |  15 +-
 fs/fscache/cache.c                                 |   3 +-
 fs/ioctl.c                                         |   3 +-
 fs/namei.c                                         |  60 ++--
 fs/nfsd/nfs4state.c                                |  26 +-
 fs/overlayfs/namei.c                               |  43 ++-
 fs/overlayfs/overlayfs.h                           |  23 +-
 fs/overlayfs/ovl_entry.h                           |   4 +-
 fs/overlayfs/readdir.c                             |   7 +-
 fs/overlayfs/super.c                               |  15 +
 fs/overlayfs/util.c                                |  53 ++--
 fs/pipe.c                                          |   7 +-
 fs/proc/task_mmu.c                                 |  24 +-
 fs/smb/client/smb2ops.c                            |  10 +-
 fs/smb/client/smb2pdu.c                            | 108 ++++---
 fs/smb/server/connection.c                         |   1 +
 fs/smb/server/ksmbd_netlink.h                      |   3 +-
 fs/smb/server/oplock.c                             |  16 +-
 fs/smb/server/smb2pdu.c                            |   8 +-
 fs/smb/server/transport_ipc.c                      |   4 +-
 fs/ubifs/dir.c                                     |   2 +
 fs/xfs/xfs_super.c                                 |  27 +-
 include/drm/drm_drv.h                              |   9 +
 include/drm/drm_file.h                             |  12 +
 include/drm/drm_plane.h                            |  10 +
 include/linux/async.h                              |   2 +
 include/linux/lsm_hook_defs.h                      |   2 +
 include/linux/mc146818rtc.h                        |   3 +-
 include/linux/mlx5/fs.h                            |   1 +
 include/linux/mlx5/mlx5_ifc.h                      |   2 +-
 include/linux/mmzone.h                             |  14 +-
 include/linux/mtd/rawnand.h                        |   2 +
 include/linux/rmap.h                               |   4 +-
 include/linux/security.h                           |   9 +
 include/linux/seq_buf.h                            |   3 +-
 include/linux/skmsg.h                              |   6 -
 include/linux/soundwire/sdw.h                      |   4 +-
 include/linux/syscalls.h                           |   1 +
 include/media/v4l2-cci.h                           |  11 +
 include/net/af_rxrpc.h                             |  15 +-
 include/net/inet_connection_sock.h                 |   8 +
 include/net/inet_sock.h                            |   5 -
 include/net/llc_pdu.h                              |   6 +-
 include/net/sch_generic.h                          |   4 +
 include/net/sock.h                                 |  18 +-
 include/net/xdp_sock_drv.h                         |  27 ++
 include/trace/events/afs.h                         |  25 ++
 include/trace/events/rxrpc.h                       |   3 +
 include/uapi/linux/btrfs.h                         |   3 +
 kernel/async.c                                     |  85 +++--
 kernel/crash_core.c                                |  14 +-
 kernel/futex/core.c                                |  15 +-
 kernel/futex/pi.c                                  |  11 +-
 kernel/irq/irqdesc.c                               |   2 +-
 kernel/kexec_core.c                                |   1 +
 kernel/power/swap.c                                |  38 +--
 kernel/rcu/tree.c                                  |  34 +-
 kernel/rcu/tree_exp.h                              |   3 +-
 kernel/time/clocksource.c                          |  25 +-
 kernel/time/tick-sched.c                           |   5 +
 kernel/trace/tracing_map.c                         |   7 +-
 lib/crypto/mpi/ec.c                                |   3 +
 mm/memblock.c                                      |   3 +
 mm/migrate.c                                       |  27 +-
 mm/mm_init.c                                       |   6 +
 mm/page_alloc.c                                    |  16 +-
 mm/sparse.c                                        |  17 +-
 net/8021q/vlan_netlink.c                           |   4 +
 net/core/dev.c                                     |   9 +
 net/core/dev.h                                     |   3 +
 net/core/filter.c                                  |  44 ++-
 net/core/request_sock.c                            |   3 -
 net/core/sock.c                                    |  11 +-
 net/ipv4/af_inet.c                                 |   3 +
 net/ipv4/inet_connection_sock.c                    |   4 +
 net/ipv4/tcp.c                                     |   1 +
 net/ipv6/af_inet6.c                                |   3 +
 net/llc/af_llc.c                                   |  24 +-
 net/llc/llc_core.c                                 |   7 -
 net/mac80211/sta_info.c                            |   5 +-
 net/netfilter/nf_tables_api.c                      |  20 +-
 net/netfilter/nft_chain_filter.c                   |  11 +-
 net/netfilter/nft_compat.c                         |  12 +
 net/netfilter/nft_flow_offload.c                   |   5 +
 net/netfilter/nft_limit.c                          |  23 +-
 net/netfilter/nft_nat.c                            |   5 +
 net/netfilter/nft_rt.c                             |   5 +
 net/netfilter/nft_socket.c                         |   5 +
 net/netfilter/nft_synproxy.c                       |   7 +-
 net/netfilter/nft_tproxy.c                         |   5 +
 net/netfilter/nft_xfrm.c                           |   5 +
 net/netlink/af_netlink.c                           |   2 +-
 net/rds/af_rds.c                                   |   2 +-
 net/rxrpc/af_rxrpc.c                               |  62 +++-
 net/rxrpc/ar-internal.h                            |   2 +-
 net/rxrpc/call_object.c                            |  17 +-
 net/rxrpc/peer_object.c                            |  58 ++--
 net/rxrpc/sendmsg.c                                |  11 +-
 net/sched/cls_api.c                                |   9 +-
 net/sched/cls_flower.c                             |  23 ++
 net/smc/smc_diag.c                                 |   2 +-
 net/sunrpc/svcsock.c                               |   4 +-
 net/xdp/xsk.c                                      |  12 +-
 net/xdp/xsk_buff_pool.c                            |   1 +
 scripts/get_abi.pl                                 |   2 +-
 security/security.c                                |  18 ++
 security/selinux/hooks.c                           |  28 ++
 security/smack/smack_lsm.c                         |   1 +
 security/tomoyo/tomoyo.c                           |   1 +
 sound/soc/intel/boards/sof_sdw.c                   |   4 +-
 .../selftests/drivers/net/bonding/bond_options.sh  |   8 +-
 .../testing/selftests/drivers/net/bonding/settings |   2 +-
 .../drivers/net/netdevsim/udp_tunnel_nic.sh        |   9 +
 tools/testing/selftests/mm/hugepage-vmemmap.c      |  29 +-
 tools/testing/selftests/net/config                 |  28 ++
 tools/testing/selftests/net/rps_default_mask.sh    |   6 +-
 tools/testing/selftests/net/so_incoming_cpu.c      |  68 ++--
 tools/testing/selftests/riscv/hwprobe/cbo.c        |  18 +-
 414 files changed, 4903 insertions(+), 2618 deletions(-)
author maintainer
#9 lore raw

PATCH 9/346 async: Introduce async_schedule_dev_nocall()

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rafael J. Wysocki <[email protected]>

commit 7d4b5d7a37bdd63a5a3371b988744b060d5bb86f upstream.

In preparation for subsequent changes, introduce a specialized variant of async_schedule_dev() that will not invoke the argument function synchronously when it cannot be scheduled for asynchronous execution.

The new function, async_schedule_dev_nocall(), will be used for fixing possible deadlocks in the system-wide power management core code.

---
 include/linux/async.h |    2 ++
 kernel/async.c        |   29 +++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)
include/linux/async.h +2 -0
@@ -90,6 +90,8 @@ async_schedule_dev(async_func_t func, st
 	return async_schedule_node(func, dev, dev_to_node(dev));
 }
 
+bool async_schedule_dev_nocall(async_func_t func, struct device *dev);
+
 /**
  * async_schedule_dev_domain - A device specific version of async_schedule_domain
  * @func: function to execute asynchronously
kernel/async.c +29 -0
@@ -244,6 +244,35 @@ async_cookie_t async_schedule_node(async
 EXPORT_SYMBOL_GPL(async_schedule_node);
 
 /**
+ * async_schedule_dev_nocall - A simplified variant of async_schedule_dev()
+ * @func: function to execute asynchronously
+ * @dev: device argument to be passed to function
+ *
+ * @dev is used as both the argument for the function and to provide NUMA
+ * context for where to run the function.
+ *
+ * If the asynchronous execution of @func is scheduled successfully, return
+ * true. Otherwise, do nothing and return false, unlike async_schedule_dev()
+ * that will run the function synchronously then.
+ */
+bool async_schedule_dev_nocall(async_func_t func, struct device *dev)
+{
+	struct async_entry *entry;
+
+	entry = kzalloc(sizeof(struct async_entry), GFP_KERNEL);
+
+	/* Give up if there is no memory or too much work. */
+	if (!entry || atomic_read(&entry_count) > MAX_WORK) {
+		kfree(entry);
+		return false;
+	}
+
+	__async_schedule_node_domain(func, dev, dev_to_node(dev),
+				     &async_dfl_domain, entry);
+	return true;
+}
+
+/**
  * async_synchronize_full - synchronize all asynchronous function calls
  *
  * This function waits until all asynchronous function calls have been done.
author maintainer
#29 lore raw

PATCH 29/346 rpmsg: virtio: Free driver_override when rpmsg_remove()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Xiaolei Wang <[email protected]>

commit d5362c37e1f8a40096452fc201c30e705750e687 upstream.

Free driver_override when rpmsg_remove(), otherwise the following memory leak will occur:

unreferenced object 0xffff0000d55d7080 (size 128):
comm "kworker/u8:2", pid 56, jiffies 4294893188 (age 214.272s) hex dump (first 32 bytes):

    72 70 6d 73 67 5f 6e 73 00 00 00 00 00 00 00 00  rpmsg_ns........
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  backtrace:
    [<000000009c94c9c1>] __kmem_cache_alloc_node+0x1f8/0x320
    [<000000002300d89b>] __kmalloc_node_track_caller+0x44/0x70
    [<00000000228a60c3>] kstrndup+0x4c/0x90
    [<0000000077158695>] driver_set_override+0xd0/0x164
    [<000000003e9c4ea5>] rpmsg_register_device_override+0x98/0x170
    [<000000001c0c89a8>] rpmsg_ns_register_device+0x24/0x30
    [<000000008bbf8fa2>] rpmsg_probe+0x2e0/0x3ec
    [<00000000e65a68df>] virtio_dev_probe+0x1c0/0x280
    [<00000000443331cc>] really_probe+0xbc/0x2dc
    [<00000000391064b1>] __driver_probe_device+0x78/0xe0
    [<00000000a41c9a5b>] driver_probe_device+0xd8/0x160
    [<000000009c3bd5df>] __device_attach_driver+0xb8/0x140
    [<0000000043cd7614>] bus_for_each_drv+0x7c/0xd4
    [<000000003b929a36>] __device_attach+0x9c/0x19c
    [<00000000a94e0ba8>] device_initial_probe+0x14/0x20
    [<000000003c999637>] bus_probe_device+0xa0/0xac
---
 drivers/rpmsg/virtio_rpmsg_bus.c |    1 +
 1 file changed, 1 insertion(+)
drivers/rpmsg/virtio_rpmsg_bus.c +1 -0
@@ -378,6 +378,7 @@ static void virtio_rpmsg_release_device(
 	struct rpmsg_device *rpdev = to_rpmsg_device(dev);
 	struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev);
 
+	kfree(rpdev->driver_override);
 	kfree(vch);
 }
 
author maintainer
#38 lore raw

PATCH 38/346 s390/vfio-ap: let on_scan_complete() callback filter matrix and update guests APCB

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tony Krowiak <[email protected]>

commit 774d10196e648e2c0b78da817f631edfb3dfa557 upstream.

When adapters and/or domains are added to the host's AP configuration, this may result in multiple queue devices getting created and probed by the vfio_ap device driver. For each queue device probed, the matrix of adapters and domains assigned to a matrix mdev will be filtered to update the guest's APCB. If any adapters or domains get added to or removed from the APCB, the guest's AP configuration will be dynamically updated (i.e., hot plug/unplug). To dynamically update the guest's configuration, its VCPUs must be taken out of SIE for the period of time it takes to make the update. This is disruptive to the guest's operation and if there are many queues probed due to a change in the host's AP configuration, this could be troublesome. The problem is exacerbated by the fact that the 'on_scan_complete' callback also filters the mdev's matrix and updates the guest's AP configuration.

In order to reduce the potential amount of disruption to the guest that may result from a change to the host's AP configuration, let's bypass the filtering of the matrix and updating of the guest's AP configuration in the probe callback - if due to a host config change - and defer it until the 'on_scan_complete' callback is invoked after the AP bus finishes its device scan operation. This way the filtering and updating will be performed only once regardless of the number of queues added.

Fixes 48cae940c31d ("s390/vfio-ap: refresh guest's APCB by filtering AP resources assigned to mdev")
---
 drivers/s390/crypto/vfio_ap_ops.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/s390/crypto/vfio_ap_ops.c +13 -0
@@ -2084,9 +2084,22 @@ int vfio_ap_mdev_probe_queue(struct ap_d
 	if (matrix_mdev) {
 		vfio_ap_mdev_link_queue(matrix_mdev, q);
 
+		/*
+		 * If we're in the process of handling the adding of adapters or
+		 * domains to the host's AP configuration, then let the
+		 * vfio_ap device driver's on_scan_complete callback filter the
+		 * matrix and update the guest's AP configuration after all of
+		 * the new queue devices are probed.
+		 */
+		if (!bitmap_empty(matrix_mdev->apm_add, AP_DEVICES) ||
+		    !bitmap_empty(matrix_mdev->aqm_add, AP_DOMAINS))
+			goto done;
+
 		if (vfio_ap_mdev_filter_matrix(matrix_mdev))
 			vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 	}
+
+done:
 	dev_set_drvdata(&apdev->device, q);
 	release_update_locks_for_mdev(matrix_mdev);
 
author maintainer
#39 lore raw

PATCH 39/346 s390/vfio-ap: reset queues filtered from the guests AP config

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tony Krowiak <[email protected]>

commit f848cba767e59f8d5c54984b1d45451aae040d50 upstream.

When filtering the adapters from the configuration profile for a guest to create or update a guest's AP configuration, if the APID of an adapter and the APQI of a domain identify a queue device that is not bound to the vfio_ap device driver, the APID of the adapter will be filtered because an individual APQN can not be filtered due to the fact the APQNs are assigned to an AP configuration as a matrix of APIDs and APQIs. Consequently, a guest will not have access to all of the queues associated with the filtered adapter. If the queues are subsequently made available again to the guest, they should re-appear in a reset state; so, let's make sure all queues associated with an adapter unplugged from the guest are reset.

In order to identify the set of queues that need to be reset, let's allow a vfio_ap_queue object to be simultaneously stored in both a hashtable and a
list: A hashtable used to store all of the queues assigned
to a matrix mdev; and/or, a list used to store a subset of the queues that need to be reset. For example, when an adapter is hot unplugged from a guest, all guest queues associated with that adapter must be reset. Since that may be a subset of those assigned to the matrix mdev, they can be stored in a list that can be passed to the vfio_ap_mdev_reset_queues function.

Fixes 48cae940c31d ("s390/vfio-ap: refresh guest's APCB by filtering AP resources assigned to mdev")
---
 drivers/s390/crypto/vfio_ap_ops.c     |  171 +++++++++++++++++++++++++---------
 drivers/s390/crypto/vfio_ap_private.h |    3 
 2 files changed, 129 insertions(+), 45 deletions(-)
drivers/s390/crypto/vfio_ap_ops.c +126 -45
@@ -32,7 +32,8 @@
 
 #define AP_RESET_INTERVAL		20	/* Reset sleep interval (20ms)		*/
 
-static int vfio_ap_mdev_reset_queues(struct ap_queue_table *qtable);
+static int vfio_ap_mdev_reset_queues(struct ap_matrix_mdev *matrix_mdev);
+static int vfio_ap_mdev_reset_qlist(struct list_head *qlist);
 static struct vfio_ap_queue *vfio_ap_find_queue(int apqn);
 static const struct vfio_device_ops vfio_ap_matrix_dev_ops;
 static void vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q);
@@ -662,16 +663,23 @@ static bool vfio_ap_mdev_filter_cdoms(st
  *				device driver.
  *
  * @matrix_mdev: the matrix mdev whose matrix is to be filtered.
+ * @apm_filtered: a 256-bit bitmap for storing the APIDs filtered from the
+ *		  guest's AP configuration that are still in the host's AP
+ *		  configuration.
  *
  * Note: If an APQN referencing a queue device that is not bound to the vfio_ap
  *	 driver, its APID will be filtered from the guest's APCB. The matrix
  *	 structure precludes filtering an individual APQN, so its APID will be
- *	 filtered.
+ *	 filtered. Consequently, all queues associated with the adapter that
+ *	 are in the host's AP configuration must be reset. If queues are
+ *	 subsequently made available again to the guest, they should re-appear
+ *	 in a reset state
  *
  * Return: a boolean value indicating whether the KVM guest's APCB was changed
  *	   by the filtering or not.
  */
-static bool vfio_ap_mdev_filter_matrix(struct ap_matrix_mdev *matrix_mdev)
+static bool vfio_ap_mdev_filter_matrix(struct ap_matrix_mdev *matrix_mdev,
+				       unsigned long *apm_filtered)
 {
 	unsigned long apid, apqi, apqn;
 	DECLARE_BITMAP(prev_shadow_apm, AP_DEVICES);
@@ -681,6 +689,7 @@ static bool vfio_ap_mdev_filter_matrix(s
 	bitmap_copy(prev_shadow_apm, matrix_mdev->shadow_apcb.apm, AP_DEVICES);
 	bitmap_copy(prev_shadow_aqm, matrix_mdev->shadow_apcb.aqm, AP_DOMAINS);
 	vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->shadow_apcb);
+	bitmap_clear(apm_filtered, 0, AP_DEVICES);
 
 	/*
 	 * Copy the adapters, domains and control domains to the shadow_apcb
@@ -706,8 +715,16 @@ static bool vfio_ap_mdev_filter_matrix(s
 			apqn = AP_MKQID(apid, apqi);
 			q = vfio_ap_mdev_get_queue(matrix_mdev, apqn);
 			if (!q || q->reset_status.response_code) {
-				clear_bit_inv(apid,
-					      matrix_mdev->shadow_apcb.apm);
+				clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm);
+
+				/*
+				 * If the adapter was previously plugged into
+				 * the guest, let's let the caller know that
+				 * the APID was filtered.
+				 */
+				if (test_bit_inv(apid, prev_shadow_apm))
+					set_bit_inv(apid, apm_filtered);
+
 				break;
 			}
 		}
@@ -809,7 +826,7 @@ static void vfio_ap_mdev_remove(struct m
 
 	mutex_lock(&matrix_dev->guests_lock);
 	mutex_lock(&matrix_dev->mdevs_lock);
-	vfio_ap_mdev_reset_queues(&matrix_mdev->qtable);
+	vfio_ap_mdev_reset_queues(matrix_mdev);
 	vfio_ap_mdev_unlink_fr_queues(matrix_mdev);
 	list_del(&matrix_mdev->node);
 	mutex_unlock(&matrix_dev->mdevs_lock);
@@ -919,6 +936,47 @@ static void vfio_ap_mdev_link_adapter(st
 				       AP_MKQID(apid, apqi));
 }
 
+static int reset_queues_for_apids(struct ap_matrix_mdev *matrix_mdev,
+				  unsigned long *apm_reset)
+{
+	struct vfio_ap_queue *q, *tmpq;
+	struct list_head qlist;
+	unsigned long apid, apqi;
+	int apqn, ret = 0;
+
+	if (bitmap_empty(apm_reset, AP_DEVICES))
+		return 0;
+
+	INIT_LIST_HEAD(&qlist);
+
+	for_each_set_bit_inv(apid, apm_reset, AP_DEVICES) {
+		for_each_set_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm,
+				     AP_DOMAINS) {
+			/*
+			 * If the domain is not in the host's AP configuration,
+			 * then resetting it will fail with response code 01
+			 * (APQN not valid).
+			 */
+			if (!test_bit_inv(apqi,
+					  (unsigned long *)matrix_dev->info.aqm))
+				continue;
+
+			apqn = AP_MKQID(apid, apqi);
+			q = vfio_ap_mdev_get_queue(matrix_mdev, apqn);
+
+			if (q)
+				list_add_tail(&q->reset_qnode, &qlist);
+		}
+	}
+
+	ret = vfio_ap_mdev_reset_qlist(&qlist);
+
+	list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode)
+		list_del(&q->reset_qnode);
+
+	return ret;
+}
+
 /**
  * assign_adapter_store - parses the APID from @buf and sets the
  * corresponding bit in the mediated matrix device's APM
@@ -959,6 +1017,7 @@ static ssize_t assign_adapter_store(stru
 {
 	int ret;
 	unsigned long apid;
+	DECLARE_BITMAP(apm_filtered, AP_DEVICES);
 	struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
 
 	mutex_lock(&ap_perms_mutex);
@@ -988,8 +1047,10 @@ static ssize_t assign_adapter_store(stru
 
 	vfio_ap_mdev_link_adapter(matrix_mdev, apid);
 
-	if (vfio_ap_mdev_filter_matrix(matrix_mdev))
+	if (vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered)) {
 		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+		reset_queues_for_apids(matrix_mdev, apm_filtered);
+	}
 
 	ret = count;
 done:
@@ -1020,11 +1081,12 @@ static struct vfio_ap_queue
  *				 adapter was assigned.
  * @matrix_mdev: the matrix mediated device to which the adapter was assigned.
  * @apid: the APID of the unassigned adapter.
- * @qtable: table for storing queues associated with unassigned adapter.
+ * @qlist: list for storing queues associated with unassigned adapter that
+ *	   need to be reset.
  */
 static void vfio_ap_mdev_unlink_adapter(struct ap_matrix_mdev *matrix_mdev,
 					unsigned long apid,
-					struct ap_queue_table *qtable)
+					struct list_head *qlist)
 {
 	unsigned long apqi;
 	struct vfio_ap_queue *q;
@@ -1032,11 +1094,10 @@ static void vfio_ap_mdev_unlink_adapter(
 	for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, AP_DOMAINS) {
 		q = vfio_ap_unlink_apqn_fr_mdev(matrix_mdev, apid, apqi);
 
-		if (q && qtable) {
+		if (q && qlist) {
 			if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) &&
 			    test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm))
-				hash_add(qtable->queues, &q->mdev_qnode,
-					 q->apqn);
+				list_add_tail(&q->reset_qnode, qlist);
 		}
 	}
 }
@@ -1044,26 +1105,23 @@ static void vfio_ap_mdev_unlink_adapter(
 static void vfio_ap_mdev_hot_unplug_adapter(struct ap_matrix_mdev *matrix_mdev,
 					    unsigned long apid)
 {
-	int loop_cursor;
-	struct vfio_ap_queue *q;
-	struct ap_queue_table *qtable = kzalloc(sizeof(*qtable), GFP_KERNEL);
+	struct vfio_ap_queue *q, *tmpq;
+	struct list_head qlist;
 
-	hash_init(qtable->queues);
-	vfio_ap_mdev_unlink_adapter(matrix_mdev, apid, qtable);
+	INIT_LIST_HEAD(&qlist);
+	vfio_ap_mdev_unlink_adapter(matrix_mdev, apid, &qlist);
 
 	if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm)) {
 		clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm);
 		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 	}
 
-	vfio_ap_mdev_reset_queues(qtable);
+	vfio_ap_mdev_reset_qlist(&qlist);
 
-	hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) {
+	list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode) {
 		vfio_ap_unlink_mdev_fr_queue(q);
-		hash_del(&q->mdev_qnode);
+		list_del(&q->reset_qnode);
 	}
-
-	kfree(qtable);
 }
 
 /**
@@ -1164,6 +1222,7 @@ static ssize_t assign_domain_store(struc
 {
 	int ret;
 	unsigned long apqi;
+	DECLARE_BITMAP(apm_filtered, AP_DEVICES);
 	struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
 
 	mutex_lock(&ap_perms_mutex);
@@ -1193,8 +1252,10 @@ static ssize_t assign_domain_store(struc
 
 	vfio_ap_mdev_link_domain(matrix_mdev, apqi);
 
-	if (vfio_ap_mdev_filter_matrix(matrix_mdev))
+	if (vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered)) {
 		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+		reset_queues_for_apids(matrix_mdev, apm_filtered);
+	}
 
 	ret = count;
 done:
@@ -1207,7 +1268,7 @@ static DEVICE_ATTR_WO(assign_domain);
 
 static void vfio_ap_mdev_unlink_domain(struct ap_matrix_mdev *matrix_mdev,
 				       unsigned long apqi,
-				       struct ap_queue_table *qtable)
+				       struct list_head *qlist)
 {
 	unsigned long apid;
 	struct vfio_ap_queue *q;
@@ -1215,11 +1276,10 @@ static void vfio_ap_mdev_unlink_domain(s
 	for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, AP_DEVICES) {
 		q = vfio_ap_unlink_apqn_fr_mdev(matrix_mdev, apid, apqi);
 
-		if (q && qtable) {
+		if (q && qlist) {
 			if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) &&
 			    test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm))
-				hash_add(qtable->queues, &q->mdev_qnode,
-					 q->apqn);
+				list_add_tail(&q->reset_qnode, qlist);
 		}
 	}
 }
@@ -1227,26 +1287,23 @@ static void vfio_ap_mdev_unlink_domain(s
 static void vfio_ap_mdev_hot_unplug_domain(struct ap_matrix_mdev *matrix_mdev,
 					   unsigned long apqi)
 {
-	int loop_cursor;
-	struct vfio_ap_queue *q;
-	struct ap_queue_table *qtable = kzalloc(sizeof(*qtable), GFP_KERNEL);
+	struct vfio_ap_queue *q, *tmpq;
+	struct list_head qlist;
 
-	hash_init(qtable->queues);
-	vfio_ap_mdev_unlink_domain(matrix_mdev, apqi, qtable);
+	INIT_LIST_HEAD(&qlist);
+	vfio_ap_mdev_unlink_domain(matrix_mdev, apqi, &qlist);
 
 	if (test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) {
 		clear_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm);
 		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 	}
 
-	vfio_ap_mdev_reset_queues(qtable);
+	vfio_ap_mdev_reset_qlist(&qlist);
 
-	hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) {
+	list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode) {
 		vfio_ap_unlink_mdev_fr_queue(q);
-		hash_del(&q->mdev_qnode);
+		list_del(&q->reset_qnode);
 	}
-
-	kfree(qtable);
 }
 
 /**
@@ -1601,7 +1658,7 @@ static void vfio_ap_mdev_unset_kvm(struc
 		get_update_locks_for_kvm(kvm);
 
 		kvm_arch_crypto_clear_masks(kvm);
-		vfio_ap_mdev_reset_queues(&matrix_mdev->qtable);
+		vfio_ap_mdev_reset_queues(matrix_mdev);
 		kvm_put_kvm(kvm);
 		matrix_mdev->kvm = NULL;
 
@@ -1737,15 +1794,33 @@ static void vfio_ap_mdev_reset_queue(str
 	}
 }
 
-static int vfio_ap_mdev_reset_queues(struct ap_queue_table *qtable)
+static int vfio_ap_mdev_reset_queues(struct ap_matrix_mdev *matrix_mdev)
 {
 	int ret = 0, loop_cursor;
 	struct vfio_ap_queue *q;
 
-	hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode)
+	hash_for_each(matrix_mdev->qtable.queues, loop_cursor, q, mdev_qnode)
 		vfio_ap_mdev_reset_queue(q);
 
-	hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) {
+	hash_for_each(matrix_mdev->qtable.queues, loop_cursor, q, mdev_qnode) {
+		flush_work(&q->reset_work);
+
+		if (q->reset_status.response_code)
+			ret = -EIO;
+	}
+
+	return ret;
+}
+
+static int vfio_ap_mdev_reset_qlist(struct list_head *qlist)
+{
+	int ret = 0;
+	struct vfio_ap_queue *q;
+
+	list_for_each_entry(q, qlist, reset_qnode)
+		vfio_ap_mdev_reset_queue(q);
+
+	list_for_each_entry(q, qlist, reset_qnode) {
 		flush_work(&q->reset_work);
 
 		if (q->reset_status.response_code)
@@ -1931,7 +2006,7 @@ static ssize_t vfio_ap_mdev_ioctl(struct
 		ret = vfio_ap_mdev_get_device_info(arg);
 		break;
 	case VFIO_DEVICE_RESET:
-		ret = vfio_ap_mdev_reset_queues(&matrix_mdev->qtable);
+		ret = vfio_ap_mdev_reset_queues(matrix_mdev);
 		break;
 	case VFIO_DEVICE_GET_IRQ_INFO:
 			ret = vfio_ap_get_irq_info(arg);
@@ -2063,6 +2138,7 @@ int vfio_ap_mdev_probe_queue(struct ap_d
 {
 	int ret;
 	struct vfio_ap_queue *q;
+	DECLARE_BITMAP(apm_filtered, AP_DEVICES);
 	struct ap_matrix_mdev *matrix_mdev;
 
 	ret = sysfs_create_group(&apdev->device.kobj, &vfio_queue_attr_group);
@@ -2095,15 +2171,17 @@ int vfio_ap_mdev_probe_queue(struct ap_d
 		    !bitmap_empty(matrix_mdev->aqm_add, AP_DOMAINS))
 			goto done;
 
-		if (vfio_ap_mdev_filter_matrix(matrix_mdev))
+		if (vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered)) {
 			vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+			reset_queues_for_apids(matrix_mdev, apm_filtered);
+		}
 	}
 
 done:
 	dev_set_drvdata(&apdev->device, q);
 	release_update_locks_for_mdev(matrix_mdev);
 
-	return 0;
+	return ret;
 
 err_remove_group:
 	sysfs_remove_group(&apdev->device.kobj, &vfio_queue_attr_group);
@@ -2447,6 +2525,7 @@ void vfio_ap_on_cfg_changed(struct ap_co
 
 static void vfio_ap_mdev_hot_plug_cfg(struct ap_matrix_mdev *matrix_mdev)
 {
+	DECLARE_BITMAP(apm_filtered, AP_DEVICES);
 	bool filter_domains, filter_adapters, filter_cdoms, do_hotplug = false;
 
 	mutex_lock(&matrix_mdev->kvm->lock);
@@ -2460,7 +2539,7 @@ static void vfio_ap_mdev_hot_plug_cfg(st
 					 matrix_mdev->adm_add, AP_DOMAINS);
 
 	if (filter_adapters || filter_domains)
-		do_hotplug = vfio_ap_mdev_filter_matrix(matrix_mdev);
+		do_hotplug = vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered);
 
 	if (filter_cdoms)
 		do_hotplug |= vfio_ap_mdev_filter_cdoms(matrix_mdev);
@@ -2468,6 +2547,8 @@ static void vfio_ap_mdev_hot_plug_cfg(st
 	if (do_hotplug)
 		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 
+	reset_queues_for_apids(matrix_mdev, apm_filtered);
+
 	mutex_unlock(&matrix_dev->mdevs_lock);
 	mutex_unlock(&matrix_mdev->kvm->lock);
 }
drivers/s390/crypto/vfio_ap_private.h +3 -0
@@ -133,6 +133,8 @@ struct ap_matrix_mdev {
  * @apqn: the APQN of the AP queue device
  * @saved_isc: the guest ISC registered with the GIB interface
  * @mdev_qnode: allows the vfio_ap_queue struct to be added to a hashtable
+ * @reset_qnode: allows the vfio_ap_queue struct to be added to a list of queues
+ *		 that need to be reset
  * @reset_status: the status from the last reset of the queue
  * @reset_work: work to wait for queue reset to complete
  */
@@ -143,6 +145,7 @@ struct vfio_ap_queue {
 #define VFIO_AP_ISC_INVALID 0xff
 	unsigned char saved_isc;
 	struct hlist_node mdev_qnode;
+	struct list_head reset_qnode;
 	struct ap_queue_status reset_status;
 	struct work_struct reset_work;
 };
author maintainer
#40 lore raw

PATCH 40/346 s390/vfio-ap: reset queues associated with adapter for queue unbound from driver

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tony Krowiak <[email protected]>

commit f009cfa466558b7dfe97f167ba1875d6f9ea4c07 upstream.

When a queue is unbound from the vfio_ap device driver, if that queue is assigned to a guest's AP configuration, its associated adapter is removed because queues are defined to a guest via a matrix of adapters and domains; so, it is not possible to remove a single queue.

If an adapter is removed from the guest's AP configuration, all associated queues must be reset to prevent leaking crypto data should any of them be assigned to a different guest or device driver. The one caveat is that if the queue is being removed because the adapter or domain has been removed from the host's AP configuration, then an attempt to reset the queue will fail with response code 01, AP-queue number not valid; so resetting these queues should be skipped.

Fixes 09d31ff78793 ("s390/vfio-ap: hot plug/unplug of AP devices when probed/removed")
---
 drivers/s390/crypto/vfio_ap_ops.c |   76 ++++++++++++++++++++------------------
 1 file changed, 41 insertions(+), 35 deletions(-)
drivers/s390/crypto/vfio_ap_ops.c +41 -35
@@ -936,45 +936,45 @@ static void vfio_ap_mdev_link_adapter(st
 				       AP_MKQID(apid, apqi));
 }
 
+static void collect_queues_to_reset(struct ap_matrix_mdev *matrix_mdev,
+				    unsigned long apid,
+				    struct list_head *qlist)
+{
+	struct vfio_ap_queue *q;
+	unsigned long  apqi;
+
+	for_each_set_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm, AP_DOMAINS) {
+		q = vfio_ap_mdev_get_queue(matrix_mdev, AP_MKQID(apid, apqi));
+		if (q)
+			list_add_tail(&q->reset_qnode, qlist);
+	}
+}
+
+static void reset_queues_for_apid(struct ap_matrix_mdev *matrix_mdev,
+				  unsigned long apid)
+{
+	struct list_head qlist;
+
+	INIT_LIST_HEAD(&qlist);
+	collect_queues_to_reset(matrix_mdev, apid, &qlist);
+	vfio_ap_mdev_reset_qlist(&qlist);
+}
+
 static int reset_queues_for_apids(struct ap_matrix_mdev *matrix_mdev,
 				  unsigned long *apm_reset)
 {
-	struct vfio_ap_queue *q, *tmpq;
 	struct list_head qlist;
-	unsigned long apid, apqi;
-	int apqn, ret = 0;
+	unsigned long apid;
 
 	if (bitmap_empty(apm_reset, AP_DEVICES))
 		return 0;
 
 	INIT_LIST_HEAD(&qlist);
 
-	for_each_set_bit_inv(apid, apm_reset, AP_DEVICES) {
-		for_each_set_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm,
-				     AP_DOMAINS) {
-			/*
-			 * If the domain is not in the host's AP configuration,
-			 * then resetting it will fail with response code 01
-			 * (APQN not valid).
-			 */
-			if (!test_bit_inv(apqi,
-					  (unsigned long *)matrix_dev->info.aqm))
-				continue;
-
-			apqn = AP_MKQID(apid, apqi);
-			q = vfio_ap_mdev_get_queue(matrix_mdev, apqn);
+	for_each_set_bit_inv(apid, apm_reset, AP_DEVICES)
+		collect_queues_to_reset(matrix_mdev, apid, &qlist);
 
-			if (q)
-				list_add_tail(&q->reset_qnode, &qlist);
-		}
-	}
-
-	ret = vfio_ap_mdev_reset_qlist(&qlist);
-
-	list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode)
-		list_del(&q->reset_qnode);
-
-	return ret;
+	return vfio_ap_mdev_reset_qlist(&qlist);
 }
 
 /**
@@ -2200,24 +2200,30 @@ void vfio_ap_mdev_remove_queue(struct ap
 	matrix_mdev = q->matrix_mdev;
 
 	if (matrix_mdev) {
-		vfio_ap_unlink_queue_fr_mdev(q);
-
 		apid = AP_QID_CARD(q->apqn);
 		apqi = AP_QID_QUEUE(q->apqn);
-
-		/*
-		 * If the queue is assigned to the guest's APCB, then remove
-		 * the adapter's APID from the APCB and hot it into the guest.
-		 */
+		/* If the queue is assigned to the guest's AP configuration */
 		if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) &&
 		    test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) {
+			/*
+			 * Since the queues are defined via a matrix of adapters
+			 * and domains, it is not possible to hot unplug a
+			 * single queue; so, let's unplug the adapter.
+			 */
 			clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm);
 			vfio_ap_mdev_update_guest_apcb(matrix_mdev);
+			reset_queues_for_apid(matrix_mdev, apid);
+			goto done;
 		}
 	}
 
 	vfio_ap_mdev_reset_queue(q);
 	flush_work(&q->reset_work);
+
+done:
+	if (matrix_mdev)
+		vfio_ap_unlink_queue_fr_mdev(q);
+
 	dev_set_drvdata(&apdev->device, NULL);
 	kfree(q);
 	release_update_locks_for_mdev(matrix_mdev);
author maintainer
#41 lore raw

PATCH 41/346 s390/vfio-ap: do not reset queue removed from host config

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tony Krowiak <[email protected]>

commit b9bd10c43456d16abd97b717446f51afb3b88411 upstream.

When a queue is unbound from the vfio_ap device driver, it is reset to ensure its crypto data is not leaked when it is bound to another device driver. If the queue is unbound due to the fact that the adapter or domain was removed from the host's AP configuration, then attempting to reset it will fail with response code 01 (APID not valid) getting returned from the reset command. Let's ensure that the queue is assigned to the host's configuration before resetting it.

---
 drivers/s390/crypto/vfio_ap_ops.c |   16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/s390/crypto/vfio_ap_ops.c +12 -4
@@ -2198,10 +2198,10 @@ void vfio_ap_mdev_remove_queue(struct ap
 	q = dev_get_drvdata(&apdev->device);
 	get_update_locks_for_queue(q);
 	matrix_mdev = q->matrix_mdev;
+	apid = AP_QID_CARD(q->apqn);
+	apqi = AP_QID_QUEUE(q->apqn);
 
 	if (matrix_mdev) {
-		apid = AP_QID_CARD(q->apqn);
-		apqi = AP_QID_QUEUE(q->apqn);
 		/* If the queue is assigned to the guest's AP configuration */
 		if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) &&
 		    test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) {
@@ -2217,8 +2217,16 @@ void vfio_ap_mdev_remove_queue(struct ap
 		}
 	}
 
-	vfio_ap_mdev_reset_queue(q);
-	flush_work(&q->reset_work);
+	/*
+	 * If the queue is not in the host's AP configuration, then resetting
+	 * it will fail with response code 01, (APQN not valid); so, let's make
+	 * sure it is in the host's config.
+	 */
+	if (test_bit_inv(apid, (unsigned long *)matrix_dev->info.apm) &&
+	    test_bit_inv(apqi, (unsigned long *)matrix_dev->info.aqm)) {
+		vfio_ap_mdev_reset_queue(q);
+		flush_work(&q->reset_work);
+	}
 
 done:
 	if (matrix_mdev)
author maintainer
#42 lore raw

PATCH 42/346 seq_buf: Make DECLARE_SEQ_BUF() usable

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Nathan Lynch <[email protected]>

commit 7a8e9cdf9405819105ae7405cd91e482bf574b01 upstream.

Using the address operator on the array doesn't work:

./include/linux/seq_buf.h:27:27: error: initialization of ‘char *’
from incompatible pointer type ‘char (*)[128]’ [-Werror=incompatible-pointer-types]
27 | .buffer = &__ ## NAME ## _buffer, \
| ^

Apart from fixing that, we can improve DECLARE_SEQ_BUF() by using a compound literal to define the buffer array without attaching a name to it. This makes the macro a single statement, allowing constructs such as:

  static DECLARE_SEQ_BUF(my_seq_buf, MYSB_SIZE);

to work as intended.

Fixes dcc4e5728eea ("seq_buf: Introduce DECLARE_SEQ_BUF and seq_buf_str()")
---
 include/linux/seq_buf.h |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
include/linux/seq_buf.h +1 -2
@@ -22,9 +22,8 @@ struct seq_buf {
 };
 
 #define DECLARE_SEQ_BUF(NAME, SIZE)			\
-	char __ ## NAME ## _buffer[SIZE] = "";		\
 	struct seq_buf NAME = {				\
-		.buffer = &__ ## NAME ## _buffer,	\
+		.buffer = (char[SIZE]) { 0 },		\
 		.size = SIZE,				\
 	}
 
author maintainer
#43 lore raw

PATCH 43/346 nbd: always initialize struct msghdr completely

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Eric Dumazet <[email protected]>

commit 78fbb92af27d0982634116c7a31065f24d092826 upstream.

syzbot complains that msg->msg_get_inq value can be uninitialized [1]

struct msghdr got many new fields recently, we should always make sure their values is zero by default.

[1]

 BUG: KMSAN: uninit-value in tcp_recvmsg+0x686/0xac0 net/ipv4/tcp.c:2571
  tcp_recvmsg+0x686/0xac0 net/ipv4/tcp.c:2571
  inet_recvmsg+0x131/0x580 net/ipv4/af_inet.c:879
  sock_recvmsg_nosec net/socket.c:1044 [inline]
  sock_recvmsg+0x12b/0x1e0 net/socket.c:1066
  __sock_xmit+0x236/0x5c0 drivers/block/nbd.c:538
  nbd_read_reply drivers/block/nbd.c:732 [inline]
  recv_work+0x262/0x3100 drivers/block/nbd.c:863
  process_one_work kernel/workqueue.c:2627 [inline]
  process_scheduled_works+0x104e/0x1e70 kernel/workqueue.c:2700
  worker_thread+0xf45/0x1490 kernel/workqueue.c:2781
  kthread+0x3ed/0x540 kernel/kthread.c:388
  ret_from_fork+0x66/0x80 arch/x86/kernel/process.c:147
  ret_from_fork_asm+0x11/0x20 arch/x86/entry/entry_64.S:242

Local variable msg created at:

  __sock_xmit+0x4c/0x5c0 drivers/block/nbd.c:513
  nbd_read_reply drivers/block/nbd.c:732 [inline]
  recv_work+0x262/0x3100 drivers/block/nbd.c:863

CPU: 1 PID: 7465 Comm: kworker/u5:1 Not tainted 6.7.0-rc7-syzkaller-00041-gf016f7547aee #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023
Workqueue: nbd5-recv recv_work
---
 drivers/block/nbd.c |    6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/block/nbd.c +1 -5
@@ -510,7 +510,7 @@ static int __sock_xmit(struct nbd_device
 		       struct iov_iter *iter, int msg_flags, int *sent)
 {
 	int result;
-	struct msghdr msg;
+	struct msghdr msg = {} ;
 	unsigned int noreclaim_flag;
 
 	if (unlikely(!sock)) {
@@ -526,10 +526,6 @@ static int __sock_xmit(struct nbd_device
 	do {
 		sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC;
 		sock->sk->sk_use_task_frag = false;
-		msg.msg_name = NULL;
-		msg.msg_namelen = 0;
-		msg.msg_control = NULL;
-		msg.msg_controllen = 0;
 		msg.msg_flags = msg_flags | MSG_NOSIGNAL;
 
 		if (send)
author maintainer
#44 lore raw

PATCH 44/346 mips: Fix max_mapnr being uninitialized on early stages

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Serge Semin <[email protected]>

commit e1a9ae45736989c972a8d1c151bc390678ae6205 upstream.

max_mapnr variable is utilized in the pfn_valid() method in order to determine the upper PFN space boundary. Having it uninitialized effectively makes any PFN passed to that method invalid. That in its turn causes the kernel mm-subsystem occasion malfunctions even after the max_mapnr variable is actually properly updated. For instance, pfn_valid() is called in the init_unavailable_range() method in the framework of the calls-chain on MIPS:
setup_arch()

+-> paging_init()
    +-> free_area_init()
        +-> memmap_init()
            +-> memmap_init_zone_range()
                +-> init_unavailable_range()

Since pfn_valid() always returns "false" value before max_mapnr is initialized in the mem_init() method, any flatmem page-holes will be left in the poisoned/uninitialized state including the IO-memory pages. Thus any further attempts to map/remap the IO-memory by using MMU may fail. In particular it happened in my case on attempt to map the SRAM region. The kernel bootup procedure just crashed on the unhandled unaligned access bug raised in the __update_cache() method:

Quoted 11 lines

Unhandled kernel unaligned access[#1]:

CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.7.0-rc1-XXX-dirty #2056
...
Call Trace:
[<8011ef9c>] __update_cache+0x88/0x1bc
[<80385944>] ioremap_page_range+0x110/0x2a4
[<80126948>] ioremap_prot+0x17c/0x1f4
[<80711b80>] __devm_ioremap+0x8c/0x120
[<80711e0c>] __devm_ioremap_resource+0xf4/0x218
[<808bf244>] sram_probe+0x4f4/0x930
[<80889d20>] platform_probe+0x68/0xec
Quoted 1 line

...

Let's fix the problem by initializing the max_mapnr variable as soon as the required data is available. In particular it can be done right in the paging_init() method before free_area_init() is called since all the PFN zone boundaries have already been calculated by that time.

---
 arch/mips/mm/init.c |   12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
arch/mips/mm/init.c +5 -7
@@ -422,7 +422,12 @@ void __init paging_init(void)
 		       (highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10));
 		max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn;
 	}
+
+	max_mapnr = highend_pfn ? highend_pfn : max_low_pfn;
+#else
+	max_mapnr = max_low_pfn;
 #endif
+	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
 
 	free_area_init(max_zone_pfns);
 }
@@ -458,13 +463,6 @@ void __init mem_init(void)
 	 */
 	BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (PFN_PTE_SHIFT > PAGE_SHIFT));
 
-#ifdef CONFIG_HIGHMEM
-	max_mapnr = highend_pfn ? highend_pfn : max_low_pfn;
-#else
-	max_mapnr = max_low_pfn;
-#endif
-	high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
-
 	maar_init();
 	memblock_free_all();
 	setup_zero_pages();	/* Setup zeroed pages.  */
author maintainer
#45 lore raw

PATCH 45/346 bus: mhi: host: Add alignment check for event ring read pointer

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Krishna chaitanya chundru <[email protected]>

commit eff9704f5332a13b08fbdbe0f84059c9e7051d5f upstream.

Though we do check the event ring read pointer by "is_valid_ring_ptr" to make sure it is in the buffer range, but there is another risk the pointer may be not aligned. Since we are expecting event ring elements are 128 bits(struct mhi_ring_element) aligned, an unaligned read pointer could lead to multiple issues like DoS or ring buffer memory corruption.

So add a alignment check for event ring read pointer.

---
 drivers/bus/mhi/host/main.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/bus/mhi/host/main.c +2 -1
@@ -268,7 +268,8 @@ static void mhi_del_ring_element(struct
 
 static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr)
 {
-	return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len;
+	return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len &&
+			!(addr & (sizeof(struct mhi_ring_element) - 1));
 }
 
 int mhi_destroy_device(struct device *dev, void *data)
author maintainer
#46 lore raw

PATCH 46/346 bus: mhi: host: Drop chan lock before queuing buffers

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Qiang Yu <[email protected]>

commit 01bd694ac2f682fb8017e16148b928482bc8fa4b upstream.

Ensure read and write locks for the channel are not taken in succession by dropping the read lock from parse_xfer_event() such that a callback given to client can potentially queue buffers and acquire the write lock in that process. Any queueing of buffers should be done without channel read lock acquired as it can result in multiple locks and a soft lockup.

Fixes 1d3173a3bae7 ("bus: mhi: core: Add support for processing events from client device")
[mani: added fixes tag and cc'ed stable]
---
 drivers/bus/mhi/host/main.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/bus/mhi/host/main.c +4 -0
@@ -643,6 +643,8 @@ static int parse_xfer_event(struct mhi_c
 			mhi_del_ring_element(mhi_cntrl, tre_ring);
 			local_rp = tre_ring->rp;
 
+			read_unlock_bh(&mhi_chan->lock);
+
 			/* notify client */
 			mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
 
@@ -668,6 +670,8 @@ static int parse_xfer_event(struct mhi_c
 					kfree(buf_info->cb_buf);
 				}
 			}
+
+			read_lock_bh(&mhi_chan->lock);
 		}
 		break;
 	} /* CC_EOT */
author maintainer
#47 lore raw

PATCH 47/346 bus: mhi: host: Add spinlock to protect WP access when queueing TREs

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bhaumik Bhatt <[email protected]>

commit b89b6a863dd53bc70d8e52d50f9cfaef8ef5e9c9 upstream.

Protect WP accesses such that multiple threads queueing buffers for incoming data do not race.

Meanwhile, if CONFIG_TRACE_IRQFLAGS is enabled, irq will be enabled once __local_bh_enable_ip is called as part of write_unlock_bh. Hence, let's take irqsave lock after TRE is generated to avoid running write_unlock_bh when irqsave lock is held.

---
 drivers/bus/mhi/host/main.c |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)
drivers/bus/mhi/host/main.c +13 -9
@@ -1127,17 +1127,15 @@ static int mhi_queue(struct mhi_device *
 	if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)))
 		return -EIO;
 
-	read_lock_irqsave(&mhi_cntrl->pm_lock, flags);
-
 	ret = mhi_is_ring_full(mhi_cntrl, tre_ring);
-	if (unlikely(ret)) {
-		ret = -EAGAIN;
-		goto exit_unlock;
-	}
+	if (unlikely(ret))
+		return -EAGAIN;
 
 	ret = mhi_gen_tre(mhi_cntrl, mhi_chan, buf_info, mflags);
 	if (unlikely(ret))
-		goto exit_unlock;
+		return ret;
+
+	read_lock_irqsave(&mhi_cntrl->pm_lock, flags);
 
 	/* Packet is queued, take a usage ref to exit M3 if necessary
 	 * for host->device buffer, balanced put is done on buffer completion
@@ -1157,7 +1155,6 @@ static int mhi_queue(struct mhi_device *
 	if (dir == DMA_FROM_DEVICE)
 		mhi_cntrl->runtime_put(mhi_cntrl);
 
-exit_unlock:
 	read_unlock_irqrestore(&mhi_cntrl->pm_lock, flags);
 
 	return ret;
@@ -1209,6 +1206,9 @@ int mhi_gen_tre(struct mhi_controller *m
 	int eot, eob, chain, bei;
 	int ret;
 
+	/* Protect accesses for reading and incrementing WP */
+	write_lock_bh(&mhi_chan->lock);
+
 	buf_ring = &mhi_chan->buf_ring;
 	tre_ring = &mhi_chan->tre_ring;
 
@@ -1226,8 +1226,10 @@ int mhi_gen_tre(struct mhi_controller *m
 
 	if (!info->pre_mapped) {
 		ret = mhi_cntrl->map_single(mhi_cntrl, buf_info);
-		if (ret)
+		if (ret) {
+			write_unlock_bh(&mhi_chan->lock);
 			return ret;
+		}
 	}
 
 	eob = !!(flags & MHI_EOB);
@@ -1244,6 +1246,8 @@ int mhi_gen_tre(struct mhi_controller *m
 	mhi_add_ring_element(mhi_cntrl, tre_ring);
 	mhi_add_ring_element(mhi_cntrl, buf_ring);
 
+	write_unlock_bh(&mhi_chan->lock);
+
 	return 0;
 }
 
author maintainer
#30 lore raw

PATCH 30/346 media: ov9734: Enable runtime PM before registering async sub-device

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bingbu Cao <[email protected]>

commit e242e9c144050ed120cf666642ba96b7c4462a4c upstream.

As the sensor device maybe accessible right after its async sub-device is registered, such as ipu-bridge will try to power up sensor by sensor's client device's runtime PM from the async notifier callback, if runtime PM is not enabled, it will fail.

So runtime PM should be ready before its async sub-device is registered and accessible by others.

Fixes d3f863a63fe4 ("media: i2c: Add ov9734 image sensor driver")
---
 drivers/media/i2c/ov9734.c |   19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)
drivers/media/i2c/ov9734.c +11 -8
@@ -894,6 +894,7 @@ static void ov9734_remove(struct i2c_cli
 	media_entity_cleanup(&sd->entity);
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
 	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
 	mutex_destroy(&ov9734->mutex);
 }
 
@@ -939,13 +940,6 @@ static int ov9734_probe(struct i2c_clien
 		goto probe_error_v4l2_ctrl_handler_free;
 	}
 
-	ret = v4l2_async_register_subdev_sensor(&ov9734->sd);
-	if (ret < 0) {
-		dev_err(&client->dev, "failed to register V4L2 subdev: %d",
-			ret);
-		goto probe_error_media_entity_cleanup;
-	}
-
 	/*
 	 * Device is already turned on by i2c-core with ACPI domain PM.
 	 * Enable runtime PM and turn off the device.
@@ -954,9 +948,18 @@ static int ov9734_probe(struct i2c_clien
 	pm_runtime_enable(&client->dev);
 	pm_runtime_idle(&client->dev);
 
+	ret = v4l2_async_register_subdev_sensor(&ov9734->sd);
+	if (ret < 0) {
+		dev_err(&client->dev, "failed to register V4L2 subdev: %d",
+			ret);
+		goto probe_error_media_entity_cleanup_pm;
+	}
+
 	return 0;
 
-probe_error_media_entity_cleanup:
+probe_error_media_entity_cleanup_pm:
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
 	media_entity_cleanup(&ov9734->sd.entity);
 
 probe_error_v4l2_ctrl_handler_free:
author maintainer
#48 lore raw

PATCH 48/346 parisc/firmware: Fix F-extend for PDC addresses

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Helge Deller <[email protected]>

commit 735ae74f73e55c191d48689bd11ff4a06ea0508f upstream.

When running with narrow firmware (64-bit kernel using a 32-bit firmware), extend PDC addresses into the 0xfffffff0.00000000 region instead of the 0xf0f0f0f0.00000000 region.

This fixes the power button on the C3700 machine in qemu (64-bit CPU with 32-bit firmware), and my assumption is that the previous code was really never used (because most 64-bit machines have a 64-bit firmware), or it just worked on very old machines because they may only decode 40-bit of virtual addresses.

---
 arch/parisc/kernel/firmware.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/parisc/kernel/firmware.c +2 -2
@@ -123,10 +123,10 @@ static unsigned long f_extend(unsigned l
 #ifdef CONFIG_64BIT
 	if(unlikely(parisc_narrow_firmware)) {
 		if((address & 0xff000000) == 0xf0000000)
-			return 0xf0f0f0f000000000UL | (u32)address;
+			return (0xfffffff0UL << 32) | (u32)address;
 
 		if((address & 0xf0000000) == 0xf0000000)
-			return 0xffffffff00000000UL | (u32)address;
+			return (0xffffffffUL << 32) | (u32)address;
 	}
 #endif
 	return address;
author maintainer
#49 lore raw

PATCH 49/346 parisc/power: Fix power soft-off button emulation on qemu

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Helge Deller <[email protected]>

commit 6472036581f947109b20664121db1d143e916f0b upstream.

Make sure to start the kthread to check the power button on qemu as well if the power button address was provided.
This fixes the qemu built-in system_powerdown runtime command.

Fixes d0c219472980 ("parisc/power: Add power soft-off when running on qemu")
---
 drivers/parisc/power.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/parisc/power.c +1 -1
@@ -213,7 +213,7 @@ static int __init power_init(void)
 	if (running_on_qemu && soft_power_reg)
 		register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT,
 					qemu_power_off, (void *)soft_power_reg);
-	else
+	if (!running_on_qemu || soft_power_reg)
 		power_task = kthread_run(kpowerswd, (void*)soft_power_reg,
 					KTHREAD_NAME);
 	if (IS_ERR(power_task)) {
author maintainer
#50 lore raw

PATCH 50/346 iio: adc: ad7091r: Enable internal vref if external vref is not supplied

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Marcelo Schmitt <[email protected]>

[ Upstream commit e71c5c89bcb165a02df35325aa13d1ee40112401 ]

The ADC needs a voltage reference to work correctly.
Users can provide an external voltage reference or use the chip internal reference to operate the ADC.
The availability of an in chip reference for the ADC saves the user from having to supply an external voltage reference, which makes the external reference an optional property as described in the device tree documentation.
Though, to use the internal reference, it must be enabled by writing to the configuration register.
Enable AD7091R internal voltage reference if no external vref is supplied.

---
 drivers/iio/adc/ad7091r-base.c | 7 +++++++
 drivers/iio/adc/ad7091r-base.h | 2 ++
 2 files changed, 9 insertions(+)
drivers/iio/adc/ad7091r-base.c +7 -0
index 3d36bcd26b0c..76002b91c86a 100644
@@ -405,7 +405,14 @@ int ad7091r_probe(struct device *dev, const char *name,
 	if (IS_ERR(st->vref)) {
 		if (PTR_ERR(st->vref) == -EPROBE_DEFER)
 			return -EPROBE_DEFER;
+
 		st->vref = NULL;
+		/* Enable internal vref */
+		ret = regmap_set_bits(st->map, AD7091R_REG_CONF,
+				      AD7091R_REG_CONF_INT_VREF);
+		if (ret)
+			return dev_err_probe(st->dev, ret,
+					     "Error on enable internal reference\n");
 	} else {
 		ret = regulator_enable(st->vref);
 		if (ret)
drivers/iio/adc/ad7091r-base.h +2 -0
index 7a78976a2f80..b9e1c8bf3440 100644
@@ -8,6 +8,8 @@
 #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
 #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
 
+#define AD7091R_REG_CONF_INT_VREF	BIT(0)
+
 /* AD7091R_REG_CH_LIMIT */
 #define AD7091R_HIGH_LIMIT		0xFFF
 #define AD7091R_LOW_LIMIT		0x0
Signature · 1 line
2.43.0
author maintainer
#51 lore raw

PATCH 51/346 dmaengine: fsl-edma: fix eDMAv4 channel allocation issue

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Frank Li <[email protected]>

[ Upstream commit dc51b4442dd94ab12c146c1897bbdb40e16d5636 ]

The eDMAv4 channel mux has a limitation where certain requests must use even channels, while others must use odd numbers.

Add two flags (ARGS_EVEN_CH and ARGS_ODD_CH) to reflect this limitation. The device tree source (dts) files need to be updated accordingly.

This issue was identified by the following commit:
commit a725990557e7 ("arm64: dts: imx93: Fix the dmas entries order")

Reverting channel orders triggered this problem.

Fixes 72f5801a4e2b ("dmaengine: fsl-edma: integrate v3 support")
---
 drivers/dma/fsl-edma-main.c | 8 ++++++++
 1 file changed, 8 insertions(+)
drivers/dma/fsl-edma-main.c +8 -0
index 238a69bd0d6f..75cae7ccae27 100644
@@ -24,6 +24,8 @@
 #define ARGS_RX                         BIT(0)
 #define ARGS_REMOTE                     BIT(1)
 #define ARGS_MULTI_FIFO                 BIT(2)
+#define ARGS_EVEN_CH                    BIT(3)
+#define ARGS_ODD_CH                     BIT(4)
 
 static void fsl_edma_synchronize(struct dma_chan *chan)
 {
@@ -157,6 +159,12 @@ static struct dma_chan *fsl_edma3_xlate(struct of_phandle_args *dma_spec,
 		fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE;
 		fsl_chan->is_multi_fifo = dma_spec->args[2] & ARGS_MULTI_FIFO;
 
+		if ((dma_spec->args[2] & ARGS_EVEN_CH) && (i & 0x1))
+			continue;
+
+		if ((dma_spec->args[2] & ARGS_ODD_CH) && !(i & 0x1))
+			continue;
+
 		if (!b_chmux && i == dma_spec->args[0]) {
 			chan = dma_get_slave_channel(chan);
 			chan->device->privatecnt++;
Signature · 1 line
2.43.0
author maintainer
#52 lore raw

PATCH 52/346 dmaengine: fix NULL pointer in channel unregistration function

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Amelie Delaunay <[email protected]>

[ Upstream commit f5c24d94512f1b288262beda4d3dcb9629222fc7 ]

__dma_async_device_channel_register() can fail. In case of failure, chan->local is freed (with free_percpu()), and chan->local is nullified. When dma_async_device_unregister() is called (because of managed API or intentionally by DMA controller driver), channels are unconditionally unregistered, leading to this NULL pointer:

[    1.318693] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000d0
[...]
[    1.484499] Call trace:
[    1.486930]  device_del+0x40/0x394
[    1.490314]  device_unregister+0x20/0x7c
[    1.494220]  __dma_async_device_channel_unregister+0x68/0xc0

Look at dma_async_device_register() function error path, channel device unregistration is done only if chan->local is not NULL.

Then add the same condition at the beginning of __dma_async_device_channel_unregister() function, to avoid NULL pointer issue whatever the API used to reach this function.

Fixes d2fb0a043838 ("dmaengine: break out channel registration")
---
 drivers/dma/dmaengine.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/dma/dmaengine.c +3 -0
index b7388ae62d7f..491b22240221 100644
@@ -1103,6 +1103,9 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_register);
 static void __dma_async_device_channel_unregister(struct dma_device *device,
 						  struct dma_chan *chan)
 {
+	if (chan->local == NULL)
+		return;
+
 	WARN_ONCE(!device->device_release && chan->client_count,
 		  "%s called while %d clients hold a reference\n",
 		  __func__, chan->client_count);
Signature · 1 line
2.43.0
author maintainer
#53 lore raw

PATCH 53/346 dmaengine: idxd: Move dma_free_coherent() out of spinlocked context

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rex Zhang <[email protected]>

[ Upstream commit e271c0ba3f919c48e90c64b703538fbb7865cb63 ]

Task may be rescheduled within dma_free_coherent(). So dma_free_coherent() can't be called between spin_lock() and spin_unlock() to avoid Call Trace:

    Call Trace:
    <TASK>
    dump_stack_lvl+0x37/0x50
    __might_resched+0x16a/0x1c0
    vunmap+0x2c/0x70
    __iommu_dma_free+0x96/0x100
    idxd_device_evl_free+0xd5/0x100 [idxd]
    device_release_driver_internal+0x197/0x200
    unbind_store+0xa1/0xb0
    kernfs_fop_write_iter+0x120/0x1c0
    vfs_write+0x2d3/0x400
    ksys_write+0x63/0xe0
    do_syscall_64+0x44/0xa0
    entry_SYSCALL_64_after_hwframe+0x6e/0xd8

Move it out of the context.

Fixes 244da66cda35 ("dmaengine: idxd: setup event log configuration")
---
 drivers/dma/idxd/device.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/dma/idxd/device.c +8 -1
index 8f754f922217..fa0f880beae6 100644
@@ -802,6 +802,9 @@ static int idxd_device_evl_setup(struct idxd_device *idxd)
 
 static void idxd_device_evl_free(struct idxd_device *idxd)
 {
+	void *evl_log;
+	unsigned int evl_log_size;
+	dma_addr_t evl_dma;
 	union gencfg_reg gencfg;
 	union genctrl_reg genctrl;
 	struct device *dev = &idxd->pdev->dev;
@@ -822,11 +825,15 @@ static void idxd_device_evl_free(struct idxd_device *idxd)
 	iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET);
 	iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET + 8);
 
-	dma_free_coherent(dev, evl->log_size, evl->log, evl->dma);
 	bitmap_free(evl->bmap);
+	evl_log = evl->log;
+	evl_log_size = evl->log_size;
+	evl_dma = evl->dma;
 	evl->log = NULL;
 	evl->size = IDXD_EVL_SIZE_MIN;
 	spin_unlock(&evl->lock);
+
+	dma_free_coherent(dev, evl_log_size, evl_log, evl_dma);
 }
 
 static void idxd_group_config_write(struct idxd_group *group)
Signature · 1 line
2.43.0
author maintainer
#54 lore raw

PATCH 54/346 dmaengine: xilinx: xdma: Fix the count of elapsed periods in cyclic mode

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Miquel Raynal <[email protected]>

[ Upstream commit 26ee018ff6d1c326ac9b9be36513e35870ed09db ]

Xilinx DMA engine is capable of keeping track of the number of elapsed periods and this is an increasing 32-bit counter which is only reset when turning off the engine. No need to add this value to our local counter.

Fixes cd8c732ce1a5 ("dmaengine: xilinx: xdma: Support cyclic transfers")
---
 drivers/dma/xilinx/xdma.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/dma/xilinx/xdma.c +4 -2
index 84a88029226f..2c9c72d4b5a2 100644
@@ -754,9 +754,9 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id)
 	if (ret)
 		goto out;
 
-	desc->completed_desc_num += complete_desc_num;
-
 	if (desc->cyclic) {
+		desc->completed_desc_num = complete_desc_num;
+
 		ret = regmap_read(xdev->rmap, xchan->base + XDMA_CHAN_STATUS,
 				  &st);
 		if (ret)
@@ -768,6 +768,8 @@ static irqreturn_t xdma_channel_isr(int irq, void *dev_id)
 		goto out;
 	}
 
+	desc->completed_desc_num += complete_desc_num;
+
 	/*
 	 * if all data blocks are transferred, remove and complete the request
 	 */
Signature · 1 line
2.43.0
author maintainer
#31 lore raw

PATCH 31/346 media: ov13b10: Enable runtime PM before registering async sub-device

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bingbu Cao <[email protected]>

commit 7b0454cfd8edb3509619407c3b9f78a6d0dee1a5 upstream.

As the sensor device maybe accessible right after its async sub-device is registered, such as ipu-bridge will try to power up sensor by sensor's client device's runtime PM from the async notifier callback, if runtime PM is not enabled, it will fail.

So runtime PM should be ready before its async sub-device is registered and accessible by others.

Fixes 7ee850546822 ("media: Add sensor driver support for the ov13b10 camera.")
---
 drivers/media/i2c/ov13b10.c |   14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)
drivers/media/i2c/ov13b10.c +9 -5
@@ -1556,24 +1556,27 @@ static int ov13b10_probe(struct i2c_clie
 		goto error_handler_free;
 	}
 
-	ret = v4l2_async_register_subdev_sensor(&ov13b->sd);
-	if (ret < 0)
-		goto error_media_entity;
 
 	/*
 	 * Device is already turned on by i2c-core with ACPI domain PM.
 	 * Enable runtime PM and turn off the device.
 	 */
-
 	/* Set the device's state to active if it's in D0 state. */
 	if (full_power)
 		pm_runtime_set_active(&client->dev);
 	pm_runtime_enable(&client->dev);
 	pm_runtime_idle(&client->dev);
 
+	ret = v4l2_async_register_subdev_sensor(&ov13b->sd);
+	if (ret < 0)
+		goto error_media_entity_runtime_pm;
+
 	return 0;
 
-error_media_entity:
+error_media_entity_runtime_pm:
+	pm_runtime_disable(&client->dev);
+	if (full_power)
+		pm_runtime_set_suspended(&client->dev);
 	media_entity_cleanup(&ov13b->sd.entity);
 
 error_handler_free:
@@ -1596,6 +1599,7 @@ static void ov13b10_remove(struct i2c_cl
 	ov13b10_free_controls(ov13b);
 
 	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
 }
 
 static DEFINE_RUNTIME_DEV_PM_OPS(ov13b10_pm_ops, ov13b10_suspend,
author maintainer
#32 lore raw

PATCH 32/346 media: ov01a10: Enable runtime PM before registering async sub-device

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bingbu Cao <[email protected]>

commit 47a78052db51b16e8045524fbf33373b58f1323b upstream.

As the sensor device maybe accessible right after its async sub-device is registered, such as ipu-bridge will try to power up sensor by sensor's client device's runtime PM from the async notifier callback, if runtime PM is not enabled, it will fail.

So runtime PM should be ready before its async sub-device is registered and accessible by others.

It also sets the runtime PM status to active as the sensor was turned on by i2c-core.

Fixes 0827b58dabff ("media: i2c: add ov01a10 image sensor driver")
---
 drivers/media/i2c/ov01a10.c |   18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/media/i2c/ov01a10.c +14 -4
@@ -859,6 +859,7 @@ static void ov01a10_remove(struct i2c_cl
 	v4l2_ctrl_handler_free(sd->ctrl_handler);
 
 	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
 }
 
 static int ov01a10_probe(struct i2c_client *client)
@@ -905,17 +906,26 @@ static int ov01a10_probe(struct i2c_clie
 		goto err_media_entity_cleanup;
 	}
 
+	/*
+	 * Device is already turned on by i2c-core with ACPI domain PM.
+	 * Enable runtime PM and turn off the device.
+	 */
+	pm_runtime_set_active(&client->dev);
+	pm_runtime_enable(dev);
+	pm_runtime_idle(dev);
+
 	ret = v4l2_async_register_subdev_sensor(&ov01a10->sd);
 	if (ret < 0) {
 		dev_err(dev, "Failed to register subdev: %d\n", ret);
-		goto err_media_entity_cleanup;
+		goto err_pm_disable;
 	}
 
-	pm_runtime_enable(dev);
-	pm_runtime_idle(dev);
-
 	return 0;
 
+err_pm_disable:
+	pm_runtime_disable(dev);
+	pm_runtime_set_suspended(&client->dev);
+
 err_media_entity_cleanup:
 	media_entity_cleanup(&ov01a10->sd.entity);
 
author maintainer
#33 lore raw

PATCH 33/346 soc: fsl: cpm1: tsa: Fix __iomem addresses declaration

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herve Codina <[email protected]>

commit fc0c64154e5ddeb6f63c954735bd646ce5b8d9a4 upstream.

Running sparse (make C=1) on tsa.c raises a lot of warning such as:
--- 8< ---
warning: incorrect type in assignment (different address spaces)
expected void *[noderef] si_regs
got void [noderef] __iomem *
--- 8< ---

Indeed, some variable were declared 'type *__iomem var' instead of 'type __iomem *var'.

Use the correct declaration to remove these warnings.

---
 drivers/soc/fsl/qe/tsa.c |   22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)
drivers/soc/fsl/qe/tsa.c +11 -11
@@ -98,9 +98,9 @@
 #define TSA_SIRP	0x10
 
 struct tsa_entries_area {
-	void *__iomem entries_start;
-	void *__iomem entries_next;
-	void *__iomem last_entry;
+	void __iomem *entries_start;
+	void __iomem *entries_next;
+	void __iomem *last_entry;
 };
 
 struct tsa_tdm {
@@ -117,8 +117,8 @@ struct tsa_tdm {
 
 struct tsa {
 	struct device *dev;
-	void *__iomem si_regs;
-	void *__iomem si_ram;
+	void __iomem *si_regs;
+	void __iomem *si_ram;
 	resource_size_t si_ram_sz;
 	spinlock_t	lock;
 	int tdms; /* TSA_TDMx ORed */
@@ -135,27 +135,27 @@ static inline struct tsa *tsa_serial_get
 	return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]);
 }
 
-static inline void tsa_write32(void *__iomem addr, u32 val)
+static inline void tsa_write32(void __iomem *addr, u32 val)
 {
 	iowrite32be(val, addr);
 }
 
-static inline void tsa_write8(void *__iomem addr, u32 val)
+static inline void tsa_write8(void __iomem *addr, u32 val)
 {
 	iowrite8(val, addr);
 }
 
-static inline u32 tsa_read32(void *__iomem addr)
+static inline u32 tsa_read32(void __iomem *addr)
 {
 	return ioread32be(addr);
 }
 
-static inline void tsa_clrbits32(void *__iomem addr, u32 clr)
+static inline void tsa_clrbits32(void __iomem *addr, u32 clr)
 {
 	tsa_write32(addr, tsa_read32(addr) & ~clr);
 }
 
-static inline void tsa_clrsetbits32(void *__iomem addr, u32 clr, u32 set)
+static inline void tsa_clrsetbits32(void __iomem *addr, u32 clr, u32 set)
 {
 	tsa_write32(addr, (tsa_read32(addr) & ~clr) | set);
 }
@@ -313,7 +313,7 @@ static u32 tsa_serial_id2csel(struct tsa
 static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area,
 			 u32 count, u32 serial_id)
 {
-	void *__iomem addr;
+	void __iomem *addr;
 	u32 left;
 	u32 val;
 	u32 cnt;
author maintainer
#34 lore raw

PATCH 34/346 soc: fsl: cpm1: qmc: Fix __iomem addresses declaration

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herve Codina <[email protected]>

commit a5ec3a21220da06bdda2e686012ca64fdb6c513d upstream.

Running sparse (make C=1) on qmc.c raises a lot of warning such as:
...
warning: incorrect type in assignment (different address spaces)
expected struct cpm_buf_desc [usertype] *[noderef] __iomem bd got struct cpm_buf_desc [noderef] [usertype] __iomem *txbd_free
...

Indeed, some variable were declared 'type *__iomem var' instead of 'type __iomem *var'.

Use the correct declaration to remove these warnings.

---
 drivers/soc/fsl/qe/qmc.c |   34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)
drivers/soc/fsl/qe/qmc.c +17 -17
@@ -175,7 +175,7 @@ struct qmc_chan {
 	struct list_head list;
 	unsigned int id;
 	struct qmc *qmc;
-	void *__iomem s_param;
+	void __iomem *s_param;
 	enum qmc_mode mode;
 	u64	tx_ts_mask;
 	u64	rx_ts_mask;
@@ -203,9 +203,9 @@ struct qmc_chan {
 struct qmc {
 	struct device *dev;
 	struct tsa_serial *tsa_serial;
-	void *__iomem scc_regs;
-	void *__iomem scc_pram;
-	void *__iomem dpram;
+	void __iomem *scc_regs;
+	void __iomem *scc_pram;
+	void __iomem *dpram;
 	u16 scc_pram_offset;
 	cbd_t __iomem *bd_table;
 	dma_addr_t bd_dma_addr;
@@ -218,37 +218,37 @@ struct qmc {
 	struct qmc_chan *chans[64];
 };
 
-static inline void qmc_write16(void *__iomem addr, u16 val)
+static inline void qmc_write16(void __iomem *addr, u16 val)
 {
 	iowrite16be(val, addr);
 }
 
-static inline u16 qmc_read16(void *__iomem addr)
+static inline u16 qmc_read16(void __iomem *addr)
 {
 	return ioread16be(addr);
 }
 
-static inline void qmc_setbits16(void *__iomem addr, u16 set)
+static inline void qmc_setbits16(void __iomem *addr, u16 set)
 {
 	qmc_write16(addr, qmc_read16(addr) | set);
 }
 
-static inline void qmc_clrbits16(void *__iomem addr, u16 clr)
+static inline void qmc_clrbits16(void __iomem *addr, u16 clr)
 {
 	qmc_write16(addr, qmc_read16(addr) & ~clr);
 }
 
-static inline void qmc_write32(void *__iomem addr, u32 val)
+static inline void qmc_write32(void __iomem *addr, u32 val)
 {
 	iowrite32be(val, addr);
 }
 
-static inline u32 qmc_read32(void *__iomem addr)
+static inline u32 qmc_read32(void __iomem *addr)
 {
 	return ioread32be(addr);
 }
 
-static inline void qmc_setbits32(void *__iomem addr, u32 set)
+static inline void qmc_setbits32(void __iomem *addr, u32 set)
 {
 	qmc_write32(addr, qmc_read32(addr) | set);
 }
@@ -318,7 +318,7 @@ int qmc_chan_write_submit(struct qmc_cha
 {
 	struct qmc_xfer_desc *xfer_desc;
 	unsigned long flags;
-	cbd_t *__iomem bd;
+	cbd_t __iomem *bd;
 	u16 ctrl;
 	int ret;
 
@@ -374,7 +374,7 @@ static void qmc_chan_write_done(struct q
 	void (*complete)(void *context);
 	unsigned long flags;
 	void *context;
-	cbd_t *__iomem bd;
+	cbd_t __iomem *bd;
 	u16 ctrl;
 
 	/*
@@ -425,7 +425,7 @@ int qmc_chan_read_submit(struct qmc_chan
 {
 	struct qmc_xfer_desc *xfer_desc;
 	unsigned long flags;
-	cbd_t *__iomem bd;
+	cbd_t __iomem *bd;
 	u16 ctrl;
 	int ret;
 
@@ -488,7 +488,7 @@ static void qmc_chan_read_done(struct qm
 	void (*complete)(void *context, size_t size);
 	struct qmc_xfer_desc *xfer_desc;
 	unsigned long flags;
-	cbd_t *__iomem bd;
+	cbd_t __iomem *bd;
 	void *context;
 	u16 datalen;
 	u16 ctrl;
@@ -663,7 +663,7 @@ static void qmc_chan_reset_rx(struct qmc
 {
 	struct qmc_xfer_desc *xfer_desc;
 	unsigned long flags;
-	cbd_t *__iomem bd;
+	cbd_t __iomem *bd;
 	u16 ctrl;
 
 	spin_lock_irqsave(&chan->rx_lock, flags);
@@ -694,7 +694,7 @@ static void qmc_chan_reset_tx(struct qmc
 {
 	struct qmc_xfer_desc *xfer_desc;
 	unsigned long flags;
-	cbd_t *__iomem bd;
+	cbd_t __iomem *bd;
 	u16 ctrl;
 
 	spin_lock_irqsave(&chan->tx_lock, flags);
author maintainer
#35 lore raw

PATCH 35/346 soc: fsl: cpm1: qmc: Fix rx channel reset

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Herve Codina <[email protected]>

commit dfe66d012af2ddfa566cf9c860b8472b412fb7e4 upstream.

The qmc_chan_reset_rx() set the is_rx_stopped flag. This leads to an inconsistent state in the following sequence.

    qmc_chan_stop()
    qmc_chan_reset()

Indeed, after the qmc_chan_reset() call, the channel must still be stopped. Only a qmc_chan_start() call can move the channel from stopped state to started state.

Fix the issue removing the is_rx_stopped flag setting from qmc_chan_reset()

---
 drivers/soc/fsl/qe/qmc.c |    1 -
 1 file changed, 1 deletion(-)
drivers/soc/fsl/qe/qmc.c +0 -1
@@ -685,7 +685,6 @@ static void qmc_chan_reset_rx(struct qmc
 		    qmc_read16(chan->s_param + QMC_SPE_RBASE));
 
 	chan->rx_pending = 0;
-	chan->is_rx_stopped = false;
 
 	spin_unlock_irqrestore(&chan->rx_lock, flags);
 }
author maintainer
#36 lore raw

PATCH 36/346 s390/vfio-ap: always filter entire AP matrix

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tony Krowiak <[email protected]>

commit 850fb7fa8c684a4c6bf0e4b6978f4ddcc5d43d11 upstream.

The vfio_ap_mdev_filter_matrix function is called whenever a new adapter or domain is assigned to the mdev. The purpose of the function is to update the guest's AP configuration by filtering the matrix of adapters and domains assigned to the mdev. When an adapter or domain is assigned, only the APQNs associated with the APID of the new adapter or APQI of the new domain are inspected. If an APQN does not reference a queue device bound to the vfio_ap device driver, then it's APID will be filtered from the mdev's matrix when updating the guest's AP configuration.

Inspecting only the APID of the new adapter or APQI of the new domain will result in passing AP queues through to a guest that are not bound to the vfio_ap device driver under certain circumstances. Consider the following:

guest's AP configuration (all also assigned to the mdev's matrix):
14.0004
14.0005
14.0006
16.0004
16.0005
16.0006

unassign domain 4
unbind queue 16.0005
assign domain 4

When domain 4 is re-assigned, since only domain 4 will be inspected, the APQNs that will be examined will be:
14.0004
16.0004

Since both of those APQNs reference queue devices that are bound to the vfio_ap device driver, nothing will get filtered from the mdev's matrix when updating the guest's AP configuration. Consequently, queue 16.0005 will get passed through despite not being bound to the driver. This violates the linux device model requirement that a guest shall only be given access to devices bound to the device driver facilitating their pass-through.

To resolve this problem, every adapter and domain assigned to the mdev will be inspected when filtering the mdev's matrix.

Fixes 48cae940c31d ("s390/vfio-ap: refresh guest's APCB by filtering AP resources assigned to mdev")
---
 drivers/s390/crypto/vfio_ap_ops.c |   57 +++++++++++---------------------------
 1 file changed, 17 insertions(+), 40 deletions(-)
drivers/s390/crypto/vfio_ap_ops.c +17 -40
@@ -671,8 +671,7 @@ static bool vfio_ap_mdev_filter_cdoms(st
  * Return: a boolean value indicating whether the KVM guest's APCB was changed
  *	   by the filtering or not.
  */
-static bool vfio_ap_mdev_filter_matrix(unsigned long *apm, unsigned long *aqm,
-				       struct ap_matrix_mdev *matrix_mdev)
+static bool vfio_ap_mdev_filter_matrix(struct ap_matrix_mdev *matrix_mdev)
 {
 	unsigned long apid, apqi, apqn;
 	DECLARE_BITMAP(prev_shadow_apm, AP_DEVICES);
@@ -693,8 +692,8 @@ static bool vfio_ap_mdev_filter_matrix(u
 	bitmap_and(matrix_mdev->shadow_apcb.aqm, matrix_mdev->matrix.aqm,
 		   (unsigned long *)matrix_dev->info.aqm, AP_DOMAINS);
 
-	for_each_set_bit_inv(apid, apm, AP_DEVICES) {
-		for_each_set_bit_inv(apqi, aqm, AP_DOMAINS) {
+	for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, AP_DEVICES) {
+		for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, AP_DOMAINS) {
 			/*
 			 * If the APQN is not bound to the vfio_ap device
 			 * driver, then we can't assign it to the guest's
@@ -959,7 +958,6 @@ static ssize_t assign_adapter_store(stru
 {
 	int ret;
 	unsigned long apid;
-	DECLARE_BITMAP(apm_delta, AP_DEVICES);
 	struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
 
 	mutex_lock(&ap_perms_mutex);
@@ -988,11 +986,8 @@ static ssize_t assign_adapter_store(stru
 	}
 
 	vfio_ap_mdev_link_adapter(matrix_mdev, apid);
-	memset(apm_delta, 0, sizeof(apm_delta));
-	set_bit_inv(apid, apm_delta);
 
-	if (vfio_ap_mdev_filter_matrix(apm_delta,
-				       matrix_mdev->matrix.aqm, matrix_mdev))
+	if (vfio_ap_mdev_filter_matrix(matrix_mdev))
 		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 
 	ret = count;
@@ -1168,7 +1163,6 @@ static ssize_t assign_domain_store(struc
 {
 	int ret;
 	unsigned long apqi;
-	DECLARE_BITMAP(aqm_delta, AP_DOMAINS);
 	struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev);
 
 	mutex_lock(&ap_perms_mutex);
@@ -1197,11 +1191,8 @@ static ssize_t assign_domain_store(struc
 	}
 
 	vfio_ap_mdev_link_domain(matrix_mdev, apqi);
-	memset(aqm_delta, 0, sizeof(aqm_delta));
-	set_bit_inv(apqi, aqm_delta);
 
-	if (vfio_ap_mdev_filter_matrix(matrix_mdev->matrix.apm, aqm_delta,
-				       matrix_mdev))
+	if (vfio_ap_mdev_filter_matrix(matrix_mdev))
 		vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 
 	ret = count;
@@ -2092,9 +2083,7 @@ int vfio_ap_mdev_probe_queue(struct ap_d
 	if (matrix_mdev) {
 		vfio_ap_mdev_link_queue(matrix_mdev, q);
 
-		if (vfio_ap_mdev_filter_matrix(matrix_mdev->matrix.apm,
-					       matrix_mdev->matrix.aqm,
-					       matrix_mdev))
+		if (vfio_ap_mdev_filter_matrix(matrix_mdev))
 			vfio_ap_mdev_update_guest_apcb(matrix_mdev);
 	}
 	dev_set_drvdata(&apdev->device, q);
@@ -2444,34 +2433,22 @@ void vfio_ap_on_cfg_changed(struct ap_co
 
 static void vfio_ap_mdev_hot_plug_cfg(struct ap_matrix_mdev *matrix_mdev)
 {
-	bool do_hotplug = false;
-	int filter_domains = 0;
-	int filter_adapters = 0;
-	DECLARE_BITMAP(apm, AP_DEVICES);
-	DECLARE_BITMAP(aqm, AP_DOMAINS);
+	bool filter_domains, filter_adapters, filter_cdoms, do_hotplug = false;
 
 	mutex_lock(&matrix_mdev->kvm->lock);
 	mutex_lock(&matrix_dev->mdevs_lock);
 
-	filter_adapters = bitmap_and(apm, matrix_mdev->matrix.apm,
-				     matrix_mdev->apm_add, AP_DEVICES);
-	filter_domains = bitmap_and(aqm, matrix_mdev->matrix.aqm,
-				    matrix_mdev->aqm_add, AP_DOMAINS);
-
-	if (filter_adapters && filter_domains)
-		do_hotplug |= vfio_ap_mdev_filter_matrix(apm, aqm, matrix_mdev);
-	else if (filter_adapters)
-		do_hotplug |=
-			vfio_ap_mdev_filter_matrix(apm,
-						   matrix_mdev->shadow_apcb.aqm,
-						   matrix_mdev);
-	else
-		do_hotplug |=
-			vfio_ap_mdev_filter_matrix(matrix_mdev->shadow_apcb.apm,
-						   aqm, matrix_mdev);
+	filter_adapters = bitmap_intersects(matrix_mdev->matrix.apm,
+					    matrix_mdev->apm_add, AP_DEVICES);
+	filter_domains = bitmap_intersects(matrix_mdev->matrix.aqm,
+					   matrix_mdev->aqm_add, AP_DOMAINS);
+	filter_cdoms = bitmap_intersects(matrix_mdev->matrix.adm,
+					 matrix_mdev->adm_add, AP_DOMAINS);
+
+	if (filter_adapters || filter_domains)
+		do_hotplug = vfio_ap_mdev_filter_matrix(matrix_mdev);
 
-	if (bitmap_intersects(matrix_mdev->matrix.adm, matrix_mdev->adm_add,
-			      AP_DOMAINS))
+	if (filter_cdoms)
 		do_hotplug |= vfio_ap_mdev_filter_cdoms(matrix_mdev);
 
 	if (do_hotplug)
author maintainer
#37 lore raw

PATCH 37/346 s390/vfio-ap: loop over the shadow APCB when filtering guests AP configuration

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tony Krowiak <[email protected]>

commit 16fb78cbf56e42b8efb2682a4444ab59e32e7959 upstream.

While filtering the mdev matrix, it doesn't make sense - and will have unexpected results - to filter an APID from the matrix if the APID or one of the associated APQIs is not in the host's AP configuration. There are two reasons for this:

1. An adapter or domain that is not in the host's AP configuration can be assigned to the matrix; this is known as over-provisioning. Queue devices, however, are only created for adapters and domains in the host's AP configuration, so there will be no queues associated with an over-provisioned adapter or domain to filter.

2. The adapter or domain may have been externally removed from the host's configuration via an SE or HMC attached to a DPM enabled LPAR. In this case, the vfio_ap device driver would have been notified by the AP bus via the on_config_changed callback and the adapter or domain would have already been filtered.

Since the matrix_mdev->shadow_apcb.apm and matrix_mdev->shadow_apcb.aqm are copied from the mdev matrix sans the APIDs and APQIs not in the host's AP configuration, let's loop over those bitmaps instead of those assigned to the matrix.

Fixes 48cae940c31d ("s390/vfio-ap: refresh guest's APCB by filtering AP resources assigned to mdev")
---
 drivers/s390/crypto/vfio_ap_ops.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/s390/crypto/vfio_ap_ops.c +3 -2
@@ -692,8 +692,9 @@ static bool vfio_ap_mdev_filter_matrix(s
 	bitmap_and(matrix_mdev->shadow_apcb.aqm, matrix_mdev->matrix.aqm,
 		   (unsigned long *)matrix_dev->info.aqm, AP_DOMAINS);
 
-	for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, AP_DEVICES) {
-		for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, AP_DOMAINS) {
+	for_each_set_bit_inv(apid, matrix_mdev->shadow_apcb.apm, AP_DEVICES) {
+		for_each_set_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm,
+				     AP_DOMAINS) {
 			/*
 			 * If the APQN is not bound to the vfio_ap device
 			 * driver, then we can't assign it to the guest's
author maintainer
#28 lore raw

PATCH 28/346 media: imx355: Enable runtime PM before registering async sub-device

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bingbu Cao <[email protected]>

commit efa5fe19c0a9199f49e36e1f5242ed5c88da617d upstream.

As the sensor device maybe accessible right after its async sub-device is registered, such as ipu-bridge will try to power up sensor by sensor's client device's runtime PM from the async notifier callback, if runtime PM is not enabled, it will fail.

So runtime PM should be ready before its async sub-device is registered and accessible by others.

Fixes df0b5c4a7ddd ("media: add imx355 camera sensor driver")
---
 drivers/media/i2c/imx355.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/media/i2c/imx355.c +7 -5
@@ -1748,10 +1748,6 @@ static int imx355_probe(struct i2c_clien
 		goto error_handler_free;
 	}
 
-	ret = v4l2_async_register_subdev_sensor(&imx355->sd);
-	if (ret < 0)
-		goto error_media_entity;
-
 	/*
 	 * Device is already turned on by i2c-core with ACPI domain PM.
 	 * Enable runtime PM and turn off the device.
@@ -1760,9 +1756,15 @@ static int imx355_probe(struct i2c_clien
 	pm_runtime_enable(&client->dev);
 	pm_runtime_idle(&client->dev);
 
+	ret = v4l2_async_register_subdev_sensor(&imx355->sd);
+	if (ret < 0)
+		goto error_media_entity_runtime_pm;
+
 	return 0;
 
-error_media_entity:
+error_media_entity_runtime_pm:
+	pm_runtime_disable(&client->dev);
+	pm_runtime_set_suspended(&client->dev);
 	media_entity_cleanup(&imx355->sd.entity);
 
 error_handler_free:
author maintainer
#56 lore raw

PATCH 56/346 riscv: Fix module loading free order

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Charlie Jenkins <[email protected]>

[ Upstream commit 78996eee79ebdfe8b6f0e54cb6dcc792d5129291 ]

Reverse order of kfree calls to resolve use-after-free error.

---
 arch/riscv/kernel/module.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/module.c +1 -1
index 862834bb1d64..5cf3a693482d 100644
@@ -723,8 +723,8 @@ static int add_relocation_to_accumulate(struct module *me, int type,
 
 			if (!bucket) {
 				kfree(entry);
-				kfree(rel_head);
 				kfree(rel_head->rel_entry);
+				kfree(rel_head);
 				return -ENOMEM;
 			}
 
Signature · 1 line
2.43.0
author maintainer
#65 lore raw

PATCH 65/346 ARM: dts: imx6q-apalis: add can power-up delay on ixora board

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andrejs Cainikovs <[email protected]>

commit b76bbf835d8945080b22b52fc1e6f41cde06865d upstream.

Newer variants of Ixora boards require a power-up delay when powering up the CAN transceiver of up to 1ms.

---
 arch/arm/boot/dts/nxp/imx/imx6q-apalis-ixora-v1.2.dts |    2 ++
 1 file changed, 2 insertions(+)
arch/arm/boot/dts/nxp/imx/imx6q-apalis-ixora-v1.2.dts +2 -0
@@ -76,6 +76,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_enable_can1_power>;
 		regulator-name = "can1_supply";
+		startup-delay-us = <1000>;
 	};
 
 	reg_can2_supply: regulator-can2-supply {
@@ -85,6 +86,7 @@
 		pinctrl-names = "default";
 		pinctrl-0 = <&pinctrl_enable_can2_power>;
 		regulator-name = "can2_supply";
+		startup-delay-us = <1000>;
 	};
 };
 
author maintainer
#66 lore raw

PATCH 66/346 arm64: dts: qcom: sc8280xp-crd: fix eDP phy compatible

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 663affdb12b3e26c77d103327cf27de720c8117e upstream.

The sc8280xp Display Port PHYs can be used in either DP or eDP mode and this is configured using the devicetree compatible string which defaults to DP mode in the SoC dtsi.

Override the default compatible string for the CRD eDP PHY node so that the eDP settings are used.

Fixes 4a883a8d80b5 ("arm64: dts: qcom: sc8280xp-crd: Enable EDP")
---
 arch/arm64/boot/dts/qcom/sc8280xp-crd.dts |    2 ++
 1 file changed, 2 insertions(+)
arch/arm64/boot/dts/qcom/sc8280xp-crd.dts +2 -0
@@ -458,6 +458,8 @@
 };
 
 &mdss0_dp3_phy {
+	compatible = "qcom,sc8280xp-edp-phy";
+
 	vdda-phy-supply = <&vreg_l6b>;
 	vdda-pll-supply = <&vreg_l3b>;
 
author maintainer
#67 lore raw

PATCH 67/346 ARM: dts: qcom: sdx55: fix USB wakeup interrupt types

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit d0ec3c4c11c3b30e1f2d344973b2a7bf0f986734 upstream.

The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.

Fixes fea4b41022f3 ("ARM: dts: qcom: sdx55: Add USB3 and PHY support")
Cc Manivannan Sadhasivam <[email protected]>
---
 arch/arm/boot/dts/qcom/qcom-sdx55.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/qcom/qcom-sdx55.dtsi +2 -2
@@ -587,8 +587,8 @@
 
 			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 158 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 157 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#68 lore raw

PATCH 68/346 ARM: dts: samsung: exynos4210-i9100: Unconditionally enable LDO12

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paul Cercueil <[email protected]>

commit 84228d5e29dbc7a6be51e221000e1d122125826c upstream.

The kernel hangs for a good 12 seconds without any info being printed to dmesg, very early in the boot process, if this regulator is not enabled.

Force-enable it to work around this issue, until we know more about the underlying problem.

Fixes 8620cc2f99b7 ("ARM: dts: exynos: Add devicetree file for the Galaxy S2")
---
 arch/arm/boot/dts/samsung/exynos4210-i9100.dts |    8 ++++++++
 1 file changed, 8 insertions(+)
arch/arm/boot/dts/samsung/exynos4210-i9100.dts +8 -0
@@ -527,6 +527,14 @@
 				regulator-name = "VT_CAM_1.8V";
 				regulator-min-microvolt = <1800000>;
 				regulator-max-microvolt = <1800000>;
+
+				/*
+				 * Force-enable this regulator; otherwise the
+				 * kernel hangs very early in the boot process
+				 * for about 12 seconds, without apparent
+				 * reason.
+				 */
+				regulator-always-on;
 			};
 
 			vcclcd_reg: LDO13 {
author maintainer
#69 lore raw

PATCH 69/346 ARM: dts: qcom: sdx55: fix pdc #interrupt-cells

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit cc25bd06c16aa582596a058d375b2e3133f79b93 upstream.

The Qualcomm PDC interrupt controller binding expects two cells in interrupt specifiers.

Fixes 9d038b2e62de ("ARM: dts: qcom: Add SDX55 platform and MTP board support")
Cc Manivannan Sadhasivam <[email protected]>
---
 arch/arm/boot/dts/qcom/qcom-sdx55.dtsi |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/qcom/qcom-sdx55.dtsi +1 -1
@@ -612,7 +612,7 @@
 			compatible = "qcom,sdx55-pdc", "qcom,pdc";
 			reg = <0x0b210000 0x30000>;
 			qcom,pdc-ranges = <0 179 52>;
-			#interrupt-cells = <3>;
+			#interrupt-cells = <2>;
 			interrupt-parent = <&intc>;
 			interrupt-controller;
 		};
author maintainer
#70 lore raw

PATCH 70/346 arm64: dts: sprd: fix the cpu node for UMS512

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Cixi Geng <[email protected]>

commit 2da4f4a7b003441b80f0f12d8a216590f652a40f upstream.

The UMS512 Socs have 8 cores contains 6 a55 and 2 a75. modify the cpu nodes to correct information.

Fixes 2b4881839a39 ("arm64: dts: sprd: Add support for Unisoc's UMS512")
---
 arch/arm64/boot/dts/sprd/ums512.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/sprd/ums512.dtsi +2 -2
@@ -96,7 +96,7 @@
 
 		CPU6: cpu@600 {
 			device_type = "cpu";
-			compatible = "arm,cortex-a55";
+			compatible = "arm,cortex-a75";
 			reg = <0x0 0x600>;
 			enable-method = "psci";
 			cpu-idle-states = <&CORE_PD>;
@@ -104,7 +104,7 @@
 
 		CPU7: cpu@700 {
 			device_type = "cpu";
-			compatible = "arm,cortex-a55";
+			compatible = "arm,cortex-a75";
 			reg = <0x0 0x700>;
 			enable-method = "psci";
 			cpu-idle-states = <&CORE_PD>;
author maintainer
#71 lore raw

PATCH 71/346 arm64: dts: rockchip: configure eth pad driver strength for orangepi r1 plus lts

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Tianling Shen <[email protected]>

commit fc5a80a432607d05e85bba37971712405f75c546 upstream.

The default strength is not enough to provide stable connection under 3.3v LDO voltage.

Fixes 387b3bbac5ea ("arm64: dts: rockchip: Add Xunlong OrangePi R1 Plus LTS")
---
 arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +3 -1
@@ -26,9 +26,11 @@
 			compatible = "ethernet-phy-ieee802.3-c22";
 			reg = <0>;
 
+			motorcomm,auto-sleep-disabled;
 			motorcomm,clk-out-frequency-hz = <125000000>;
 			motorcomm,keep-pll-enabled;
-			motorcomm,auto-sleep-disabled;
+			motorcomm,rx-clk-drv-microamp = <5020>;
+			motorcomm,rx-data-drv-microamp = <5020>;
 
 			pinctrl-0 = <&eth_phy_reset_pin>;
 			pinctrl-names = "default";
author maintainer
#72 lore raw

PATCH 72/346 arm64: dts: rockchip: Fix rk3588 USB power-domain clocks

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Sam Edwards <[email protected]>

commit 44de8996ed5a10f08f2fe947182da6535edcfae5 upstream.

The QoS blocks saved/restored when toggling the PD_USB power domain are clocked by ACLK_USB. Attempting to access these memory regions without that clock running will result in an indefinite CPU stall.

The PD_USB node wasn't specifying this clock dependency, resulting in hangs when trying to toggle the power domain (either on or off), unless we get "lucky" and have ACLK_USB running for another reason at the time. This "luck" can result from the bootloader leaving USB powered/clocked, and if no built-in driver wants USB, Linux will disable the unused PD+CLK on boot when {pd,clk}_ignore_unused aren't given. This can also be unlucky because the two cleanup tasks run in parallel and race: if the CLK is disabled first, the PD deactivation stalls the boot. In any case, the PD cannot then be reenabled (if e.g. the driver loads later) once the clock has been stopped.

Fix this by specifying a dependency on ACLK_USB, instead of only ACLK_USB_ROOT. The child-parent relationship means the former implies the latter anyway.

Fixes c9211fa2602b8 ("arm64: dts: rockchip: Add base DT for rk3588 SoC")
[changed to only include the missing clock, not dropping the root-clocks]
---
 arch/arm64/boot/dts/rockchip/rk3588s.dtsi |    1 +
 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/rockchip/rk3588s.dtsi +1 -0
@@ -916,6 +916,7 @@
 				reg = <RK3588_PD_USB>;
 				clocks = <&cru PCLK_PHP_ROOT>,
 					 <&cru ACLK_USB_ROOT>,
+					 <&cru ACLK_USB>,
 					 <&cru HCLK_USB_ROOT>,
 					 <&cru HCLK_HOST0>,
 					 <&cru HCLK_HOST_ARB0>,
author maintainer
#73 lore raw

PATCH 73/346 arm64: dts: qcom: msm8916: Make blsp_dma controlled-remotely

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stephan Gerhold <[email protected]>

commit 7c45b6ddbcff01f9934d11802010cfeb0879e693 upstream.

The blsp_dma controller is shared between the different subsystems, which is why it is already initialized by the firmware. We should not reinitialize it from Linux to avoid potential other users of the DMA engine to misbehave.

In mainline this can be described using the "qcom,controlled-remotely" property. In the downstream/vendor kernel from Qualcomm there is an opposite "qcom,managed-locally" property. This property is *not* set for the qcom,sps-dma@7884000 [1] so adding "qcom,controlled-remotely" upstream matches the behavior of the downstream/vendor kernel.

Adding this seems to fix some weird issues with UART where both input/output becomes garbled with certain obscure firmware versions on some devices.

[1]: https://git.codelinaro.org/clo/la/kernel/msm-3.10/-/blob/LA.BR.1.2.9.1-02310-8x16.0/arch/arm/boot/dts/qcom/msm8916.dtsi#L1466-1472

---
 arch/arm64/boot/dts/qcom/msm8916.dtsi |    1 +
 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/qcom/msm8916.dtsi +1 -0
@@ -2106,6 +2106,7 @@
 			clock-names = "bam_clk";
 			#dma-cells = <1>;
 			qcom,ee = <0>;
+			qcom,controlled-remotely;
 		};
 
 		blsp_uart1: serial@78af000 {
author maintainer
#74 lore raw

PATCH 74/346 arm64: dts: qcom: msm8939: Make blsp_dma controlled-remotely

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stephan Gerhold <[email protected]>

commit 4bbda9421f316efdaef5dbf642e24925ef7de130 upstream.

The blsp_dma controller is shared between the different subsystems, which is why it is already initialized by the firmware. We should not reinitialize it from Linux to avoid potential other users of the DMA engine to misbehave.

In mainline this can be described using the "qcom,controlled-remotely" property. In the downstream/vendor kernel from Qualcomm there is an opposite "qcom,managed-locally" property. This property is *not* set for the qcom,sps-dma@7884000 [1] so adding "qcom,controlled-remotely" upstream matches the behavior of the downstream/vendor kernel.

Adding this seems to fix some weird issues with UART where both input/output becomes garbled with certain obscure firmware versions on some devices.

[1]: https://git.codelinaro.org/clo/la/kernel/msm-3.10/-/blob/LA.BR.1.2.9.1-02310-8x16.0/arch/arm/boot/dts/qcom/msm8939-common.dtsi#L866-872

---
 arch/arm64/boot/dts/qcom/msm8939.dtsi |    1 +
 1 file changed, 1 insertion(+)
arch/arm64/boot/dts/qcom/msm8939.dtsi +1 -0
@@ -1682,6 +1682,7 @@
 			clock-names = "bam_clk";
 			#dma-cells = <1>;
 			qcom,ee = <0>;
+			qcom,controlled-remotely;
 		};
 
 		blsp_uart1: serial@78af000 {
author maintainer
#57 lore raw

PATCH 57/346 riscv: Correctly free relocation hashtable on error

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Charlie Jenkins <[email protected]>

[ Upstream commit 4b38b36bfbd83b23e20c172d08dd85773791e3bd ]

When there is not enough allocatable memory for the relocation hashtable, module loading should exit gracefully. Previously, this was attempted to be accomplished by checking if an unsigned number is less than zero which does not work. Instead have the caller check if the hashtable was correctly allocated and add a comment explaining that hashtable_bits that is 0 is valid.

---
 arch/riscv/kernel/module.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
arch/riscv/kernel/module.c +7 -3
index 5cf3a693482d..91f7cd221afc 100644
@@ -747,6 +747,10 @@ initialize_relocation_hashtable(unsigned int num_relocations,
 {
 	/* Can safely assume that bits is not greater than sizeof(long) */
 	unsigned long hashtable_size = roundup_pow_of_two(num_relocations);
+	/*
+	 * When hashtable_size == 1, hashtable_bits == 0.
+	 * This is valid because the hashing algorithm returns 0 in this case.
+	 */
 	unsigned int hashtable_bits = ilog2(hashtable_size);
 
 	/*
@@ -763,7 +767,7 @@ initialize_relocation_hashtable(unsigned int num_relocations,
 					      sizeof(*relocation_hashtable),
 					      GFP_KERNEL);
 	if (!*relocation_hashtable)
-		return -ENOMEM;
+		return 0;
 
 	__hash_init(*relocation_hashtable, hashtable_size);
 
@@ -789,8 +793,8 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
 	hashtable_bits = initialize_relocation_hashtable(num_relocations,
 							 &relocation_hashtable);
 
-	if (hashtable_bits < 0)
-		return hashtable_bits;
+	if (!relocation_hashtable)
+		return -ENOMEM;
 
 	INIT_LIST_HEAD(&used_buckets_list);
 
Signature · 1 line
2.43.0
author maintainer
#75 lore raw

PATCH 75/346 arm64: dts: qcom: sc7180: fix USB wakeup interrupt types

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 9b956999bf725fd62613f719c3178fdbee6e5f47 upstream.

The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.

Fixes 0b766e7fe5a2 ("arm64: dts: qcom: sc7180: Add USB related nodes")
---
 arch/arm64/boot/dts/qcom/sc7180.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sc7180.dtsi +2 -2
@@ -2966,8 +2966,8 @@
 
 			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 8 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 9 IRQ_TYPE_LEVEL_HIGH>;
+					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#76 lore raw

PATCH 76/346 arm64: dts: qcom: sdm845: fix USB wakeup interrupt types

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 84ad9ac8d9ca29033d589e79a991866b38e23b85 upstream.

The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.

Fixes ca4db2b538a1 ("arm64: dts: qcom: sdm845: Add USB-related nodes")
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/qcom/sdm845.dtsi +4 -4
@@ -4055,8 +4055,8 @@
 
 			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
@@ -4106,8 +4106,8 @@
 
 			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#77 lore raw

PATCH 77/346 arm64: dts: qcom: sdm670: fix USB wakeup interrupt types

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit de3b3de30999106549da4df88a7963d0ac02b91e upstream.

The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.

Fixes 07c8ded6e373 ("arm64: dts: qcom: add sdm670 and pixel 3a device trees")
Cc Richard Acayan <[email protected]>
---
 arch/arm64/boot/dts/qcom/sdm670.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sdm670.dtsi +2 -2
@@ -1297,8 +1297,8 @@
 
 			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#78 lore raw

PATCH 78/346 arm64: dts: qcom: sm8150: fix USB wakeup interrupt types

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 54524b6987d1fffe64cbf3dded1b2fa6b903edf9 upstream.

The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.

Fixes 0c9dde0d2015 ("arm64: dts: qcom: sm8150: Add secondary USB and PHY nodes")
Fixes b33d2868e8d3 ("arm64: dts: qcom: sm8150: Add USB and PHY device nodes")
Cc Jonathan Marek <[email protected]>
Cc Jack Pham <[email protected]>
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/qcom/sm8150.dtsi +4 -4
@@ -3567,8 +3567,8 @@
 
 			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
@@ -3620,8 +3620,8 @@
 
 			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#79 lore raw

PATCH 79/346 arm64: dts: qcom: sc8180x: fix USB wakeup interrupt types

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 0dc0f6da3d43da8d2297105663e51ecb01b6f790 upstream.

The DP/DM wakeup interrupts are edge triggered and which edge to trigger on depends on use-case and whether a Low speed or Full/High speed device is connected.

Fixes b080f53a8f44 ("arm64: dts: qcom: sc8180x: Add remoteprocs, wifi and usb nodes")
Cc Vinod Koul <[email protected]>
---
 arch/arm64/boot/dts/qcom/sc8180x.dtsi |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/qcom/sc8180x.dtsi +4 -4
@@ -2554,8 +2554,8 @@
 			reg = <0 0x0a6f8800 0 0x400>;
 			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq",
 					  "ss_phy_irq",
 					  "dm_hs_phy_irq",
@@ -2628,8 +2628,8 @@
 			power-domains = <&gcc USB30_SEC_GDSC>;
 			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
 				     <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>;
+				     <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>,
+				     <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#80 lore raw

PATCH 80/346 arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit c34199d967a946e55381404fa949382691737521 upstream.

A recent cleanup reordering the usb_1 wakeup interrupts inadvertently switched the DP and SuperSpeed interrupt trigger types.

Fixes 4a7ffc10d195 ("arm64: dts: qcom: align DWC3 USB interrupts with DT schema")
Cc Krzysztof Kozlowski <[email protected]>
---
 arch/arm64/boot/dts/qcom/sc7280.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sc7280.dtsi +2 -2
@@ -3685,9 +3685,9 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&pdc 14 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 14 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 15 IRQ_TYPE_EDGE_BOTH>,
-					      <&pdc 17 IRQ_TYPE_EDGE_BOTH>;
+					      <&pdc 17 IRQ_TYPE_LEVEL_HIGH>;
 			interrupt-names = "hs_phy_irq",
 					  "dp_hs_phy_irq",
 					  "dm_hs_phy_irq",
author maintainer
#81 lore raw

PATCH 81/346 arm64: dts: qcom: Add missing vio-supply for AW2013

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Stephan Gerhold <[email protected]>

commit cc1ec484f2d0f464ad11b56fe3de2589c23f73ec upstream.

Add the missing vio-supply to all usages of the AW2013 LED controller to ensure that the regulator needed for pull-up of the interrupt and I2C lines is really turned on. While this seems to have worked fine so far some of these regulators are not guaranteed to be always-on. For example, pm8916_l6 is typically turned off together with the display if there aren't any other devices (e.g. sensors) keeping it always-on.

---
 arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts  |    1 +
 arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts |    1 +
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts      |    1 +
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts    |    1 +
 arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts     |    1 +
 5 files changed, 5 insertions(+)
arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts +1 -0
@@ -93,6 +93,7 @@
 		#size-cells = <0>;
 
 		vcc-supply = <&pm8916_l17>;
+		vio-supply = <&pm8916_l6>;
 
 		led@0 {
 			reg = <0>;
arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts +1 -0
@@ -118,6 +118,7 @@
 		#size-cells = <0>;
 
 		vcc-supply = <&pm8916_l16>;
+		vio-supply = <&pm8916_l5>;
 
 		led@0 {
 			reg = <0>;
arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts +1 -0
@@ -111,6 +111,7 @@
 		reg = <0x45>;
 
 		vcc-supply = <&pm8953_l10>;
+		vio-supply = <&pm8953_l5>;
 
 		#address-cells = <1>;
 		#size-cells = <0>;
arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts +1 -0
@@ -104,6 +104,7 @@
 		reg = <0x45>;
 
 		vcc-supply = <&pm8953_l10>;
+		vio-supply = <&pm8953_l5>;
 
 		#address-cells = <1>;
 		#size-cells = <0>;
arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts +1 -0
@@ -113,6 +113,7 @@
 		reg = <0x45>;
 
 		vcc-supply = <&pm8953_l10>;
+		vio-supply = <&pm8953_l5>;
 
 		#address-cells = <1>;
 		#size-cells = <0>;
author maintainer
#82 lore raw

PATCH 82/346 ARM: dts: qcom: sdx55: fix USB DP/DM HS PHY interrupts

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit de95f139394a5ed82270f005bc441d2e7c1e51b7 upstream.

The USB DP/DM HS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states and to be able to detect disconnect events, which requires triggering on falling edges.

A recent commit updated the trigger type but failed to change the interrupt provider as required. This leads to the current Linux driver failing to probe instead of printing an error during suspend and USB wakeup not working as intended.

Fixes d0ec3c4c11c3 ("ARM: dts: qcom: sdx55: fix USB wakeup interrupt types")
Fixes fea4b41022f3 ("ARM: dts: qcom: sdx55: Add USB3 and PHY support")
Cc Manivannan Sadhasivam <[email protected]>
---
 arch/arm/boot/dts/qcom/qcom-sdx55.dtsi |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm/boot/dts/qcom/qcom-sdx55.dtsi +4 -4
@@ -585,10 +585,10 @@
 					  <&gcc GCC_USB30_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 158 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 157 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#58 lore raw

PATCH 58/346 riscv: Fix relocation_hashtable size

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Charlie Jenkins <[email protected]>

[ Upstream commit a35551c7244d9d061643a01eb96cc3ba04eaf45c ]

A second dereference is needed to get the accurate size of the relocation_hashtable.

---
 arch/riscv/kernel/module.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/module.c +1 -1
index 91f7cd221afc..c9d59a5448b6 100644
@@ -764,7 +764,7 @@ initialize_relocation_hashtable(unsigned int num_relocations,
 	hashtable_size <<= should_double_size;
 
 	*relocation_hashtable = kmalloc_array(hashtable_size,
-					      sizeof(*relocation_hashtable),
+					      sizeof(**relocation_hashtable),
 					      GFP_KERNEL);
 	if (!*relocation_hashtable)
 		return 0;
Signature · 1 line
2.43.0
author maintainer
#83 lore raw

PATCH 83/346 arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 204f9ed4bad6293933179517624143b8f412347c upstream.

The USB DP/DM HS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states and to be able to detect disconnect events, which requires triggering on falling edges.

A recent commit updated the trigger type but failed to change the interrupt provider as required. This leads to the current Linux driver failing to probe instead of printing an error during suspend and USB wakeup not working as intended.

Fixes 84ad9ac8d9ca ("arm64: dts: qcom: sdm845: fix USB wakeup interrupt types")
Fixes ca4db2b538a1 ("arm64: dts: qcom: sdm845: Add USB-related nodes")
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/qcom/sdm845.dtsi +8 -8
@@ -4053,10 +4053,10 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <150000000>;
 
-			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc_intc 8 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
@@ -4104,10 +4104,10 @@
 					  <&gcc GCC_USB30_SEC_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <150000000>;
 
-			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc_intc 10 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#59 lore raw

PATCH 59/346 riscv: Fix an off-by-one in get_early_cmdline()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Christophe JAILLET <[email protected]>

[ Upstream commit adb1f95d388a43c4c564ef3e436f18900dde978e ]

The ending NULL is not taken into account by strncat(), so switch to strlcat() to correctly compute the size of the available memory when appending CONFIG_CMDLINE to 'early_cmdline'.

---
 arch/riscv/kernel/pi/cmdline_early.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/riscv/kernel/pi/cmdline_early.c +1 -2
index 68e786c84c94..f6d4dedffb84 100644
@@ -38,8 +38,7 @@ static char *get_early_cmdline(uintptr_t dtb_pa)
 	if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) ||
 	    IS_ENABLED(CONFIG_CMDLINE_FORCE) ||
 	    fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */) {
-		strncat(early_cmdline, CONFIG_CMDLINE,
-			COMMAND_LINE_SIZE - fdt_cmdline_size);
+		strlcat(early_cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 	}
 
 	return early_cmdline;
Signature · 1 line
2.43.0
author maintainer
#60 lore raw

PATCH 60/346 scsi: core: Kick the requeue list after inserting when flushing

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Niklas Cassel <[email protected]>

[ Upstream commit 6df0e077d76bd144c533b61d6182676aae6b0a85 ]

When libata calls ata_link_abort() to abort all ata queued commands, it calls blk_abort_request() on the SCSI command representing each QC.

This causes scsi_timeout() to be called, which calls scsi_eh_scmd_add() for each SCSI command.

scsi_eh_scmd_add() sets the SCSI host to state recovery, and then adds the command to shost->eh_cmd_q.

This will wake up the SCSI EH, and eventually the libata EH strategy handler will be called, which calls scsi_eh_flush_done_q() to either flush retry or flush finish each failed command.

The commands that are flush retried by scsi_eh_flush_done_q() are done so using scsi_queue_insert().

Before commit 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary"), __scsi_queue_insert() called blk_mq_requeue_request() with the second argument set to true, indicating that it should always kick/run the requeue list after inserting.

After commit 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary"), __scsi_queue_insert() does not kick/run the requeue list after inserting, if the current SCSI host state is recovery (which is the case in the libata example above).

This optimization is probably fine in most cases, as I can only assume that most often someone will eventually kick/run the queues.

However, that is not the case for scsi_eh_flush_done_q(), where we can see that the request gets inserted to the requeue list, but the queue is never started after the request has been inserted, leading to the block layer waiting for the completion of command that never gets to run.

Since scsi_eh_flush_done_q() is called by SCSI EH context, the SCSI host state is most likely always in recovery when this function is called.

Thus, let scsi_eh_flush_done_q() explicitly kick the requeue list after inserting a flush retry command, so that scsi_eh_flush_done_q() keeps the same behavior as before commit 8b566edbdbfb ("scsi: core: Only kick the requeue list if necessary").

Simple reproducer for the libata example above:

$ hdparm -Y /dev/sda
$ echo 1 > /sys/class/scsi_device/0\:0\:0\:0/device/delete
---
 drivers/scsi/scsi_error.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/scsi/scsi_error.c +6 -3
index 1223d34c04da..d983f4a0e9f1 100644
@@ -2196,15 +2196,18 @@ void scsi_eh_flush_done_q(struct list_head *done_q)
 	struct scsi_cmnd *scmd, *next;
 
 	list_for_each_entry_safe(scmd, next, done_q, eh_entry) {
+		struct scsi_device *sdev = scmd->device;
+
 		list_del_init(&scmd->eh_entry);
-		if (scsi_device_online(scmd->device) &&
-		    !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd) &&
-			scsi_eh_should_retry_cmd(scmd)) {
+		if (scsi_device_online(sdev) && !scsi_noretry_cmd(scmd) &&
+		    scsi_cmd_retry_allowed(scmd) &&
+		    scsi_eh_should_retry_cmd(scmd)) {
 			SCSI_LOG_ERROR_RECOVERY(3,
 				scmd_printk(KERN_INFO, scmd,
 					     "%s: flush retry cmd\n",
 					     current->comm));
 				scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY);
+				blk_mq_kick_requeue_list(sdev->request_queue);
 		} else {
 			/*
 			 * If just we got sense for the device (called
Signature · 1 line
2.43.0
author maintainer
#61 lore raw

PATCH 61/346 sh: ecovec24: Rename missed backlight field from fbdev to dev

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Geert Uytterhoeven <[email protected]>

[ Upstream commit d87123aa9a7920e88633ffc5c5a0a22ab08bdc06 ]

One instance of gpio_backlight_platform_data.fbdev was renamed, but the second instance was forgotten, causing a build failure:

arch/sh/boards/mach-ecovec24/setup.c: In function ‘arch_setup’:
arch/sh/boards/mach-ecovec24/setup.c:1223:37: error: ‘struct gpio_backlight_platform_data’ has no member named ‘fbdev’; did you mean ‘dev’?
1223 | gpio_backlight_data.fbdev = NULL;
| ^~~~~
| dev

Fix this by updating the second instance.

---
 arch/sh/boards/mach-ecovec24/setup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sh/boards/mach-ecovec24/setup.c +1 -1
index 0f279360838a..30d117f9ad7e 100644
@@ -1220,7 +1220,7 @@ static int __init arch_setup(void)
 		lcdc_info.ch[0].num_modes		= ARRAY_SIZE(ecovec_dvi_modes);
 
 		/* No backlight */
-		gpio_backlight_data.fbdev = NULL;
+		gpio_backlight_data.dev = NULL;
 
 		gpio_set_value(GPIO_PTA2, 1);
 		gpio_set_value(GPIO_PTU1, 1);
Signature · 1 line
2.43.0
author maintainer
#62 lore raw

PATCH 62/346 smb: client: fix parsing of SMB3.1.1 POSIX create context

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Paulo Alcantara <[email protected]>

[ Upstream commit 76025cc2285d9ede3d717fe4305d66f8be2d9346 ]

The data offset for the SMB3.1.1 POSIX create context will always be 8-byte aligned so having the check 'noff + nlen >= doff' in smb2_parse_contexts() is wrong as it will lead to -EINVAL because noff
+ nlen == doff.

Fix the sanity check to correctly handle aligned create context data.

Fixes af1689a9b770 ("smb: client: fix potential OOBs in smb2_parse_contexts()")
---
 fs/smb/client/smb2pdu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/smb2pdu.c +1 -1
index 4f971c1061f0..12e41fcd0b46 100644
@@ -2279,7 +2279,7 @@ int smb2_parse_contexts(struct TCP_Server_Info *server,
 
 		noff = le16_to_cpu(cc->NameOffset);
 		nlen = le16_to_cpu(cc->NameLength);
-		if (noff + nlen >= doff)
+		if (noff + nlen > doff)
 			return -EINVAL;
 
 		name = (char *)cc + noff;
Signature · 1 line
2.43.0
author maintainer
#63 lore raw

PATCH 63/346 cifs: handle servers that still advertise multichannel after disabling

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Shyam Prasad N <[email protected]>

[ Upstream commit f591062bdbf4742b7f1622173017f19e927057b0 ]

Some servers like Azure SMB servers always advertise multichannel capability in server capabilities list. Such servers return error STATUS_NOT_IMPLEMENTED for ioctl calls to query server interfaces, and expect clients to consider that as a sign that they do not support multichannel.

We already handled this at mount time. Soon after the tree connect, we query server interfaces. And when server returned STATUS_NOT_IMPLEMENTED, we kept interface list as empty. When cifs_try_adding_channels gets called, it would not find any interfaces, so will not add channels.

For the case where an active multichannel mount exists, and multichannel is disabled by such a server, this change will now allow the client to disable secondary channels on the mount. It will check the return status of query server interfaces call soon after a tree reconnect. If the return status is EOPNOTSUPP, then instead of the check to add more channels, we'll disable the secondary channels instead.

For better code reuse, this change also moves the common code for disabling multichannel to a helper function.

Stable-dep-of: 78e727e58e54 ("cifs: update iface_last_update on each query-and-update")

---
 fs/smb/client/smb2ops.c |   8 +--
 fs/smb/client/smb2pdu.c | 107 +++++++++++++++++++++++++---------------
 2 files changed, 69 insertions(+), 46 deletions(-)
fs/smb/client/smb2ops.c +1 -7
index 14bc745de199..17310f3a9d89 100644
@@ -614,7 +614,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
 				 "multichannel not available\n"
 				 "Empty network interface list returned by server %s\n",
 				 ses->server->hostname);
-		rc = -EINVAL;
+		rc = -EOPNOTSUPP;
 		goto out;
 	}
 
@@ -734,12 +734,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
 	if ((bytes_left > 8) || p->Next)
 		cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
 
-
-	if (!ses->iface_count) {
-		rc = -EINVAL;
-		goto out;
-	}
-
 out:
 	/*
 	 * Go through the list again and put the inactive entries
fs/smb/client/smb2pdu.c +68 -39

143 lines not on this page · raw message

Signature · 1 line
2.43.0
author maintainer
#64 lore raw

PATCH 64/346 cifs: update iface_last_update on each query-and-update

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Shyam Prasad N <[email protected]>

[ Upstream commit 78e727e58e54efca4c23863fbd9e16e9d2d83f81 ]

iface_last_update was an unused field when it was introduced. Later, when we had periodic update of server interface list, this field was used regularly to decide when to update next.

However, with the new logic of updating the interfaces, it becomes crucial that this field be updated whenever parse_server_interfaces runs successfully.

This change updates this field when either the server does not support query of interfaces; so that we do not query the interfaces repeatedly. It also updates the field when the function reaches the end.

Fixes aa45dadd34e4 ("cifs: change iface_list from array to sorted linked list")
---
 fs/smb/client/smb2ops.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/smb/client/smb2ops.c +3 -1
index 17310f3a9d89..beb81fa00cff 100644
@@ -615,6 +615,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
 				 "Empty network interface list returned by server %s\n",
 				 ses->server->hostname);
 		rc = -EOPNOTSUPP;
+		ses->iface_last_update = jiffies;
 		goto out;
 	}
 
@@ -712,7 +713,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
 
 		ses->iface_count++;
 		spin_unlock(&ses->iface_lock);
-		ses->iface_last_update = jiffies;
 next_iface:
 		nb_iface++;
 		next = le32_to_cpu(p->Next);
@@ -734,6 +734,8 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
 	if ((bytes_left > 8) || p->Next)
 		cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
 
+	ses->iface_last_update = jiffies;
+
 out:
 	/*
 	 * Go through the list again and put the inactive entries
Signature · 1 line
2.43.0
author maintainer
#55 lore raw

PATCH 55/346 scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Bart Van Assche <[email protected]>

[ Upstream commit ee36710912b2075c417100a8acc642c9c6496501 ]

Calling ufshcd_hba_exit() from a function that is called asynchronously from ufshcd_init() is wrong because this triggers multiple race conditions. Instead of calling ufshcd_hba_exit(), log an error message.

---
 drivers/ufs/core/ufshcd.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/ufs/core/ufshcd.c +2 -5
index ce2f76769fb0..1f8d86b9c4fa 100644
@@ -8916,12 +8916,9 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie)
 
 out:
 	pm_runtime_put_sync(hba->dev);
-	/*
-	 * If we failed to initialize the device or the device is not
-	 * present, turn off the power/clocks etc.
-	 */
+
 	if (ret)
-		ufshcd_hba_exit(hba);
+		dev_err(hba->dev, "%s failed: %d\n", __func__, ret);
 }
 
 static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd)
Signature · 1 line
2.43.0
author maintainer
#85 lore raw

PATCH 85/346 arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 134de5e831775e8b178db9b131c1d3769a766982 upstream.

The USB DP/DM HS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states and to be able to detect disconnect events, which requires triggering on falling edges.

A recent commit updated the trigger type but failed to change the interrupt provider as required. This leads to the current Linux driver failing to probe instead of printing an error during suspend and USB wakeup not working as intended.

Fixes 54524b6987d1 ("arm64: dts: qcom: sm8150: fix USB wakeup interrupt types")
Fixes 0c9dde0d2015 ("arm64: dts: qcom: sm8150: Add secondary USB and PHY nodes")
Fixes b33d2868e8d3 ("arm64: dts: qcom: sm8150: Add USB and PHY device nodes")
Cc Jack Pham <[email protected]>
Cc Jonathan Marek <[email protected]>
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/qcom/sm8150.dtsi +8 -8
@@ -3565,10 +3565,10 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
@@ -3618,10 +3618,10 @@
 					  <&gcc GCC_USB30_SEC_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <200000000>;
 
-			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#94 lore raw

PATCH 94/346 docs: kernel_abi.py: fix command injection

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vegard Nossum <[email protected]>

commit 3231dd5862779c2e15633c96133a53205ad660ce upstream.

The kernel-abi directive passes its argument straight to the shell. This is unfortunate and unnecessary.

Let's always use paths relative to $srctree/Documentation/ and use subprocess.check_call() instead of subprocess.Popen(shell=True).

This also makes the code shorter.

---
 Documentation/admin-guide/abi-obsolete.rst |    2 -
 Documentation/admin-guide/abi-removed.rst  |    2 -
 Documentation/admin-guide/abi-stable.rst   |    2 -
 Documentation/admin-guide/abi-testing.rst  |    2 -
 Documentation/sphinx/kernel_abi.py         |   56 +++++------------------------
 5 files changed, 14 insertions(+), 50 deletions(-)
Documentation/admin-guide/abi-obsolete.rst +1 -1
@@ -7,5 +7,5 @@ marked to be removed at some later point
 The description of the interface will document the reason why it is
 obsolete and when it can be expected to be removed.
 
-.. kernel-abi:: $srctree/Documentation/ABI/obsolete
+.. kernel-abi:: ABI/obsolete
    :rst:
Documentation/admin-guide/abi-removed.rst +1 -1
@@ -1,5 +1,5 @@
 ABI removed symbols
 ===================
 
-.. kernel-abi:: $srctree/Documentation/ABI/removed
+.. kernel-abi:: ABI/removed
    :rst:
Documentation/admin-guide/abi-stable.rst +1 -1
@@ -10,5 +10,5 @@ for at least 2 years.
 Most interfaces (like syscalls) are expected to never change and always
 be available.
 
-.. kernel-abi:: $srctree/Documentation/ABI/stable
+.. kernel-abi:: ABI/stable
    :rst:
Documentation/admin-guide/abi-testing.rst +1 -1
@@ -16,5 +16,5 @@ Programs that use these interfaces are s
 name to the description of these interfaces, so that the kernel
 developers can easily notify them if any changes occur.
 
-.. kernel-abi:: $srctree/Documentation/ABI/testing
+.. kernel-abi:: ABI/testing
    :rst:
Documentation/sphinx/kernel_abi.py +10 -46

78 lines not on this page · raw message

author maintainer
#95 lore raw

PATCH 95/346 scripts/get_abi: fix source path leak

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Vegard Nossum <[email protected]>

commit 5889d6ede53bc17252f79c142387e007224aa554 upstream.

The code currently leaks the absolute path of the ABI files into the rendered documentation.

There exists code to prevent this, but it is not effective when an absolute path is passed, which it is when $srctree is used.

I consider this to be a minimal, stop-gap fix; a better fix would strip off the actual prefix instead of hacking it off with a regex.

---
 scripts/get_abi.pl |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
scripts/get_abi.pl +1 -1
@@ -98,7 +98,7 @@ sub parse_abi {
 	$name =~ s,.*/,,;
 
 	my $fn = $file;
-	$fn =~ s,Documentation/ABI/,,;
+	$fn =~ s,.*Documentation/ABI/,,;
 
 	my $nametag = "File $fn";
 	$data{$nametag}->{what} = "File $name";
author maintainer
#96 lore raw

PATCH 96/346 media: videobuf2-dma-sg: fix vmap callback

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Michael Grzeschik <[email protected]>

commit 608ca5a60ee47b48fec210aeb7a795a64eb5dcee upstream.

For dmabuf import users to be able to use the vaddr from another videobuf2-dma-sg source, the exporter needs to set a proper vaddr on vb2_dma_sg_dmabuf_ops_vmap callback. This patch adds vmap on map if buf->vaddr was not set.

Fixes 7938f4218168 ("dma-buf-map: Rename to iosys-map")
---
 drivers/media/common/videobuf2/videobuf2-dma-sg.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/media/common/videobuf2/videobuf2-dma-sg.c +8 -2
@@ -487,9 +487,15 @@ vb2_dma_sg_dmabuf_ops_end_cpu_access(str
 static int vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf,
 				      struct iosys_map *map)
 {
-	struct vb2_dma_sg_buf *buf = dbuf->priv;
+	struct vb2_dma_sg_buf *buf;
+	void *vaddr;
 
-	iosys_map_set_vaddr(map, buf->vaddr);
+	buf = dbuf->priv;
+	vaddr = vb2_dma_sg_vaddr(buf->vb, buf);
+	if (!vaddr)
+		return -EINVAL;
+
+	iosys_map_set_vaddr(map, vaddr);
 
 	return 0;
 }
author maintainer
#97 lore raw

PATCH 97/346 mmc: core: Use mrq.sbc in close-ended ffu

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Avri Altman <[email protected]>

commit 4d0c8d0aef6355660b6775d57ccd5d4ea2e15802 upstream.

Field Firmware Update (ffu) may use close-ended or open ended sequence. Each such sequence is comprised of a write commands enclosed between 2 switch commands - to and from ffu mode. So for the close-ended case, it will be: cmd6->cmd23-cmd25-cmd6.

Some host controllers however, get confused when multi-block rw is sent without sbc, and may generate auto-cmd12 which breaks the ffu sequence. I encountered this issue while testing fwupd (github.com/fwupd/fwupd) on HP Chromebook x2, a qualcomm based QC-7c, code name - strongbad.

Instead of a quirk, or hooking the request function of the msm ops, it would be better to fix the ioctl handling and make it use mrq.sbc instead of issuing SET_BLOCK_COUNT separately.

---
 drivers/mmc/core/block.c |   46 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 3 deletions(-)
drivers/mmc/core/block.c +43 -3
@@ -400,6 +400,10 @@ struct mmc_blk_ioc_data {
 	struct mmc_ioc_cmd ic;
 	unsigned char *buf;
 	u64 buf_bytes;
+	unsigned int flags;
+#define MMC_BLK_IOC_DROP	BIT(0)	/* drop this mrq */
+#define MMC_BLK_IOC_SBC	BIT(1)	/* use mrq.sbc */
+
 	struct mmc_rpmb_data *rpmb;
 };
 
@@ -465,7 +469,7 @@ static int mmc_blk_ioctl_copy_to_user(st
 }
 
 static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
-			       struct mmc_blk_ioc_data *idata)
+			       struct mmc_blk_ioc_data **idatas, int i)
 {
 	struct mmc_command cmd = {}, sbc = {};
 	struct mmc_data data = {};
@@ -475,10 +479,18 @@ static int __mmc_blk_ioctl_cmd(struct mm
 	unsigned int busy_timeout_ms;
 	int err;
 	unsigned int target_part;
+	struct mmc_blk_ioc_data *idata = idatas[i];
+	struct mmc_blk_ioc_data *prev_idata = NULL;
 
 	if (!card || !md || !idata)
 		return -EINVAL;
 
+	if (idata->flags & MMC_BLK_IOC_DROP)
+		return 0;
+
+	if (idata->flags & MMC_BLK_IOC_SBC)
+		prev_idata = idatas[i - 1];
+
 	/*
 	 * The RPMB accesses comes in from the character device, so we
 	 * need to target these explicitly. Else we just target the
@@ -532,7 +544,7 @@ static int __mmc_blk_ioctl_cmd(struct mm
 			return err;
 	}
 
-	if (idata->rpmb) {
+	if (idata->rpmb || prev_idata) {
 		sbc.opcode = MMC_SET_BLOCK_COUNT;
 		/*
 		 * We don't do any blockcount validation because the max size
@@ -540,6 +552,8 @@ static int __mmc_blk_ioctl_cmd(struct mm
 		 * 'Reliable Write' bit here.
 		 */
 		sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31));
+		if (prev_idata)
+			sbc.arg = prev_idata->ic.arg;
 		sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
 		mrq.sbc = &sbc;
 	}
@@ -557,6 +571,15 @@ static int __mmc_blk_ioctl_cmd(struct mm
 	mmc_wait_for_req(card->host, &mrq);
 	memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp));
 
+	if (prev_idata) {
+		memcpy(&prev_idata->ic.response, sbc.resp, sizeof(sbc.resp));
+		if (sbc.error) {
+			dev_err(mmc_dev(card->host), "%s: sbc error %d\n",
+							__func__, sbc.error);
+			return sbc.error;
+		}
+	}
+
 	if (cmd.error) {
 		dev_err(mmc_dev(card->host), "%s: cmd error %d\n",
 						__func__, cmd.error);
@@ -1034,6 +1057,20 @@ static inline void mmc_blk_reset_success
 	md->reset_done &= ~type;
 }
 
+static void mmc_blk_check_sbc(struct mmc_queue_req *mq_rq)
+{
+	struct mmc_blk_ioc_data **idata = mq_rq->drv_op_data;
+	int i;
+
+	for (i = 1; i < mq_rq->ioc_count; i++) {
+		if (idata[i - 1]->ic.opcode == MMC_SET_BLOCK_COUNT &&
+		    mmc_op_multi(idata[i]->ic.opcode)) {
+			idata[i - 1]->flags |= MMC_BLK_IOC_DROP;
+			idata[i]->flags |= MMC_BLK_IOC_SBC;
+		}
+	}
+}
+
 /*
  * The non-block commands come back from the block layer after it queued it and
  * processed it with all other requests and then they get issued in this
@@ -1061,11 +1098,14 @@ static void mmc_blk_issue_drv_op(struct
 			if (ret)
 				break;
 		}
+
+		mmc_blk_check_sbc(mq_rq);
+
 		fallthrough;
 	case MMC_DRV_OP_IOCTL_RPMB:
 		idata = mq_rq->drv_op_data;
 		for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) {
-			ret = __mmc_blk_ioctl_cmd(card, md, idata[i]);
+			ret = __mmc_blk_ioctl_cmd(card, md, idata, i);
 			if (ret)
 				break;
 		}
author maintainer
#98 lore raw

PATCH 98/346 mmc: mmc_spi: remove custom DMA mapped buffers

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andy Shevchenko <[email protected]>

commit 84a6be7db9050dd2601c9870f65eab9a665d2d5d upstream.

There is no need to duplicate what SPI core or individual controller drivers already do, i.e. mapping the buffers for DMA capable transfers.

Note, that the code, besides its redundancy, was buggy: strictly speaking there is no guarantee, while it's true for those which can use this code (see below), that the SPI host controller _is_ the device which does DMA.

Also see the Link tags below.

Additional notes. Currently only two SPI host controller drivers may use premapped (by the user) DMA buffers:

- drivers/spi/spi-au1550.c

- drivers/spi/spi-fsl-spi.c

Both of them have DMA mapping support code. I don't expect that SPI host controller code is worse than what has been done in mmc_spi. Hence I do not expect any regressions here. Otherwise, I'm pretty much sure these regressions have to be fixed in the respective drivers, and not here.

That said, remove all related pieces of DMA mapping code from mmc_spi.

---
 drivers/mmc/host/mmc_spi.c |  186 +--------------------------------------------
 1 file changed, 5 insertions(+), 181 deletions(-)
drivers/mmc/host/mmc_spi.c +5 -181
@@ -15,7 +15,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/bio.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-direction.h>
 #include <linux/crc7.h>
 #include <linux/crc-itu-t.h>
 #include <linux/scatterlist.h>
@@ -119,19 +119,14 @@ struct mmc_spi_host {
 	struct spi_transfer	status;
 	struct spi_message	readback;
 
-	/* underlying DMA-aware controller, or null */
-	struct device		*dma_dev;
-
 	/* buffer used for commands and for message "overhead" */
 	struct scratch		*data;
-	dma_addr_t		data_dma;
 
 	/* Specs say to write ones most of the time, even when the card
 	 * has no need to read its input data; and many cards won't care.
 	 * This is our source of those ones.
 	 */
 	void			*ones;
-	dma_addr_t		ones_dma;
 };
 
 
@@ -147,11 +142,8 @@ static inline int mmc_cs_off(struct mmc_
 	return spi_setup(host->spi);
 }
 
-static int
-mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len)
+static int mmc_spi_readbytes(struct mmc_spi_host *host, unsigned int len)
 {
-	int status;
-
 	if (len > sizeof(*host->data)) {
 		WARN_ON(1);
 		return -EIO;
@@ -159,19 +151,7 @@ mmc_spi_readbytes(struct mmc_spi_host *h
 
 	host->status.len = len;
 
-	if (host->dma_dev)
-		dma_sync_single_for_device(host->dma_dev,
-				host->data_dma, sizeof(*host->data),
-				DMA_FROM_DEVICE);
-
-	status = spi_sync_locked(host->spi, &host->readback);
-
-	if (host->dma_dev)
-		dma_sync_single_for_cpu(host->dma_dev,
-				host->data_dma, sizeof(*host->data),
-				DMA_FROM_DEVICE);
-
-	return status;
+	return spi_sync_locked(host->spi, &host->readback);
 }
 
 static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout,
@@ -506,23 +486,11 @@ mmc_spi_command_send(struct mmc_spi_host
 	t = &host->t;
 	memset(t, 0, sizeof(*t));
 	t->tx_buf = t->rx_buf = data->status;
-	t->tx_dma = t->rx_dma = host->data_dma;
 	t->len = cp - data->status;
 	t->cs_change = 1;
 	spi_message_add_tail(t, &host->m);
 
-	if (host->dma_dev) {
-		host->m.is_dma_mapped = 1;
-		dma_sync_single_for_device(host->dma_dev,
-				host->data_dma, sizeof(*host->data),
-				DMA_BIDIRECTIONAL);
-	}
 	status = spi_sync_locked(host->spi, &host->m);
-
-	if (host->dma_dev)
-		dma_sync_single_for_cpu(host->dma_dev,
-				host->data_dma, sizeof(*host->data),
-				DMA_BIDIRECTIONAL);
 	if (status < 0) {
 		dev_dbg(&host->spi->dev, "  ... write returned %d\n", status);
 		cmd->error = status;
@@ -540,9 +508,6 @@ mmc_spi_command_send(struct mmc_spi_host
  * We always provide TX data for data and CRC.  The MMC/SD protocol
  * requires us to write ones; but Linux defaults to writing zeroes;
  * so we explicitly initialize it to all ones on RX paths.
- *
- * We also handle DMA mapping, so the underlying SPI controller does
- * not need to (re)do it for each message.
  */
 static void
 mmc_spi_setup_data_message(
@@ -552,11 +517,8 @@ mmc_spi_setup_data_message(
 {
 	struct spi_transfer	*t;
 	struct scratch		*scratch = host->data;
-	dma_addr_t		dma = host->data_dma;
 
 	spi_message_init(&host->m);
-	if (dma)
-		host->m.is_dma_mapped = 1;
 
 	/* for reads, readblock() skips 0xff bytes before finding
 	 * the token; for writes, this transfer issues that token.
@@ -570,8 +532,6 @@ mmc_spi_setup_data_message(
 		else
 			scratch->data_token = SPI_TOKEN_SINGLE;
 		t->tx_buf = &scratch->data_token;
-		if (dma)
-			t->tx_dma = dma + offsetof(struct scratch, data_token);
 		spi_message_add_tail(t, &host->m);
 	}
 
@@ -581,7 +541,6 @@ mmc_spi_setup_data_message(
 	t = &host->t;
 	memset(t, 0, sizeof(*t));
 	t->tx_buf = host->ones;
-	t->tx_dma = host->ones_dma;
 	/* length and actual buffer info are written later */
 	spi_message_add_tail(t, &host->m);
 
@@ -591,14 +550,9 @@ mmc_spi_setup_data_message(
 	if (direction == DMA_TO_DEVICE) {
 		/* the actual CRC may get written later */
 		t->tx_buf = &scratch->crc_val;
-		if (dma)
-			t->tx_dma = dma + offsetof(struct scratch, crc_val);
 	} else {
 		t->tx_buf = host->ones;
-		t->tx_dma = host->ones_dma;
 		t->rx_buf = &scratch->crc_val;
-		if (dma)
-			t->rx_dma = dma + offsetof(struct scratch, crc_val);
 	}
 	spi_message_add_tail(t, &host->m);
 
@@ -621,10 +575,7 @@ mmc_spi_setup_data_message(
 		memset(t, 0, sizeof(*t));
 		t->len = (direction == DMA_TO_DEVICE) ? sizeof(scratch->status) : 1;
 		t->tx_buf = host->ones;
-		t->tx_dma = host->ones_dma;
 		t->rx_buf = scratch->status;
-		if (dma)
-			t->rx_dma = dma + offsetof(struct scratch, status);
 		t->cs_change = 1;
 		spi_message_add_tail(t, &host->m);
 	}
@@ -653,23 +604,13 @@ mmc_spi_writeblock(struct mmc_spi_host *
 
 	if (host->mmc->use_spi_crc)
 		scratch->crc_val = cpu_to_be16(crc_itu_t(0, t->tx_buf, t->len));
-	if (host->dma_dev)
-		dma_sync_single_for_device(host->dma_dev,
-				host->data_dma, sizeof(*scratch),
-				DMA_BIDIRECTIONAL);
 
 	status = spi_sync_locked(spi, &host->m);
-
 	if (status != 0) {
 		dev_dbg(&spi->dev, "write error (%d)\n", status);
 		return status;
 	}
 
-	if (host->dma_dev)
-		dma_sync_single_for_cpu(host->dma_dev,
-				host->data_dma, sizeof(*scratch),
-				DMA_BIDIRECTIONAL);
-
 	/*
 	 * Get the transmission data-response reply.  It must follow
 	 * immediately after the data block we transferred.  This reply
@@ -718,8 +659,6 @@ mmc_spi_writeblock(struct mmc_spi_host *
 	}
 
 	t->tx_buf += t->len;
-	if (host->dma_dev)
-		t->tx_dma += t->len;
 
 	/* Return when not busy.  If we didn't collect that status yet,
 	 * we'll need some more I/O.
@@ -783,30 +722,12 @@ mmc_spi_readblock(struct mmc_spi_host *h
 	}
 	leftover = status << 1;
 
-	if (host->dma_dev) {
-		dma_sync_single_for_device(host->dma_dev,
-				host->data_dma, sizeof(*scratch),
-				DMA_BIDIRECTIONAL);
-		dma_sync_single_for_device(host->dma_dev,
-				t->rx_dma, t->len,
-				DMA_FROM_DEVICE);
-	}
-
 	status = spi_sync_locked(spi, &host->m);
 	if (status < 0) {
 		dev_dbg(&spi->dev, "read error %d\n", status);
 		return status;
 	}
 
-	if (host->dma_dev) {
-		dma_sync_single_for_cpu(host->dma_dev,
-				host->data_dma, sizeof(*scratch),
-				DMA_BIDIRECTIONAL);
-		dma_sync_single_for_cpu(host->dma_dev,
-				t->rx_dma, t->len,
-				DMA_FROM_DEVICE);
-	}
-
 	if (bitshift) {
 		/* Walk through the data and the crc and do
 		 * all the magic to get byte-aligned data.
@@ -841,8 +762,6 @@ mmc_spi_readblock(struct mmc_spi_host *h
 	}
 
 	t->rx_buf += t->len;
-	if (host->dma_dev)
-		t->rx_dma += t->len;
 
 	return 0;
 }
@@ -857,7 +776,6 @@ mmc_spi_data_do(struct mmc_spi_host *hos
 		struct mmc_data *data, u32 blk_size)
 {
 	struct spi_device	*spi = host->spi;
-	struct device		*dma_dev = host->dma_dev;
 	struct spi_transfer	*t;
 	enum dma_data_direction	direction = mmc_get_dma_dir(data);
 	struct scatterlist	*sg;
@@ -884,31 +802,8 @@ mmc_spi_data_do(struct mmc_spi_host *hos
 	 */
 	for_each_sg(data->sg, sg, data->sg_len, n_sg) {
 		int			status = 0;
-		dma_addr_t		dma_addr = 0;
 		void			*kmap_addr;
 		unsigned		length = sg->length;
-		enum dma_data_direction	dir = direction;
-
-		/* set up dma mapping for controller drivers that might
-		 * use DMA ... though they may fall back to PIO
-		 */
-		if (dma_dev) {
-			/* never invalidate whole *shared* pages ... */
-			if ((sg->offset != 0 || length != PAGE_SIZE)
-					&& dir == DMA_FROM_DEVICE)
-				dir = DMA_BIDIRECTIONAL;
-
-			dma_addr = dma_map_page(dma_dev, sg_page(sg), 0,
-						PAGE_SIZE, dir);
-			if (dma_mapping_error(dma_dev, dma_addr)) {
-				data->error = -EFAULT;
-				break;
-			}
-			if (direction == DMA_TO_DEVICE)
-				t->tx_dma = dma_addr + sg->offset;
-			else
-				t->rx_dma = dma_addr + sg->offset;
-		}
 
 		/* allow pio too; we don't allow highmem */
 		kmap_addr = kmap(sg_page(sg));
@@ -941,8 +836,6 @@ mmc_spi_data_do(struct mmc_spi_host *hos
 		if (direction == DMA_FROM_DEVICE)
 			flush_dcache_page(sg_page(sg));
 		kunmap(sg_page(sg));
-		if (dma_dev)
-			dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir);
 
 		if (status < 0) {
 			data->error = status;
@@ -977,21 +870,9 @@ mmc_spi_data_do(struct mmc_spi_host *hos
 		scratch->status[0] = SPI_TOKEN_STOP_TRAN;
 
 		host->early_status.tx_buf = host->early_status.rx_buf;
-		host->early_status.tx_dma = host->early_status.rx_dma;
 		host->early_status.len = statlen;
 
-		if (host->dma_dev)
-			dma_sync_single_for_device(host->dma_dev,
-					host->data_dma, sizeof(*scratch),
-					DMA_BIDIRECTIONAL);
-
 		tmp = spi_sync_locked(spi, &host->m);
-
-		if (host->dma_dev)
-			dma_sync_single_for_cpu(host->dma_dev,
-					host->data_dma, sizeof(*scratch),
-					DMA_BIDIRECTIONAL);
-
 		if (tmp < 0) {
 			if (!data->error)
 				data->error = tmp;
@@ -1265,52 +1146,6 @@ mmc_spi_detect_irq(int irq, void *mmc)
 	return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_HAS_DMA
-static int mmc_spi_dma_alloc(struct mmc_spi_host *host)
-{
-	struct spi_device *spi = host->spi;
-	struct device *dev;
-
-	if (!spi->master->dev.parent->dma_mask)
-		return 0;
-
-	dev = spi->master->dev.parent;
-
-	host->ones_dma = dma_map_single(dev, host->ones, MMC_SPI_BLOCKSIZE,
-					DMA_TO_DEVICE);
-	if (dma_mapping_error(dev, host->ones_dma))
-		return -ENOMEM;
-
-	host->data_dma = dma_map_single(dev, host->data, sizeof(*host->data),
-					DMA_BIDIRECTIONAL);
-	if (dma_mapping_error(dev, host->data_dma)) {
-		dma_unmap_single(dev, host->ones_dma, MMC_SPI_BLOCKSIZE,
-				 DMA_TO_DEVICE);
-		return -ENOMEM;
-	}
-
-	dma_sync_single_for_cpu(dev, host->data_dma, sizeof(*host->data),
-				DMA_BIDIRECTIONAL);
-
-	host->dma_dev = dev;
-	return 0;
-}
-
-static void mmc_spi_dma_free(struct mmc_spi_host *host)
-{
-	if (!host->dma_dev)
-		return;
-
-	dma_unmap_single(host->dma_dev, host->ones_dma, MMC_SPI_BLOCKSIZE,
-			 DMA_TO_DEVICE);
-	dma_unmap_single(host->dma_dev, host->data_dma,	sizeof(*host->data),
-			 DMA_BIDIRECTIONAL);
-}
-#else
-static inline int mmc_spi_dma_alloc(struct mmc_spi_host *host) { return 0; }
-static inline void mmc_spi_dma_free(struct mmc_spi_host *host) {}
-#endif
-
 static int mmc_spi_probe(struct spi_device *spi)
 {
 	void			*ones;
@@ -1402,24 +1237,17 @@ static int mmc_spi_probe(struct spi_devi
 			host->powerup_msecs = 250;
 	}
 
-	/* preallocate dma buffers */
+	/* Preallocate buffers */
 	host->data = kmalloc(sizeof(*host->data), GFP_KERNEL);
 	if (!host->data)
 		goto fail_nobuf1;
 
-	status = mmc_spi_dma_alloc(host);
-	if (status)
-		goto fail_dma;
-
 	/* setup message for status/busy readback */
 	spi_message_init(&host->readback);
-	host->readback.is_dma_mapped = (host->dma_dev != NULL);
 
 	spi_message_add_tail(&host->status, &host->readback);
 	host->status.tx_buf = host->ones;
-	host->status.tx_dma = host->ones_dma;
 	host->status.rx_buf = &host->data->status;
-	host->status.rx_dma = host->data_dma + offsetof(struct scratch, status);
 	host->status.cs_change = 1;
 
 	/* register card detect irq */
@@ -1464,9 +1292,8 @@ static int mmc_spi_probe(struct spi_devi
 	if (!status)
 		has_ro = true;
 
-	dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n",
+	dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n",
 			dev_name(&mmc->class_dev),
-			host->dma_dev ? "" : ", no DMA",
 			has_ro ? "" : ", no WP",
 			(host->pdata && host->pdata->setpower)
 				? "" : ", no poweroff",
@@ -1477,8 +1304,6 @@ static int mmc_spi_probe(struct spi_devi
 fail_gpiod_request:
 	mmc_remove_host(mmc);
 fail_glue_init:
-	mmc_spi_dma_free(host);
-fail_dma:
 	kfree(host->data);
 fail_nobuf1:
 	mmc_spi_put_pdata(spi);
@@ -1500,7 +1325,6 @@ static void mmc_spi_remove(struct spi_de
 
 	mmc_remove_host(mmc);
 
-	mmc_spi_dma_free(host);
 	kfree(host->data);
 	kfree(host->ones);
 
author maintainer
#99 lore raw

PATCH 99/346 media: i2c: st-mipid02: correct format propagation

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alain Volmat <[email protected]>

commit b33cb0cbe2893b96ecbfa16254407153f4b55d16 upstream.

Use a copy of the struct v4l2_subdev_format when propagating format from the sink to source pad in order to avoid impacting the sink format returned to the application.

Thanks to Jacopo Mondi for pointing the issue.

Fixes 6c01e6f3f27b ("media: st-mipid02: Propagate format from sink to source pad")
---
 drivers/media/i2c/st-mipid02.c |    9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/media/i2c/st-mipid02.c +7 -2
@@ -770,6 +770,7 @@ static void mipid02_set_fmt_sink(struct
 				 struct v4l2_subdev_format *format)
 {
 	struct mipid02_dev *bridge = to_mipid02_dev(sd);
+	struct v4l2_subdev_format source_fmt;
 	struct v4l2_mbus_framefmt *fmt;
 
 	format->format.code = get_fmt_code(format->format.code);
@@ -781,8 +782,12 @@ static void mipid02_set_fmt_sink(struct
 
 	*fmt = format->format;
 
-	/* Propagate the format change to the source pad */
-	mipid02_set_fmt_source(sd, sd_state, format);
+	/*
+	 * Propagate the format change to the source pad, taking
+	 * care not to update the format pointer given back to user
+	 */
+	source_fmt = *format;
+	mipid02_set_fmt_source(sd, sd_state, &source_fmt);
 }
 
 static int mipid02_set_fmt(struct v4l2_subdev *sd,
author maintainer
#100 lore raw

PATCH 100/346 media: mtk-jpeg: Fix timeout schedule error in mtk_jpegdec_worker.

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zheng Wang <[email protected]>

commit 38e1857933def4b3fafc28cc34ff3bbc84cad2c3 upstream.

In mtk_jpegdec_worker, if error occurs in mtk_jpeg_set_dec_dst, it will start the timeout worker and invoke v4l2_m2m_job_finish at the same time. This will break the logic of design for there should be only one function to call v4l2_m2m_job_finish. But now the timeout handler and mtk_jpegdec_worker will both invoke it.

Fix it by start the worker only if mtk_jpeg_set_dec_dst successfully finished.

Fixes da4ede4b7fd6 ("media: mtk-jpeg: move data/code inside CONFIG_OF blocks")
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +3 -3
@@ -1749,9 +1749,6 @@ retry_select:
 	v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
 	v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
 
-	schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
-			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
-
 	mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
 	if (mtk_jpeg_set_dec_dst(ctx,
 				 &jpeg_src_buf->dec_param,
@@ -1761,6 +1758,9 @@ retry_select:
 		goto setdst_end;
 	}
 
+	schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work,
+			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
+
 	spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
 	ctx->total_frame_num++;
 	mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base);
author maintainer
#101 lore raw

PATCH 101/346 media: mtk-jpeg: Fix use after free bug due to error path handling in mtk_jpeg_dec_device_run

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Zheng Wang <[email protected]>

commit 206c857dd17d4d026de85866f1b5f0969f2a109e upstream.

In mtk_jpeg_probe, &jpeg->job_timeout_work is bound with mtk_jpeg_job_timeout_work.

In mtk_jpeg_dec_device_run, if error happens in mtk_jpeg_set_dec_dst, it will finally start the worker while mark the job as finished by invoking v4l2_m2m_job_finish.

There are two methods to trigger the bug. If we remove the module, it which will call mtk_jpeg_remove to make cleanup. The possible sequence is as follows, which will cause a use-after-free bug.

CPU0 CPU1
mtk_jpeg_dec_... |
start worker |

                    |mtk_jpeg_job_timeout_work
mtk_jpeg_remove     |
  v4l2_m2m_release  |
    kfree(m2m_dev); |
                    |
                    | v4l2_m2m_get_curr_priv
                    |   m2m_dev->curr_ctx //use

If we close the file descriptor, which will call mtk_jpeg_release, it will have a similar sequence.

Fix this bug by starting timeout worker only if started jpegdec worker successfully. Then v4l2_m2m_job_finish will only be called in either mtk_jpeg_job_timeout_work or mtk_jpeg_dec_device_run.

Fixes b2f0d2724ba4 ("[media] vcodec: mediatek: Add Mediatek JPEG Decoder Driver")
---
 drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +3 -3
@@ -1021,13 +1021,13 @@ static void mtk_jpeg_dec_device_run(void
 	if (ret < 0)
 		goto dec_end;
 
-	schedule_delayed_work(&jpeg->job_timeout_work,
-			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
-
 	mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs);
 	if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb))
 		goto dec_end;
 
+	schedule_delayed_work(&jpeg->job_timeout_work,
+			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
+
 	spin_lock_irqsave(&jpeg->hw_lock, flags);
 	mtk_jpeg_dec_reset(jpeg->reg_base);
 	mtk_jpeg_dec_set_config(jpeg->reg_base,
author maintainer
#102 lore raw

PATCH 102/346 riscv: mm: Fixup compat arch_get_mmap_end

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guo Ren <[email protected]>

commit 97b7ac69be2e5a683e898f5267f659fde52efdd5 upstream.

When the task is in COMPAT mode, the arch_get_mmap_end should be 2GB, not TASK_SIZE_64. The TASK_SIZE has contained is_compat_mode() detection, so change the definition of STACK_TOP_MAX to TASK_SIZE directly.

---
 arch/riscv/include/asm/processor.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/include/asm/processor.h +1 -1
@@ -16,7 +16,7 @@
 
 #ifdef CONFIG_64BIT
 #define DEFAULT_MAP_WINDOW	(UL(1) << (MMAP_VA_BITS - 1))
-#define STACK_TOP_MAX		TASK_SIZE_64
+#define STACK_TOP_MAX		TASK_SIZE
 
 #define arch_get_mmap_end(addr, len, flags)			\
 ({								\
author maintainer
#103 lore raw

PATCH 103/346 riscv: mm: Fixup compat mode boot failure

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Guo Ren <[email protected]>

commit 5f449e245e5b0d9d63eef6c8968fbdc3a8594407 upstream.

In COMPAT mode, the STACK_TOP is DEFAULT_MAP_WINDOW (0x80000000), but the TASK_SIZE is 0x7fff000. When the user stack is upon 0x7fff000, it will cause a user segment fault. Sometimes, it would cause boot failure when the whole rootfs is rv32.

Freeing unused kernel image (initmem) memory: 2236K
Run /sbin/init as init process
Starting init: /sbin/init exists but couldn't execute it (error -14) Run /etc/init as init process
...

Increase the TASK_SIZE to cover STACK_TOP.

---
 arch/riscv/include/asm/pgtable.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/include/asm/pgtable.h +1 -1
@@ -881,7 +881,7 @@ static inline pte_t pte_swp_clear_exclus
 #define TASK_SIZE_MIN	(PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
 
 #ifdef CONFIG_COMPAT
-#define TASK_SIZE_32	(_AC(0x80000000, UL) - PAGE_SIZE)
+#define TASK_SIZE_32	(_AC(0x80000000, UL))
 #define TASK_SIZE	(test_thread_flag(TIF_32BIT) ? \
 			 TASK_SIZE_32 : TASK_SIZE_64)
 #else
author maintainer
#86 lore raw

PATCH 86/346 arm64: dts: qcom: sm8150: fix USB SS wakeup

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit cc4e1da491b84ca05339a19893884cda78f74aef upstream.

The USB SS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states.

Fixes 0c9dde0d2015 ("arm64: dts: qcom: sm8150: Add secondary USB and PHY nodes")
Fixes b33d2868e8d3 ("arm64: dts: qcom: sm8150: Add USB and PHY device nodes")
Cc Jack Pham <[email protected]>
Cc Jonathan Marek <[email protected]>
---
 arch/arm64/boot/dts/qcom/sm8150.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sm8150.dtsi +2 -2
@@ -3566,7 +3566,7 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
@@ -3619,7 +3619,7 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 7 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
author maintainer
#104 lore raw

PATCH 104/346 RISC-V: selftests: cbo: Ensure asm operands match constraints

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andrew Jones <[email protected]>

commit 0de65288d75ff96c30e216557d979fb9342c4323 upstream.

The 'i' constraint expects a constant operand, which fn and its constant derivative MK_CBO(fn) are, but passing fn through a function as a parameter and using a local variable for MK_CBO(fn) allow the compiler to lose sight of that when no optimization is done. Use a macro instead of a function and skip the local variable to ensure the compiler uses constants, matching the asm constraints.

---
 tools/testing/selftests/riscv/hwprobe/cbo.c |   18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)
tools/testing/selftests/riscv/hwprobe/cbo.c +8 -10
@@ -36,16 +36,14 @@ static void sigill_handler(int sig, sigi
 	regs[0] += 4;
 }
 
-static void cbo_insn(char *base, int fn)
-{
-	uint32_t insn = MK_CBO(fn);
-
-	asm volatile(
-	"mv	a0, %0\n"
-	"li	a1, %1\n"
-	".4byte	%2\n"
-	: : "r" (base), "i" (fn), "i" (insn) : "a0", "a1", "memory");
-}
+#define cbo_insn(base, fn)							\
+({										\
+	asm volatile(								\
+	"mv	a0, %0\n"							\
+	"li	a1, %1\n"							\
+	".4byte	%2\n"								\
+	: : "r" (base), "i" (fn), "i" (MK_CBO(fn)) : "a0", "a1", "memory");	\
+})
 
 static void cbo_inval(char *base) { cbo_insn(base, 0); }
 static void cbo_clean(char *base) { cbo_insn(base, 1); }
author maintainer
#105 lore raw

PATCH 105/346 arm64: Rename ARM64_WORKAROUND_2966298

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rob Herring <[email protected]>

commit 546b7cde9b1dd36089649101b75266564600ffe5 upstream.

In preparation to apply ARM64_WORKAROUND_2966298 for multiple errata, rename the kconfig and capability. No functional change.

---
 arch/arm64/Kconfig             |    4 ++++
 arch/arm64/kernel/cpu_errata.c |    4 ++--
 arch/arm64/kernel/entry.S      |    2 +-
 arch/arm64/tools/cpucaps       |    2 +-
 4 files changed, 8 insertions(+), 4 deletions(-)
arch/arm64/Kconfig +4 -0
@@ -1037,8 +1037,12 @@ config ARM64_ERRATUM_2645198
 
 	  If unsure, say Y.
 
+config ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
+	bool
+
 config ARM64_ERRATUM_2966298
 	bool "Cortex-A520: 2966298: workaround for speculatively executed unprivileged load"
+	select ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
 	default y
 	help
 	  This option adds the workaround for ARM Cortex-A520 erratum 2966298.
arch/arm64/kernel/cpu_errata.c +2 -2
@@ -713,10 +713,10 @@ const struct arm64_cpu_capabilities arm6
 		MIDR_FIXED(MIDR_CPU_VAR_REV(1,1), BIT(25)),
 	},
 #endif
-#ifdef CONFIG_ARM64_ERRATUM_2966298
+#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
 	{
 		.desc = "ARM erratum 2966298",
-		.capability = ARM64_WORKAROUND_2966298,
+		.capability = ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD,
 		/* Cortex-A520 r0p0 - r0p1 */
 		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1),
 	},
arch/arm64/kernel/entry.S +1 -1
@@ -428,7 +428,7 @@ alternative_else_nop_endif
 	ldp	x28, x29, [sp, #16 * 14]
 
 	.if	\el == 0
-alternative_if ARM64_WORKAROUND_2966298
+alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
 	tlbi	vale1, xzr
 	dsb	nsh
 alternative_else_nop_endif
arch/arm64/tools/cpucaps +1 -1
@@ -84,7 +84,6 @@ WORKAROUND_2077057
 WORKAROUND_2457168
 WORKAROUND_2645198
 WORKAROUND_2658417
-WORKAROUND_2966298
 WORKAROUND_AMPERE_AC03_CPU_38
 WORKAROUND_TRBE_OVERWRITE_FILL_MODE
 WORKAROUND_TSB_FLUSH_FAILURE
@@ -100,3 +99,4 @@ WORKAROUND_NVIDIA_CARMEL_CNP
 WORKAROUND_QCOM_FALKOR_E1003
 WORKAROUND_REPEAT_TLBI
 WORKAROUND_SPECULATIVE_AT
+WORKAROUND_SPECULATIVE_UNPRIV_LOAD
author maintainer
#106 lore raw

PATCH 106/346 arm64: errata: Add Cortex-A510 speculative unprivileged load workaround

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Rob Herring <[email protected]>

commit f827bcdafa2a2ac21c91e47f587e8d0c76195409 upstream.

Implement the workaround for ARM Cortex-A510 erratum 3117295. On an affected Cortex-A510 core, a speculatively executed unprivileged load might leak data from a privileged load via a cache side channel. The issue only exists for loads within a translation regime with the same translation (e.g. same ASID and VMID). Therefore, the issue only affects the return to EL0.

The erratum and workaround are the same as ARM Cortex-A520 erratum 2966298, so reuse the existing workaround.

---
 Documentation/arch/arm64/silicon-errata.rst |    2 ++
 arch/arm64/Kconfig                          |   14 ++++++++++++++
 arch/arm64/kernel/cpu_errata.c              |   17 +++++++++++++++--
 3 files changed, 31 insertions(+), 2 deletions(-)
Documentation/arch/arm64/silicon-errata.rst +2 -0
@@ -71,6 +71,8 @@ stable kernels.
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A510     | #2658417        | ARM64_ERRATUM_2658417       |
 +----------------+-----------------+-----------------+-----------------------------+
+| ARM            | Cortex-A510     | #3117295        | ARM64_ERRATUM_3117295       |
++----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A520     | #2966298        | ARM64_ERRATUM_2966298       |
 +----------------+-----------------+-----------------+-----------------------------+
 | ARM            | Cortex-A53      | #826319         | ARM64_ERRATUM_826319        |
arch/arm64/Kconfig +14 -0
@@ -1054,6 +1054,20 @@ config ARM64_ERRATUM_2966298
 
 	  If unsure, say Y.
 
+config ARM64_ERRATUM_3117295
+	bool "Cortex-A510: 3117295: workaround for speculatively executed unprivileged load"
+	select ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
+	default y
+	help
+	  This option adds the workaround for ARM Cortex-A510 erratum 3117295.
+
+	  On an affected Cortex-A510 core, a speculatively executed unprivileged
+	  load might leak data from a privileged level via a cache side channel.
+
+	  Work around this problem by executing a TLBI before returning to EL0.
+
+	  If unsure, say Y.
+
 config CAVIUM_ERRATUM_22375
 	bool "Cavium erratum 22375, 24313"
 	default y
arch/arm64/kernel/cpu_errata.c +15 -2
@@ -416,6 +416,19 @@ static struct midr_range broken_aarch32_
 };
 #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */
 
+#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
+static const struct midr_range erratum_spec_unpriv_load_list[] = {
+#ifdef CONFIG_ARM64_ERRATUM_3117295
+	MIDR_ALL_VERSIONS(MIDR_CORTEX_A510),
+#endif
+#ifdef CONFIG_ARM64_ERRATUM_2966298
+	/* Cortex-A520 r0p0 to r0p1 */
+	MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1),
+#endif
+	{},
+};
+#endif
+
 const struct arm64_cpu_capabilities arm64_errata[] = {
 #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE
 	{
@@ -715,10 +728,10 @@ const struct arm64_cpu_capabilities arm6
 #endif
 #ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
 	{
-		.desc = "ARM erratum 2966298",
+		.desc = "ARM errata 2966298, 3117295",
 		.capability = ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD,
 		/* Cortex-A520 r0p0 - r0p1 */
-		ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1),
+		ERRATA_MIDR_RANGE_LIST(erratum_spec_unpriv_load_list),
 	},
 #endif
 #ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38
author maintainer
#107 lore raw

PATCH 107/346 arm64/sme: Always exit sme_alloc() early with existing storage

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mark Brown <[email protected]>

commit dc7eb8755797ed41a0d1b5c0c39df3c8f401b3d9 upstream.

When sme_alloc() is called with existing storage and we are not flushing we will always allocate new storage, both leaking the existing storage and corrupting the state. Fix this by separating the checks for flushing and for existing storage as we do for SVE.

Callers that reallocate (eg, due to changing the vector length) should call sme_free() themselves.

Fixes 5d0a8d2fba50 ("arm64/ptrace: Ensure that SME is set up for target when writing SSVE state")
---
 arch/arm64/kernel/fpsimd.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
arch/arm64/kernel/fpsimd.c +4 -2
@@ -1245,8 +1245,10 @@ void fpsimd_release_task(struct task_str
  */
 void sme_alloc(struct task_struct *task, bool flush)
 {
-	if (task->thread.sme_state && flush) {
-		memset(task->thread.sme_state, 0, sme_state_size(task));
+	if (task->thread.sme_state) {
+		if (flush)
+			memset(task->thread.sme_state, 0,
+			       sme_state_size(task));
 		return;
 	}
 
author maintainer
#108 lore raw

PATCH 108/346 arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mark Rutland <[email protected]>

commit 832dd634bd1b4e3bbe9f10b9c9ba5db6f6f2b97f upstream.

Currently the ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD workaround isn't quite right, as it is supposed to be applied after the last explicit memory access, but is immediately followed by an LDR.

The ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD workaround is used to handle Cortex-A520 erratum 2966298 and Cortex-A510 erratum 3117295, which are described in:

* https://developer.arm.com/documentation/SDEN2444153/0600/?lang=en
* https://developer.arm.com/documentation/SDEN1873361/1600/?lang=en

In both cases the workaround is described as:

| If pagetable isolation is disabled, the context switch logic in the
| kernel can be updated to execute the following sequence on affected
| cores before exiting to EL0, and after all explicit memory accesses:
|
| 1. A non-shareable TLBI to any context and/or address, including
|    unused contexts or addresses, such as a `TLBI VALE1 Xzr`.
|
| 2. A DSB NSH to guarantee completion of the TLBI.

The important part being that the TLBI+DSB must be placed "after all explicit memory accesses".

Unfortunately, as-implemented, the TLBI+DSB is immediately followed by an LDR, as we have:

| alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
| 	tlbi	vale1, xzr
| 	dsb	nsh
| alternative_else_nop_endif
| alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
| 	ldr	lr, [sp, #S_LR]
| 	add	sp, sp, #PT_REGS_SIZE		// restore sp
| 	eret
| alternative_else_nop_endif
|
| [ ... KPTI exception return path ... ]

This patch fixes this by reworking the logic to place the TLBI+DSB immediately before the ERET, after all explicit memory accesses.

The ERET is currently in a separate alternative block, and alternatives cannot be nested. To account for this, the alternative block for ARM64_UNMAP_KERNEL_AT_EL0 is replaced with a single alternative branch to skip the KPTI logic, with the new shape of the logic being:

| alternative_insn "b .L_skip_tramp_exit_\@", nop, ARM64_UNMAP_KERNEL_AT_EL0
| 	[ ... KPTI exception return path ... ]
| .L_skip_tramp_exit_\@:
|
| 	ldr	lr, [sp, #S_LR]
| 	add	sp, sp, #PT_REGS_SIZE		// restore sp
|
| alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
| 	tlbi	vale1, xzr
| 	dsb	nsh
| alternative_else_nop_endif
| 	eret

The new structure means that the workaround is only applied when KPTI is not in use; this is fine as noted in the documented implications of the erratum:

| Pagetable isolation between EL0 and higher level ELs prevents the | issue from occurring.

... and as per the workaround description quoted above, the workaround is only necessary "If pagetable isolation is disabled".

Fixes 471470bc7052 ("arm64: errata: Add Cortex-A520 speculative unprivileged load workaround")
Cc Catalin Marinas <[email protected]>
Cc James Morse <[email protected]>
Cc Rob Herring <[email protected]>
Cc Will Deacon <[email protected]>
---
 arch/arm64/kernel/entry.S |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)
arch/arm64/kernel/entry.S +13 -9
@@ -428,16 +428,9 @@ alternative_else_nop_endif
 	ldp	x28, x29, [sp, #16 * 14]
 
 	.if	\el == 0
-alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
-	tlbi	vale1, xzr
-	dsb	nsh
-alternative_else_nop_endif
-alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0
-	ldr	lr, [sp, #S_LR]
-	add	sp, sp, #PT_REGS_SIZE		// restore sp
-	eret
-alternative_else_nop_endif
 #ifdef CONFIG_UNMAP_KERNEL_AT_EL0
+	alternative_insn "b .L_skip_tramp_exit_\@", nop, ARM64_UNMAP_KERNEL_AT_EL0
+
 	msr	far_el1, x29
 
 	ldr_this_cpu	x30, this_cpu_vector, x29
@@ -446,7 +439,18 @@ alternative_else_nop_endif
 	ldr		lr, [sp, #S_LR]		// restore x30
 	add		sp, sp, #PT_REGS_SIZE	// restore sp
 	br		x29
+
+.L_skip_tramp_exit_\@:
 #endif
+	ldr	lr, [sp, #S_LR]
+	add	sp, sp, #PT_REGS_SIZE		// restore sp
+
+	/* This must be after the last explicit memory access */
+alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD
+	tlbi	vale1, xzr
+	dsb	nsh
+alternative_else_nop_endif
+	eret
 	.else
 	ldr	lr, [sp, #S_LR]
 	add	sp, sp, #PT_REGS_SIZE		// restore sp
author maintainer
#109 lore raw

PATCH 109/346 rtc: cmos: Use ACPI alarm for non-Intel x86 systems too

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <[email protected]>

commit 3d762e21d56370a43478b55e604b4a83dd85aafc upstream.

Intel systems > 2015 have been configured to use ACPI alarm instead of HPET to avoid s2idle issues.

Having HPET programmed for wakeup causes problems on AMD systems with s2idle as well.

One particular case is that the systemd "SuspendThenHibernate" feature doesn't work properly on the Framework 13" AMD model. Switching to using ACPI alarm fixes the issue.

Adjust the quirk to apply to AMD/Hygon systems from 2021 onwards. This matches what has been tested and is specifically to avoid potential risk to older systems.

---
 drivers/rtc/rtc-cmos.c |   18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/rtc/rtc-cmos.c +12 -6
@@ -818,18 +818,24 @@ static void rtc_wake_off(struct device *
 }
 
 #ifdef CONFIG_X86
-/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
 static void use_acpi_alarm_quirks(void)
 {
-	if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_INTEL:
+		if (dmi_get_bios_year() < 2015)
+			return;
+		break;
+	case X86_VENDOR_AMD:
+	case X86_VENDOR_HYGON:
+		if (dmi_get_bios_year() < 2021)
+			return;
+		break;
+	default:
 		return;
-
+	}
 	if (!is_hpet_enabled())
 		return;
 
-	if (dmi_get_bios_year() < 2015)
-		return;
-
 	use_acpi_alarm = true;
 }
 #else
author maintainer
#110 lore raw

PATCH 110/346 rtc: Adjust failure return code for cmos_set_alarm()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <[email protected]>

commit 1311a8f0d4b23f58bbababa13623aa40b8ad4e0c upstream.

When mc146818_avoid_UIP() fails to return a valid value, this is because UIP didn't clear in the timeout period. Adjust the return code in this case to -ETIMEDOUT.

Fixes cdedc45c579f ("rtc: cmos: avoid UIP when reading alarm time")
Fixes cd17420ebea5 ("rtc: cmos: avoid UIP when writing alarm time")
---
 drivers/rtc/rtc-cmos.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/rtc/rtc-cmos.c +2 -2
@@ -292,7 +292,7 @@ static int cmos_read_alarm(struct device
 
 	/* This not only a rtc_op, but also called directly */
 	if (!is_valid_irq(cmos->irq))
-		return -EIO;
+		return -ETIMEDOUT;
 
 	/* Basic alarms only support hour, minute, and seconds fields.
 	 * Some also support day and month, for alarms up to a year in
@@ -557,7 +557,7 @@ static int cmos_set_alarm(struct device
 	 * Use mc146818_avoid_UIP() to avoid this.
 	 */
 	if (!mc146818_avoid_UIP(cmos_set_alarm_callback, &p))
-		return -EIO;
+		return -ETIMEDOUT;
 
 	cmos->alarm_expires = rtc_tm_to_time64(&t->time);
 
author maintainer
#111 lore raw

PATCH 111/346 rtc: mc146818-lib: Adjust failure return code for mc146818_get_time()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <[email protected]>

commit af838635a3eb9b1bc0d98599c101ebca98f31311 upstream.

mc146818_get_time() calls mc146818_avoid_UIP() to avoid fetching the time while RTC update is in progress (UIP). When this fails, the return code is -EIO, but actually there was no IO failure.

The reason for the return from mc146818_avoid_UIP() is that the UIP wasn't cleared in the time period. Adjust the return code to -ETIMEDOUT to match the behavior.

---
 drivers/rtc/rtc-mc146818-lib.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/rtc/rtc-mc146818-lib.c +1 -1
@@ -138,7 +138,7 @@ int mc146818_get_time(struct rtc_time *t
 
 	if (!mc146818_avoid_UIP(mc146818_get_time_callback, &p)) {
 		memset(time, 0, sizeof(*time));
-		return -EIO;
+		return -ETIMEDOUT;
 	}
 
 	if (!(p.ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
author maintainer
#87 lore raw

PATCH 87/346 arm64: dts: qcom: sc8180x: fix USB DP/DM HS PHY interrupts

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 687d402bb350b392fa330e9d9d1b917777ee9ed1 upstream.

The USB DP/DM HS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states and to be able to detect disconnect events, which requires triggering on falling edges.

A recent commit updated the trigger type but failed to change the interrupt provider as required. This leads to the current Linux driver failing to probe instead of printing an error during suspend and USB wakeup not working as intended.

Fixes 0dc0f6da3d43 ("arm64: dts: qcom: sc8180x: fix USB wakeup interrupt types")
Fixes b080f53a8f44 ("arm64: dts: qcom: sc8180x: Add remoteprocs, wifi and usb nodes")
Cc Vinod Koul <[email protected]>
---
 arch/arm64/boot/dts/qcom/sc8180x.dtsi |   16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/qcom/sc8180x.dtsi +8 -8
@@ -2552,10 +2552,10 @@
 		usb_prim: usb@a6f8800 {
 			compatible = "qcom,sc8180x-dwc3", "qcom,dwc3";
 			reg = <0 0x0a6f8800 0 0x400>;
-			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq",
 					  "ss_phy_irq",
 					  "dm_hs_phy_irq",
@@ -2626,10 +2626,10 @@
 				      "xo";
 			resets = <&gcc GCC_USB30_SEC_BCR>;
 			power-domains = <&gcc USB30_SEC_GDSC>;
-			interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 490 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 491 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#88 lore raw

PATCH 88/346 arm64: dts: qcom: sc8180x: fix USB SS wakeup

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 0afa885d42d05d30161ab8eab1ebacd993edb82b upstream.

The USB SS PHY interrupt needs to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states.

Fixes b080f53a8f44 ("arm64: dts: qcom: sc8180x: Add remoteprocs, wifi and usb nodes")
Cc Vinod Koul <[email protected]>
---
 arch/arm64/boot/dts/qcom/sc8180x.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sc8180x.dtsi +2 -2
@@ -2553,7 +2553,7 @@
 			compatible = "qcom,sc8180x-dwc3", "qcom,dwc3";
 			reg = <0 0x0a6f8800 0 0x400>;
 			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq",
@@ -2627,7 +2627,7 @@
 			resets = <&gcc GCC_USB30_SEC_BCR>;
 			power-domains = <&gcc USB30_SEC_GDSC>;
 			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 7 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
author maintainer
#89 lore raw

PATCH 89/346 arm64: dts: qcom: sdm670: fix USB DP/DM HS PHY interrupts

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit c42d12ea105f67b0f137f1e52d5c59d13fe12b1f upstream.

The USB DP/DM HS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states and to be able to detect disconnect events, which requires triggering on falling edges.

A recent commit updated the trigger type but failed to change the interrupt provider as required. This leads to the current Linux driver failing to probe instead of printing an error during suspend and USB wakeup not working as intended.

Fixes de3b3de30999 ("arm64: dts: qcom: sdm670: fix USB wakeup interrupt types")
Fixes 07c8ded6e373 ("arm64: dts: qcom: add sdm670 and pixel 3a device trees")
Cc Richard Acayan <[email protected]>
---
 arch/arm64/boot/dts/qcom/sdm670.dtsi |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/qcom/sdm670.dtsi +4 -4
@@ -1295,10 +1295,10 @@
 					  <&gcc GCC_USB30_PRIM_MASTER_CLK>;
 			assigned-clock-rates = <19200000>, <150000000>;
 
-			interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
-				     <GIC_SPI 488 IRQ_TYPE_EDGE_BOTH>,
-				     <GIC_SPI 489 IRQ_TYPE_EDGE_BOTH>;
+			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
+					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
 					  "dm_hs_phy_irq", "dp_hs_phy_irq";
 
author maintainer
#90 lore raw

PATCH 90/346 arm64: dts: qcom: sdm670: fix USB SS wakeup

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 047b2edc35b8db22354b4fba37818b548fc18896 upstream.

The USB SS PHY interrupt needs to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states.

---
 arch/arm64/boot/dts/qcom/sdm670.dtsi |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm670.dtsi +1 -1
@@ -1296,7 +1296,7 @@
 			assigned-clock-rates = <19200000>, <150000000>;
 
 			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 6 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 8 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
author maintainer
#91 lore raw

PATCH 91/346 ARM: dts: qcom: sdx55: fix USB SS wakeup

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 710dd03464e4ab5b3d329768388b165d61958577 upstream.

The USB SS PHY interrupt needs to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states.

---
 arch/arm/boot/dts/qcom/qcom-sdx55.dtsi |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/qcom/qcom-sdx55.dtsi +1 -1
@@ -586,7 +586,7 @@
 			assigned-clock-rates = <19200000>, <200000000>;
 
 			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc 51 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc 11 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc 10 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
author maintainer
#92 lore raw

PATCH 92/346 lsm: new security_file_ioctl_compat() hook

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Alfred Piccioni <[email protected]>

commit f1bb47a31dff6d4b34fb14e99850860ee74bb003 upstream.

Some ioctl commands do not require ioctl permission, but are routed to other permissions such as FILE_GETATTR or FILE_SETATTR. This routing is done by comparing the ioctl cmd to a set of 64-bit flags (FS_IOC_*).

However, if a 32-bit process is running on a 64-bit kernel, it emits 32-bit flags (FS_IOC32_*) for certain ioctl operations. These flags are being checked erroneously, which leads to these ioctl operations being routed to the ioctl permission, rather than the correct file permissions.

This was also noted in a RED-PEN finding from a while back - "/* RED-PEN how should LSM module know it's handling 32bit? */".

This patch introduces a new hook, security_file_ioctl_compat(), that is called from the compat ioctl syscall. All current LSMs have been changed to support this hook.

Reviewing the three places where we are currently using security_file_ioctl(), it appears that only SELinux needs a dedicated compat change; TOMOYO and SMACK appear to be functional without any change.

Fixes 0b24dcb7f2f7 ("Revert "selinux: simplify ioctl checking"")
[PM: subject tweak, line length fixes, and alignment corrections]
---
 fs/ioctl.c                    |    3 +--
 include/linux/lsm_hook_defs.h |    2 ++
 include/linux/security.h      |    9 +++++++++
 security/security.c           |   18 ++++++++++++++++++
 security/selinux/hooks.c      |   28 ++++++++++++++++++++++++++++
 security/smack/smack_lsm.c    |    1 +
 security/tomoyo/tomoyo.c      |    1 +
 7 files changed, 60 insertions(+), 2 deletions(-)
fs/ioctl.c +1 -2
@@ -920,8 +920,7 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned i
 	if (!f.file)
 		return -EBADF;
 
-	/* RED-PEN how should LSM module know it's handling 32bit? */
-	error = security_file_ioctl(f.file, cmd, arg);
+	error = security_file_ioctl_compat(f.file, cmd, arg);
 	if (error)
 		goto out;
 
include/linux/lsm_hook_defs.h +2 -0
@@ -171,6 +171,8 @@ LSM_HOOK(int, 0, file_alloc_security, st
 LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file)
 LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd,
 	 unsigned long arg)
+LSM_HOOK(int, 0, file_ioctl_compat, struct file *file, unsigned int cmd,
+	 unsigned long arg)
 LSM_HOOK(int, 0, mmap_addr, unsigned long addr)
 LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot,
 	 unsigned long prot, unsigned long flags)
include/linux/security.h +9 -0
@@ -389,6 +389,8 @@ int security_file_permission(struct file
 int security_file_alloc(struct file *file);
 void security_file_free(struct file *file);
 int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+int security_file_ioctl_compat(struct file *file, unsigned int cmd,
+			       unsigned long arg);
 int security_mmap_file(struct file *file, unsigned long prot,
 			unsigned long flags);
 int security_mmap_addr(unsigned long addr);
@@ -986,6 +988,13 @@ static inline int security_file_ioctl(st
 {
 	return 0;
 }
+
+static inline int security_file_ioctl_compat(struct file *file,
+					     unsigned int cmd,
+					     unsigned long arg)
+{
+	return 0;
+}
 
 static inline int security_mmap_file(struct file *file, unsigned long prot,
 				     unsigned long flags)
security/security.c +18 -0
@@ -2648,6 +2648,24 @@ int security_file_ioctl(struct file *fil
 }
 EXPORT_SYMBOL_GPL(security_file_ioctl);
 
+/**
+ * security_file_ioctl_compat() - Check if an ioctl is allowed in compat mode
+ * @file: associated file
+ * @cmd: ioctl cmd
+ * @arg: ioctl arguments
+ *
+ * Compat version of security_file_ioctl() that correctly handles 32-bit
+ * processes running on 64-bit kernels.
+ *
+ * Return: Returns 0 if permission is granted.
+ */
+int security_file_ioctl_compat(struct file *file, unsigned int cmd,
+			       unsigned long arg)
+{
+	return call_int_hook(file_ioctl_compat, 0, file, cmd, arg);
+}
+EXPORT_SYMBOL_GPL(security_file_ioctl_compat);
+
 static inline unsigned long mmap_prot(struct file *file, unsigned long prot)
 {
 	/*
security/selinux/hooks.c +28 -0
@@ -3725,6 +3725,33 @@ static int selinux_file_ioctl(struct fil
 	return error;
 }
 
+static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd,
+			      unsigned long arg)
+{
+	/*
+	 * If we are in a 64-bit kernel running 32-bit userspace, we need to
+	 * make sure we don't compare 32-bit flags to 64-bit flags.
+	 */
+	switch (cmd) {
+	case FS_IOC32_GETFLAGS:
+		cmd = FS_IOC_GETFLAGS;
+		break;
+	case FS_IOC32_SETFLAGS:
+		cmd = FS_IOC_SETFLAGS;
+		break;
+	case FS_IOC32_GETVERSION:
+		cmd = FS_IOC_GETVERSION;
+		break;
+	case FS_IOC32_SETVERSION:
+		cmd = FS_IOC_SETVERSION;
+		break;
+	default:
+		break;
+	}
+
+	return selinux_file_ioctl(file, cmd, arg);
+}
+
 static int default_noexec __ro_after_init;
 
 static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
@@ -7037,6 +7064,7 @@ static struct security_hook_list selinux
 	LSM_HOOK_INIT(file_permission, selinux_file_permission),
 	LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
 	LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
+	LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat),
 	LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
 	LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
 	LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
security/smack/smack_lsm.c +1 -0
@@ -4973,6 +4973,7 @@ static struct security_hook_list smack_h
 
 	LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security),
 	LSM_HOOK_INIT(file_ioctl, smack_file_ioctl),
+	LSM_HOOK_INIT(file_ioctl_compat, smack_file_ioctl),
 	LSM_HOOK_INIT(file_lock, smack_file_lock),
 	LSM_HOOK_INIT(file_fcntl, smack_file_fcntl),
 	LSM_HOOK_INIT(mmap_file, smack_mmap_file),
security/tomoyo/tomoyo.c +1 -0
@@ -568,6 +568,7 @@ static struct security_hook_list tomoyo_
 	LSM_HOOK_INIT(path_rename, tomoyo_path_rename),
 	LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr),
 	LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl),
+	LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl),
 	LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod),
 	LSM_HOOK_INIT(path_chown, tomoyo_path_chown),
 	LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot),
author maintainer
#84 lore raw

PATCH 84/346 arm64: dts: qcom: sdm845: fix USB SS wakeup

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Johan Hovold <[email protected]>

commit 971f5d8b0618d09db75184ddd8cca0767514db5d upstream.

The USB SS PHY interrupts need to be provided by the PDC interrupt controller in order to be able to wake the system up from low-power states.

---
 arch/arm64/boot/dts/qcom/sdm845.dtsi |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/sdm845.dtsi +2 -2
@@ -4054,7 +4054,7 @@
 			assigned-clock-rates = <19200000>, <150000000>;
 
 			interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc_intc 6 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc_intc 8 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
@@ -4105,7 +4105,7 @@
 			assigned-clock-rates = <19200000>, <150000000>;
 
 			interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
-					      <&intc GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>,
+					      <&pdc_intc 7 IRQ_TYPE_LEVEL_HIGH>,
 					      <&pdc_intc 10 IRQ_TYPE_EDGE_BOTH>,
 					      <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>;
 			interrupt-names = "hs_phy_irq", "ss_phy_irq",
author maintainer
#93 lore raw

PATCH 93/346 dlm: use kernel_connect() and kernel_bind()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jordan Rife <[email protected]>

commit e9cdebbe23f1aa9a1caea169862f479ab3fa2773 upstream.

Recent changes to kernel_connect() and kernel_bind() ensure that callers are insulated from changes to the address parameter made by BPF SOCK_ADDR hooks. This patch wraps direct calls to ops->connect() and ops->bind() with kernel_connect() and kernel_bind() to protect callers in such cases.

Fixes d74bad4e74ee ("bpf: Hooks for sys_connect")
Fixes 4fbac77d2d09 ("bpf: Hooks for sys_bind")
---
 fs/dlm/lowcomms.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
fs/dlm/lowcomms.c +7 -7
@@ -1817,8 +1817,8 @@ static int dlm_tcp_bind(struct socket *s
 	memcpy(&src_addr, &dlm_local_addr[0], sizeof(src_addr));
 	make_sockaddr(&src_addr, 0, &addr_len);
 
-	result = sock->ops->bind(sock, (struct sockaddr *)&src_addr,
-				 addr_len);
+	result = kernel_bind(sock, (struct sockaddr *)&src_addr,
+			     addr_len);
 	if (result < 0) {
 		/* This *may* not indicate a critical error */
 		log_print("could not bind for connect: %d", result);
@@ -1830,7 +1830,7 @@ static int dlm_tcp_bind(struct socket *s
 static int dlm_tcp_connect(struct connection *con, struct socket *sock,
 			   struct sockaddr *addr, int addr_len)
 {
-	return sock->ops->connect(sock, addr, addr_len, O_NONBLOCK);
+	return kernel_connect(sock, addr, addr_len, O_NONBLOCK);
 }
 
 static int dlm_tcp_listen_validate(void)
@@ -1862,8 +1862,8 @@ static int dlm_tcp_listen_bind(struct so
 
 	/* Bind to our port */
 	make_sockaddr(&dlm_local_addr[0], dlm_config.ci_tcp_port, &addr_len);
-	return sock->ops->bind(sock, (struct sockaddr *)&dlm_local_addr[0],
-			       addr_len);
+	return kernel_bind(sock, (struct sockaddr *)&dlm_local_addr[0],
+			   addr_len);
 }
 
 static const struct dlm_proto_ops dlm_tcp_ops = {
@@ -1888,12 +1888,12 @@ static int dlm_sctp_connect(struct conne
 	int ret;
 
 	/*
-	 * Make sock->ops->connect() function return in specified time,
+	 * Make kernel_connect() function return in specified time,
 	 * since O_NONBLOCK argument in connect() function does not work here,
 	 * then, we should restore the default value of this attribute.
 	 */
 	sock_set_sndtimeo(sock->sk, 5);
-	ret = sock->ops->connect(sock, addr, addr_len, 0);
+	ret = kernel_connect(sock, addr, addr_len, 0);
 	sock_set_sndtimeo(sock->sk, 0);
 	return ret;
 }
author maintainer
#113 lore raw

PATCH 113/346 rtc: Extend timeout for waiting for UIP to clear to 1s

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Mario Limonciello <[email protected]>

commit cef9ecc8e938dd48a560f7dd9be1246359248d20 upstream.

Specs don't say anything about UIP being cleared within 10ms. They only say that UIP won't occur for another 244uS. If a long NMI occurs while UIP is still updating it might not be possible to get valid data in 10ms.

This has been observed in the wild that around s2idle some calls can take up to 480ms before UIP is clear.

Adjust callers from outside an interrupt context to wait for up to a 1s instead of 10ms.

---
 arch/x86/kernel/rtc.c          |    2 +-
 drivers/base/power/trace.c     |    2 +-
 drivers/rtc/rtc-cmos.c         |    2 +-
 drivers/rtc/rtc-mc146818-lib.c |    2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)
arch/x86/kernel/rtc.c +1 -1
@@ -67,7 +67,7 @@ void mach_get_cmos_time(struct timespec6
 		return;
 	}
 
-	if (mc146818_get_time(&tm, 10)) {
+	if (mc146818_get_time(&tm, 1000)) {
 		pr_err("Unable to read current time from RTC\n");
 		now->tv_sec = now->tv_nsec = 0;
 		return;
drivers/base/power/trace.c +1 -1
@@ -120,7 +120,7 @@ static unsigned int read_magic_time(void
 	struct rtc_time time;
 	unsigned int val;
 
-	if (mc146818_get_time(&time, 10) < 0) {
+	if (mc146818_get_time(&time, 1000) < 0) {
 		pr_err("Unable to read current time from RTC\n");
 		return 0;
 	}
drivers/rtc/rtc-cmos.c +1 -1
@@ -231,7 +231,7 @@ static int cmos_read_time(struct device
 	if (!pm_trace_rtc_valid())
 		return -EIO;
 
-	ret = mc146818_get_time(t, 10);
+	ret = mc146818_get_time(t, 1000);
 	if (ret < 0) {
 		dev_err_ratelimited(dev, "unable to read current time\n");
 		return ret;
drivers/rtc/rtc-mc146818-lib.c +1 -1
@@ -93,7 +93,7 @@ EXPORT_SYMBOL_GPL(mc146818_avoid_UIP);
  */
 bool mc146818_does_rtc_work(void)
 {
-	return mc146818_avoid_UIP(NULL, 10, NULL);
+	return mc146818_avoid_UIP(NULL, 1000, NULL);
 }
 EXPORT_SYMBOL_GPL(mc146818_does_rtc_work);
 
author maintainer
#122 lore raw

PATCH 122/346 selftests: mm: hugepage-vmemmap fails on 64K page size systems

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Donet Tom <[email protected]>

commit 00bcfcd47a52f50f07a2e88d730d7931384cb073 upstream.

The kernel sefltest mm/hugepage-vmemmap fails on architectures which has different page size other than 4K. In hugepage-vmemmap page size used is 4k so the pfn calculation will go wrong on systems which has different page size .The length of MAP_HUGETLB memory must be hugepage aligned but in hugepage-vmemmap map length is 2M so this will not get aligned if the system has differnet hugepage size.

Added psize() to get the page size and default_huge_page_size() to get the default hugepage size at run time, hugepage-vmemmap test pass on powerpc with 64K page size and x86 with 4K page size.

Result on powerpc without patch (page size 64K)
*# ./hugepage-vmemmap
Returned address is 0x7effff000000 whose pfn is 0
Head page flags (100000000) is invalid
check_page_flags: Invalid argument
*#

Result on powerpc with patch (page size 64K) *# ./hugepage-vmemmap
Returned address is 0x7effff000000 whose pfn is 600 *#

Result on x86 with patch (page size 4K)
*# ./hugepage-vmemmap
Returned address is 0x7fc7c2c00000 whose pfn is 1dac00 *#

---
 tools/testing/selftests/mm/hugepage-vmemmap.c |   29 ++++++++++++++++----------
 1 file changed, 18 insertions(+), 11 deletions(-)
tools/testing/selftests/mm/hugepage-vmemmap.c +18 -11
@@ -10,10 +10,7 @@
 #include <unistd.h>
 #include <sys/mman.h>
 #include <fcntl.h>
-
-#define MAP_LENGTH		(2UL * 1024 * 1024)
-
-#define PAGE_SIZE		4096
+#include "vm_util.h"
 
 #define PAGE_COMPOUND_HEAD	(1UL << 15)
 #define PAGE_COMPOUND_TAIL	(1UL << 16)
@@ -39,6 +36,9 @@
 #define MAP_FLAGS		(MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
 #endif
 
+static size_t pagesize;
+static size_t maplength;
+
 static void write_bytes(char *addr, size_t length)
 {
 	unsigned long i;
@@ -56,7 +56,7 @@ static unsigned long virt_to_pfn(void *a
 	if (fd < 0)
 		return -1UL;
 
-	lseek(fd, (unsigned long)addr / PAGE_SIZE * sizeof(pagemap), SEEK_SET);
+	lseek(fd, (unsigned long)addr / pagesize * sizeof(pagemap), SEEK_SET);
 	read(fd, &pagemap, sizeof(pagemap));
 	close(fd);
 
@@ -86,7 +86,7 @@ static int check_page_flags(unsigned lon
 	 * this also verifies kernel has correctly set the fake page_head to tail
 	 * while hugetlb_free_vmemmap is enabled.
 	 */
-	for (i = 1; i < MAP_LENGTH / PAGE_SIZE; i++) {
+	for (i = 1; i < maplength / pagesize; i++) {
 		read(fd, &pageflags, sizeof(pageflags));
 		if ((pageflags & TAIL_PAGE_FLAGS) != TAIL_PAGE_FLAGS ||
 		    (pageflags & HEAD_PAGE_FLAGS) == HEAD_PAGE_FLAGS) {
@@ -106,18 +106,25 @@ int main(int argc, char **argv)
 	void *addr;
 	unsigned long pfn;
 
-	addr = mmap(MAP_ADDR, MAP_LENGTH, PROT_READ | PROT_WRITE, MAP_FLAGS, -1, 0);
+	pagesize  = psize();
+	maplength = default_huge_page_size();
+	if (!maplength) {
+		printf("Unable to determine huge page size\n");
+		exit(1);
+	}
+
+	addr = mmap(MAP_ADDR, maplength, PROT_READ | PROT_WRITE, MAP_FLAGS, -1, 0);
 	if (addr == MAP_FAILED) {
 		perror("mmap");
 		exit(1);
 	}
 
 	/* Trigger allocation of HugeTLB page. */
-	write_bytes(addr, MAP_LENGTH);
+	write_bytes(addr, maplength);
 
 	pfn = virt_to_pfn(addr);
 	if (pfn == -1UL) {
-		munmap(addr, MAP_LENGTH);
+		munmap(addr, maplength);
 		perror("virt_to_pfn");
 		exit(1);
 	}
@@ -125,13 +132,13 @@ int main(int argc, char **argv)
 	printf("Returned address is %p whose pfn is %lx\n", addr, pfn);
 
 	if (check_page_flags(pfn) < 0) {
-		munmap(addr, MAP_LENGTH);
+		munmap(addr, maplength);
 		perror("check_page_flags");
 		exit(1);
 	}
 
 	/* munmap() length of MAP_HUGETLB memory must be hugepage aligned */
-	if (munmap(addr, MAP_LENGTH)) {
+	if (munmap(addr, maplength)) {
 		perror("munmap");
 		exit(1);
 	}
author maintainer
#123 lore raw

PATCH 123/346 mm/rmap: fix misplaced parenthesis of a likely()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Steven Rostedt (Google) <[email protected]>

commit f67f8d4a8c1e1ebc85a6cbdb9a7266f14863461c upstream.

Running my yearly branch profiler to see where likely/unlikely annotation may be added or removed, I discovered this:

correct incorrect % Function File Line
------- --------- - -------- ---- ----

       0   457918 100 page_try_dup_anon_rmap         rmap.h               264

[..]
458021 0 0 page_try_dup_anon_rmap rmap.h 265

I thought it was interesting that line 264 of rmap.h had a 100% incorrect annotation, but the line directly below it was 100% correct. Looking at the code:

	if (likely(!is_device_private_page(page) &&
	    unlikely(page_needs_cow_for_dma(vma, page))))

It didn't make sense. The "likely()" was around the entire if statement (not just the "!is_device_private_page(page)"), which also included the "unlikely()" portion of that if condition.

If the unlikely portion is unlikely to be true, that would make the entire if condition unlikely to be true, so it made no sense at all to say the entire if condition is true.

What is more likely to be likely is just the first part of the if statement before the && operation. It's likely to be a misplaced parenthesis. And after making the if condition broken into a likely() && unlikely(), both now appear to be correct!

Fixes fb3d824d1a46c ("mm/rmap: split page_dup_rmap() into page_dup_file_rmap() and page_try_dup_anon_rmap()")
Cc David Hildenbrand <[email protected]>
Cc Vlastimil Babka <[email protected]>
---
 include/linux/rmap.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/rmap.h +2 -2
@@ -261,8 +261,8 @@ static inline int page_try_dup_anon_rmap
 	 * guarantee the pinned page won't be randomly replaced in the
 	 * future on write faults.
 	 */
-	if (likely(!is_device_private_page(page) &&
-	    unlikely(page_needs_cow_for_dma(vma, page))))
+	if (likely(!is_device_private_page(page)) &&
+	    unlikely(page_needs_cow_for_dma(vma, page)))
 		return -EBUSY;
 
 	ClearPageAnonExclusive(page);
author maintainer
#124 lore raw

PATCH 124/346 mm: migrate: fix getting incorrect page mapping during page migration

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Baolin Wang <[email protected]>

commit d1adb25df7111de83b64655a80b5a135adbded61 upstream.

When running stress-ng testing, we found below kernel crash after a few hours:

Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
pc : dentry_name+0xd8/0x224
lr : pointer+0x22c/0x370
sp : ffff800025f134c0
......
Call trace:
  dentry_name+0xd8/0x224
  pointer+0x22c/0x370
  vsnprintf+0x1ec/0x730
  vscnprintf+0x2c/0x60
  vprintk_store+0x70/0x234
  vprintk_emit+0xe0/0x24c
  vprintk_default+0x3c/0x44
  vprintk_func+0x84/0x2d0
  printk+0x64/0x88
  __dump_page+0x52c/0x530
  dump_page+0x14/0x20
  set_migratetype_isolate+0x110/0x224
  start_isolate_page_range+0xc4/0x20c
  offline_pages+0x124/0x474
  memory_block_offline+0x44/0xf4
  memory_subsys_offline+0x3c/0x70
  device_offline+0xf0/0x120
  ......

After analyzing the vmcore, I found this issue is caused by page migration. The scenario is that, one thread is doing page migration, and we will use the target page's ->mapping field to save 'anon_vma' pointer between page unmap and page move, and now the target page is locked and refcount is 1.

Currently, there is another stress-ng thread performing memory hotplug, attempting to offline the target page that is being migrated. It discovers that the refcount of this target page is 1, preventing the offline operation, thus proceeding to dump the page. However, page_mapping() of the target page may return an incorrect file mapping to crash the system in dump_mapping(), since the target page->mapping only saves 'anon_vma' pointer without setting PAGE_MAPPING_ANON flag.

There are seveval ways to fix this issue:
(1) Setting the PAGE_MAPPING_ANON flag for target page's ->mapping when saving 'anon_vma', but this can confuse PageAnon() for PFN walkers, since the target page has not built mappings yet.
(2) Getting the page lock to call page_mapping() in __dump_page() to avoid crashing the system, however, there are still some PFN walkers that call page_mapping() without holding the page lock, such as compaction.
(3) Using target page->private field to save the 'anon_vma' pointer and 2 bits page state, just as page->mapping records an anonymous page, which can remove the page_mapping() impact for PFN walkers and also seems a simple way.

So I choose option 3 to fix this issue, and this can also fix other potential issues for PFN walkers, such as compaction.

---
 mm/migrate.c |   27 ++++++++++-----------------
 1 file changed, 10 insertions(+), 17 deletions(-)
mm/migrate.c +10 -17
@@ -1025,38 +1025,31 @@ out:
 }
 
 /*
- * To record some information during migration, we use some unused
- * fields (mapping and private) of struct folio of the newly allocated
- * destination folio.  This is safe because nobody is using them
- * except us.
+ * To record some information during migration, we use unused private
+ * field of struct folio of the newly allocated destination folio.
+ * This is safe because nobody is using it except us.
  */
-union migration_ptr {
-	struct anon_vma *anon_vma;
-	struct address_space *mapping;
-};
-
 enum {
 	PAGE_WAS_MAPPED = BIT(0),
 	PAGE_WAS_MLOCKED = BIT(1),
+	PAGE_OLD_STATES = PAGE_WAS_MAPPED | PAGE_WAS_MLOCKED,
 };
 
 static void __migrate_folio_record(struct folio *dst,
-				   unsigned long old_page_state,
+				   int old_page_state,
 				   struct anon_vma *anon_vma)
 {
-	union migration_ptr ptr = { .anon_vma = anon_vma };
-	dst->mapping = ptr.mapping;
-	dst->private = (void *)old_page_state;
+	dst->private = (void *)anon_vma + old_page_state;
 }
 
 static void __migrate_folio_extract(struct folio *dst,
 				   int *old_page_state,
 				   struct anon_vma **anon_vmap)
 {
-	union migration_ptr ptr = { .mapping = dst->mapping };
-	*anon_vmap = ptr.anon_vma;
-	*old_page_state = (unsigned long)dst->private;
-	dst->mapping = NULL;
+	unsigned long private = (unsigned long)dst->private;
+
+	*anon_vmap = (struct anon_vma *)(private & ~PAGE_OLD_STATES);
+	*old_page_state = private & PAGE_OLD_STATES;
 	dst->private = NULL;
 }
 
author maintainer
#125 lore raw

PATCH 125/346 mm/sparsemem: fix race in accessing memory_section->usage

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Charan Teja Kalla <[email protected]>

commit 5ec8e8ea8b7783fab150cf86404fc38cb4db8800 upstream.

The below race is observed on a PFN which falls into the device memory region with the system memory configuration where PFN's are such that [ZONE_NORMAL ZONE_DEVICE ZONE_NORMAL]. Since normal zone start and end pfn contains the device memory PFN's as well, the compaction triggered will try on the device memory PFN's too though they end up in NOP(because pfn_to_online_page() returns NULL for ZONE_DEVICE memory sections). When from other core, the section mappings are being removed for the ZONE_DEVICE region, that the PFN in question belongs to, on which compaction is currently being operated is resulting into the kernel crash with CONFIG_SPASEMEM_VMEMAP enabled. The crash logs can be seen at [1].

compact_zone() memunmap_pages
------------- ---------------
__pageblock_pfn_to_page
......
(a)pfn_valid():

     valid_section()//return true
			      (b)__remove_pages()->
				  sparse_remove_section()->
				    section_deactivate():
				    [Free the array ms->usage and set
				     ms->usage = NULL]
     pfn_section_valid()
     [Access ms->usage which
     is NULL]

NOTE: From the above it can be said that the race is reduced to between the pfn_valid()/pfn_section_valid() and the section deactivate with SPASEMEM_VMEMAP enabled.

The commit b943f045a9af("mm/sparse: fix kernel crash with pfn_section_valid check") tried to address the same problem by clearing the SECTION_HAS_MEM_MAP with the expectation of valid_section() returns false thus ms->usage is not accessed.

Fix this issue by the below steps:

a) Clear SECTION_HAS_MEM_MAP before freeing the ->usage.

b) RCU protected read side critical section will either return NULL when SECTION_HAS_MEM_MAP is cleared or can successfully access ->usage.

c) Free the ->usage with kfree_rcu() and set ms->usage = NULL. No attempt will be made to access ->usage after this as the SECTION_HAS_MEM_MAP is cleared thus valid_section() return false.

Thanks to David/Pavan for their inputs on this patch.

[1] https://lore.kernel.org/linux-mm/[email protected]/

On Snapdragon SoC, with the mentioned memory configuration of PFN's as [ZONE_NORMAL ZONE_DEVICE ZONE_NORMAL], we are able to see bunch of issues daily while testing on a device farm.

For this particular issue below is the log. Though the below log is not directly pointing to the pfn_section_valid(){ ms->usage;}, when we loaded this dump on T32 lauterbach tool, it is pointing.

[  540.578056] Unable to handle kernel NULL pointer dereference at
virtual address 0000000000000000
[  540.578068] Mem abort info:
[  540.578070]   ESR = 0x0000000096000005
[  540.578073]   EC = 0x25: DABT (current EL), IL = 32 bits
[  540.578077]   SET = 0, FnV = 0
[  540.578080]   EA = 0, S1PTW = 0
[  540.578082]   FSC = 0x05: level 1 translation fault
[  540.578085] Data abort info:
[  540.578086]   ISV = 0, ISS = 0x00000005
[  540.578088]   CM = 0, WnR = 0
[  540.579431] pstate: 82400005 (Nzcv daif +PAN -UAO +TCO -DIT -SSBSBTYPE=--)
[  540.579436] pc : __pageblock_pfn_to_page+0x6c/0x14c
[  540.579454] lr : compact_zone+0x994/0x1058
[  540.579460] sp : ffffffc03579b510
[  540.579463] x29: ffffffc03579b510 x28: 0000000000235800 x27:000000000000000c
[  540.579470] x26: 0000000000235c00 x25: 0000000000000068 x24:ffffffc03579b640
[  540.579477] x23: 0000000000000001 x22: ffffffc03579b660 x21:0000000000000000
[  540.579483] x20: 0000000000235bff x19: ffffffdebf7e3940 x18:ffffffdebf66d140
[  540.579489] x17: 00000000739ba063 x16: 00000000739ba063 x15:00000000009f4bff
[  540.579495] x14: 0000008000000000 x13: 0000000000000000 x12:0000000000000001
[  540.579501] x11: 0000000000000000 x10: 0000000000000000 x9 :ffffff897d2cd440
[  540.579507] x8 : 0000000000000000 x7 : 0000000000000000 x6 :ffffffc03579b5b4
[  540.579512] x5 : 0000000000027f25 x4 : ffffffc03579b5b8 x3 :0000000000000001
[  540.579518] x2 : ffffffdebf7e3940 x1 : 0000000000235c00 x0 :0000000000235800
[  540.579524] Call trace:
[  540.579527]  __pageblock_pfn_to_page+0x6c/0x14c
[  540.579533]  compact_zone+0x994/0x1058
[  540.579536]  try_to_compact_pages+0x128/0x378
[  540.579540]  __alloc_pages_direct_compact+0x80/0x2b0
[  540.579544]  __alloc_pages_slowpath+0x5c0/0xe10
[  540.579547]  __alloc_pages+0x250/0x2d0
[  540.579550]  __iommu_dma_alloc_noncontiguous+0x13c/0x3fc
[  540.579561]  iommu_dma_alloc+0xa0/0x320
[  540.579565]  dma_alloc_attrs+0xd4/0x108
[[email protected]: use kfree_rcu() in place of synchronize_rcu(), per David]
Fixes f46edbd1b151 ("mm/sparsemem: add helpers track active portions of a section at boot")
Cc Aneesh Kumar K.V <[email protected]>
Cc Dan Williams <[email protected]>
Cc David Hildenbrand <[email protected]>
Cc Mel Gorman <[email protected]>
Cc Oscar Salvador <[email protected]>
Cc Vlastimil Babka <[email protected]>
---
 include/linux/mmzone.h |   14 +++++++++++---
 mm/sparse.c            |   17 +++++++++--------
 2 files changed, 20 insertions(+), 11 deletions(-)
include/linux/mmzone.h +11 -3
@@ -1793,6 +1793,7 @@ static inline unsigned long section_nr_t
 #define SUBSECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SUBSECTION_MASK)
 
 struct mem_section_usage {
+	struct rcu_head rcu;
 #ifdef CONFIG_SPARSEMEM_VMEMMAP
 	DECLARE_BITMAP(subsection_map, SUBSECTIONS_PER_SECTION);
 #endif
@@ -1986,7 +1987,7 @@ static inline int pfn_section_valid(stru
 {
 	int idx = subsection_map_index(pfn);
 
-	return test_bit(idx, ms->usage->subsection_map);
+	return test_bit(idx, READ_ONCE(ms->usage)->subsection_map);
 }
 #else
 static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn)
@@ -2010,6 +2011,7 @@ static inline int pfn_section_valid(stru
 static inline int pfn_valid(unsigned long pfn)
 {
 	struct mem_section *ms;
+	int ret;
 
 	/*
 	 * Ensure the upper PAGE_SHIFT bits are clear in the
@@ -2023,13 +2025,19 @@ static inline int pfn_valid(unsigned lon
 	if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
 		return 0;
 	ms = __pfn_to_section(pfn);
-	if (!valid_section(ms))
+	rcu_read_lock();
+	if (!valid_section(ms)) {
+		rcu_read_unlock();
 		return 0;
+	}
 	/*
 	 * Traditionally early sections always returned pfn_valid() for
 	 * the entire section-sized span.
 	 */
-	return early_section(ms) || pfn_section_valid(ms, pfn);
+	ret = early_section(ms) || pfn_section_valid(ms, pfn);
+	rcu_read_unlock();
+
+	return ret;
 }
 #endif
 
mm/sparse.c +9 -8
@@ -792,6 +792,13 @@ static void section_deactivate(unsigned
 		unsigned long section_nr = pfn_to_section_nr(pfn);
 
 		/*
+		 * Mark the section invalid so that valid_section()
+		 * return false. This prevents code from dereferencing
+		 * ms->usage array.
+		 */
+		ms->section_mem_map &= ~SECTION_HAS_MEM_MAP;
+
+		/*
 		 * When removing an early section, the usage map is kept (as the
 		 * usage maps of other sections fall into the same page). It
 		 * will be re-used when re-adding the section - which is then no
@@ -799,16 +806,10 @@ static void section_deactivate(unsigned
 		 * was allocated during boot.
 		 */
 		if (!PageReserved(virt_to_page(ms->usage))) {
-			kfree(ms->usage);
-			ms->usage = NULL;
+			kfree_rcu(ms->usage, rcu);
+			WRITE_ONCE(ms->usage, NULL);
 		}
 		memmap = sparse_decode_mem_map(ms->section_mem_map, section_nr);
-		/*
-		 * Mark the section invalid so that valid_section()
-		 * return false. This prevents code from dereferencing
-		 * ms->usage array.
-		 */
-		ms->section_mem_map &= ~SECTION_HAS_MEM_MAP;
 	}
 
 	/*
author maintainer
#131 lore raw

PATCH 126/346 rename(): fix the locking of subdirectories

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Al Viro <[email protected]>

commit 22e111ed6c83dcde3037fc81176012721bc34c0b upstream.

We should never lock two subdirectories without having taken
->s_vfs_rename_mutex; inode pointer order or not, the "order" proposed in 28eceeda130f "fs: Lock moved directories" is not transitive, with the usual consequences.

The rationale for locking renamed subdirectory in all cases was
the possibility of race between rename modifying .. in a subdirectory to reflect the new parent and another thread modifying the same subdirectory. For a lot of filesystems that's not a problem, but for some it can lead to trouble (e.g. the case when short directory contents is kept in the inode, but creating a file in it might push it across the size limit and copy its contents into separate data block(s)).

However, we need that only in case when the parent does change -
otherwise ->rename() doesn't need to do anything with .. entry in the first place. Some instances are lazy and do a tautological update anyway, but it's really not hard to avoid.

Amended locking rules for rename():
find the parent(s) of source and target
if source and target have the same parent
lock the common parent
else
lock ->s_vfs_rename_mutex
lock both parents, in ancestor-first order; if neither is an ancestor of another, lock the parent of source first.
find the source and target.
if source and target have the same parent
if operation is an overwriting rename of a subdirectory
lock the target subdirectory
else
if source is a subdirectory
lock the source
if target is a subdirectory
lock the target
lock non-directories involved, in inode pointer order if both source and target are such.

That way we are guaranteed that parents are locked (for obvious reasons), that any renamed non-directory is locked (nfsd relies upon that), that any victim is locked (emptiness check needs that, among other things) and subdirectory that changes parent is locked (needed to protect the update of .. entries). We are also guaranteed that any operation locking more than one directory either takes ->s_vfs_rename_mutex or locks a parent followed by its child.

Fixes 28eceeda130f "fs: Lock moved directories"
---
 Documentation/filesystems/directory-locking.rst |   29 ++++++-----
 Documentation/filesystems/locking.rst           |    5 +-
 Documentation/filesystems/porting.rst           |   18 +++++++
 fs/namei.c                                      |   60 ++++++++++++++----------
 4 files changed, 74 insertions(+), 38 deletions(-)
Documentation/filesystems/directory-locking.rst +15 -14
@@ -22,13 +22,16 @@ exclusive.
 3) object removal.  Locking rules: caller locks parent, finds victim,
 locks victim and calls the method.  Locks are exclusive.
 
-4) rename() that is _not_ cross-directory.  Locking rules: caller locks the
-parent and finds source and target.  We lock both (provided they exist).  If we
-need to lock two inodes of different type (dir vs non-dir), we lock directory
-first.  If we need to lock two inodes of the same type, lock them in inode
-pointer order.  Then call the method.  All locks are exclusive.
-NB: we might get away with locking the source (and target in exchange
-case) shared.
+4) rename() that is _not_ cross-directory.  Locking rules: caller locks
+the parent and finds source and target.  Then we decide which of the
+source and target need to be locked.  Source needs to be locked if it's a
+non-directory; target - if it's a non-directory or about to be removed.
+Take the locks that need to be taken, in inode pointer order if need
+to take both (that can happen only when both source and target are
+non-directories - the source because it wouldn't be locked otherwise
+and the target because mixing directory and non-directory is allowed
+only with RENAME_EXCHANGE, and that won't be removing the target).
+After the locks had been taken, call the method.  All locks are exclusive.
 
 5) link creation.  Locking rules:
 
@@ -44,20 +47,17 @@ rules:
 
 	* lock the filesystem
 	* lock parents in "ancestors first" order. If one is not ancestor of
-	  the other, lock them in inode pointer order.
+	  the other, lock the parent of source first.
 	* find source and target.
 	* if old parent is equal to or is a descendent of target
 	  fail with -ENOTEMPTY
 	* if new parent is equal to or is a descendent of source
 	  fail with -ELOOP
-	* Lock both the source and the target provided they exist. If we
-	  need to lock two inodes of different type (dir vs non-dir), we lock
-	  the directory first. If we need to lock two inodes of the same type,
-	  lock them in inode pointer order.
+	* Lock subdirectories involved (source before target).
+	* Lock non-directories involved, in inode pointer order.
 	* call the method.
 
-All ->i_rwsem are taken exclusive.  Again, we might get away with locking
-the source (and target in exchange case) shared.
+All ->i_rwsem are taken exclusive.
 
 The rules above obviously guarantee that all directories that are going to be
 read, modified or removed by method will be locked by caller.
@@ -67,6 +67,7 @@ If no directory is its own ancestor, the
 
 Proof:
 
+[XXX: will be updated once we are done massaging the lock_rename()]
 	First of all, at any moment we have a linear ordering of the
 	objects - A < B iff (A is an ancestor of B) or (B is not an ancestor
         of A and ptr(A) < ptr(B)).
Documentation/filesystems/locking.rst +4 -1
@@ -101,7 +101,7 @@ symlink:	exclusive
 mkdir:		exclusive
 unlink:		exclusive (both)
 rmdir:		exclusive (both)(see below)
-rename:		exclusive (all)	(see below)
+rename:		exclusive (both parents, some children)	(see below)
 readlink:	no
 get_link:	no
 setattr:	exclusive
@@ -123,6 +123,9 @@ get_offset_ctx  no
 	Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_rwsem
 	exclusive on victim.
 	cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem.
+	->unlink() and ->rename() have ->i_rwsem exclusive on all non-directories
+	involved.
+	->rename() has ->i_rwsem exclusive on any subdirectory that changes parent.
 
 See Documentation/filesystems/directory-locking.rst for more detailed discussion
 of the locking scheme for directory operations.
Documentation/filesystems/porting.rst +18 -0
@@ -1061,3 +1061,21 @@ export_operations ->encode_fh() no longe
 encode FILEID_INO32_GEN* file handles.
 Filesystems that used the default implementation may use the generic helper
 generic_encode_ino32_fh() explicitly.
+
+---
+
+**mandatory**
+
+If ->rename() update of .. on cross-directory move needs an exclusion with
+directory modifications, do *not* lock the subdirectory in question in your
+->rename() - it's done by the caller now [that item should've been added in
+28eceeda130f "fs: Lock moved directories"].
+
+---
+
+**mandatory**
+
+On same-directory ->rename() the (tautological) update of .. is not protected
+by any locks; just don't do it if the old parent is the same as the new one.
+We really can't lock two subdirectories in same-directory rename - not without
+deadlocks.
fs/namei.c +37 -23

97 lines not on this page · raw message

author maintainer
#132 lore raw

PATCH 127/346 serial: sc16is7xx: improve regmap debugfs by using one regmap per port

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugo Villeneuve <[email protected]>

commit 3837a0379533aabb9e4483677077479f7c6aa910 upstream.

With this current driver regmap implementation, it is hard to make sense of the register addresses displayed using the regmap debugfs interface, because they do not correspond to the actual register addresses documented in the datasheet. For example, register 1 is displayed as registers 04 thru 07:

$ cat /sys/kernel/debug/regmap/spi0.0/registers
  04: 10 -> Port 0, register offset 1
  05: 10 -> Port 1, register offset 1
  06: 00 -> Port 2, register offset 1 -> invalid
  07: 00 -> port 3, register offset 1 -> invalid
  ...

The reason is that bits 0 and 1 of the register address correspond to the channel (port) bits, so the register address itself starts at bit 2, and we must 'mentally' shift each register address by 2 bits to get its real address/offset.

Also, only channels 0 and 1 are supported by the chip, so channel mask combinations of 10b and 11b are invalid, and the display of these registers is useless.

This patch adds a separate regmap configuration for each port, similar to what is done in the max310x driver, so that register addresses displayed match the register addresses in the chip datasheet. Also, each port now has its own debugfs entry.

Example with new regmap implementation:

$ cat /sys/kernel/debug/regmap/spi0.0-port0/registers
1: 10
2: 01
3: 00
...
$ cat /sys/kernel/debug/regmap/spi0.0-port1/registers
1: 10
2: 01
3: 00

As an added bonus, this also simplifies some operations (read/write/modify) because it is no longer necessary to manually shift register addresses.

---
 drivers/tty/serial/sc16is7xx.c |  143 +++++++++++++++++++++++------------------
 1 file changed, 81 insertions(+), 62 deletions(-)
drivers/tty/serial/sc16is7xx.c +81 -62
@@ -301,8 +301,8 @@
 
 
 /* Misc definitions */
+#define SC16IS7XX_SPI_READ_BIT		BIT(7)
 #define SC16IS7XX_FIFO_SIZE		(64)
-#define SC16IS7XX_REG_SHIFT		2
 #define SC16IS7XX_GPIOS_PER_BANK	4
 
 struct sc16is7xx_devtype {
@@ -324,6 +324,7 @@ struct sc16is7xx_one_config {
 struct sc16is7xx_one {
 	struct uart_port		port;
 	u8				line;
+	struct regmap			*regmap;
 	struct kthread_work		tx_work;
 	struct kthread_work		reg_work;
 	struct kthread_delayed_work	ms_work;
@@ -361,48 +362,37 @@ static void sc16is7xx_stop_tx(struct uar
 
 #define to_sc16is7xx_one(p,e)	((container_of((p), struct sc16is7xx_one, e)))
 
-static int sc16is7xx_line(struct uart_port *port)
-{
-	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
-
-	return one->line;
-}
-
 static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg)
 {
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 	unsigned int val = 0;
-	const u8 line = sc16is7xx_line(port);
 
-	regmap_read(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, &val);
+	regmap_read(one->regmap, reg, &val);
 
 	return val;
 }
 
 static void sc16is7xx_port_write(struct uart_port *port, u8 reg, u8 val)
 {
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
-	const u8 line = sc16is7xx_line(port);
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 
-	regmap_write(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, val);
+	regmap_write(one->regmap, reg, val);
 }
 
 static void sc16is7xx_fifo_read(struct uart_port *port, unsigned int rxlen)
 {
 	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
-	const u8 line = sc16is7xx_line(port);
-	u8 addr = (SC16IS7XX_RHR_REG << SC16IS7XX_REG_SHIFT) | line;
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 
-	regcache_cache_bypass(s->regmap, true);
-	regmap_raw_read(s->regmap, addr, s->buf, rxlen);
-	regcache_cache_bypass(s->regmap, false);
+	regcache_cache_bypass(one->regmap, true);
+	regmap_raw_read(one->regmap, SC16IS7XX_RHR_REG, s->buf, rxlen);
+	regcache_cache_bypass(one->regmap, false);
 }
 
 static void sc16is7xx_fifo_write(struct uart_port *port, u8 to_send)
 {
 	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
-	const u8 line = sc16is7xx_line(port);
-	u8 addr = (SC16IS7XX_THR_REG << SC16IS7XX_REG_SHIFT) | line;
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 
 	/*
 	 * Don't send zero-length data, at least on SPI it confuses the chip
@@ -411,19 +401,17 @@ static void sc16is7xx_fifo_write(struct
 	if (unlikely(!to_send))
 		return;
 
-	regcache_cache_bypass(s->regmap, true);
-	regmap_raw_write(s->regmap, addr, s->buf, to_send);
-	regcache_cache_bypass(s->regmap, false);
+	regcache_cache_bypass(one->regmap, true);
+	regmap_raw_write(one->regmap, SC16IS7XX_THR_REG, s->buf, to_send);
+	regcache_cache_bypass(one->regmap, false);
 }
 
 static void sc16is7xx_port_update(struct uart_port *port, u8 reg,
 				  u8 mask, u8 val)
 {
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
-	const u8 line = sc16is7xx_line(port);
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 
-	regmap_update_bits(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line,
-			   mask, val);
+	regmap_update_bits(one->regmap, reg, mask, val);
 }
 
 static int sc16is7xx_alloc_line(void)
@@ -478,7 +466,7 @@ static const struct sc16is7xx_devtype sc
 
 static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg)
 {
-	switch (reg >> SC16IS7XX_REG_SHIFT) {
+	switch (reg) {
 	case SC16IS7XX_RHR_REG:
 	case SC16IS7XX_IIR_REG:
 	case SC16IS7XX_LSR_REG:
@@ -497,7 +485,7 @@ static bool sc16is7xx_regmap_volatile(st
 
 static bool sc16is7xx_regmap_precious(struct device *dev, unsigned int reg)
 {
-	switch (reg >> SC16IS7XX_REG_SHIFT) {
+	switch (reg) {
 	case SC16IS7XX_RHR_REG:
 		return true;
 	default:
@@ -510,6 +498,7 @@ static bool sc16is7xx_regmap_precious(st
 static int sc16is7xx_set_baud(struct uart_port *port, int baud)
 {
 	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 	u8 lcr;
 	u8 prescaler = 0;
 	unsigned long clk = port->uartclk, div = clk / 16 / baud;
@@ -541,12 +530,12 @@ static int sc16is7xx_set_baud(struct uar
 			     SC16IS7XX_LCR_CONF_MODE_B);
 
 	/* Enable enhanced features */
-	regcache_cache_bypass(s->regmap, true);
+	regcache_cache_bypass(one->regmap, true);
 	sc16is7xx_port_update(port, SC16IS7XX_EFR_REG,
 			      SC16IS7XX_EFR_ENABLE_BIT,
 			      SC16IS7XX_EFR_ENABLE_BIT);
 
-	regcache_cache_bypass(s->regmap, false);
+	regcache_cache_bypass(one->regmap, false);
 
 	/* Put LCR back to the normal mode */
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
@@ -562,10 +551,10 @@ static int sc16is7xx_set_baud(struct uar
 			     SC16IS7XX_LCR_CONF_MODE_A);
 
 	/* Write the new divisor */
-	regcache_cache_bypass(s->regmap, true);
+	regcache_cache_bypass(one->regmap, true);
 	sc16is7xx_port_write(port, SC16IS7XX_DLH_REG, div / 256);
 	sc16is7xx_port_write(port, SC16IS7XX_DLL_REG, div % 256);
-	regcache_cache_bypass(s->regmap, false);
+	regcache_cache_bypass(one->regmap, false);
 
 	/* Put LCR back to the normal mode */
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
@@ -1091,7 +1080,7 @@ static void sc16is7xx_set_termios(struct
 			     SC16IS7XX_LCR_CONF_MODE_B);
 
 	/* Configure flow control */
-	regcache_cache_bypass(s->regmap, true);
+	regcache_cache_bypass(one->regmap, true);
 	sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]);
 	sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]);
 
@@ -1110,7 +1099,7 @@ static void sc16is7xx_set_termios(struct
 			      SC16IS7XX_EFR_REG,
 			      SC16IS7XX_EFR_FLOWCTRL_BITS,
 			      flow);
-	regcache_cache_bypass(s->regmap, false);
+	regcache_cache_bypass(one->regmap, false);
 
 	/* Update LCR register */
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
@@ -1161,7 +1150,6 @@ static int sc16is7xx_config_rs485(struct
 static int sc16is7xx_startup(struct uart_port *port)
 {
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
 	unsigned int val;
 	unsigned long flags;
 
@@ -1178,7 +1166,7 @@ static int sc16is7xx_startup(struct uart
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
 			     SC16IS7XX_LCR_CONF_MODE_B);
 
-	regcache_cache_bypass(s->regmap, true);
+	regcache_cache_bypass(one->regmap, true);
 
 	/* Enable write access to enhanced features and internal clock div */
 	sc16is7xx_port_update(port, SC16IS7XX_EFR_REG,
@@ -1196,7 +1184,7 @@ static int sc16is7xx_startup(struct uart
 			     SC16IS7XX_TCR_RX_RESUME(24) |
 			     SC16IS7XX_TCR_RX_HALT(48));
 
-	regcache_cache_bypass(s->regmap, false);
+	regcache_cache_bypass(one->regmap, false);
 
 	/* Now, initialize the UART */
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8);
@@ -1477,7 +1465,7 @@ static int sc16is7xx_setup_mctrl_ports(s
 	if (s->mctrl_mask)
 		regmap_update_bits(
 			s->regmap,
-			SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT,
+			SC16IS7XX_IOCONTROL_REG,
 			SC16IS7XX_IOCONTROL_MODEM_A_BIT |
 			SC16IS7XX_IOCONTROL_MODEM_B_BIT, s->mctrl_mask);
 
@@ -1492,7 +1480,7 @@ static const struct serial_rs485 sc16is7
 
 static int sc16is7xx_probe(struct device *dev,
 			   const struct sc16is7xx_devtype *devtype,
-			   struct regmap *regmap, int irq)
+			   struct regmap *regmaps[], int irq)
 {
 	unsigned long freq = 0, *pfreq = dev_get_platdata(dev);
 	unsigned int val;
@@ -1500,16 +1488,16 @@ static int sc16is7xx_probe(struct device
 	int i, ret;
 	struct sc16is7xx_port *s;
 
-	if (IS_ERR(regmap))
-		return PTR_ERR(regmap);
+	for (i = 0; i < devtype->nr_uart; i++)
+		if (IS_ERR(regmaps[i]))
+			return PTR_ERR(regmaps[i]);
 
 	/*
 	 * This device does not have an identification register that would
 	 * tell us if we are really connected to the correct device.
 	 * The best we can do is to check if communication is at all possible.
 	 */
-	ret = regmap_read(regmap,
-			  SC16IS7XX_LSR_REG << SC16IS7XX_REG_SHIFT, &val);
+	ret = regmap_read(regmaps[0], SC16IS7XX_LSR_REG, &val);
 	if (ret < 0)
 		return -EPROBE_DEFER;
 
@@ -1543,7 +1531,7 @@ static int sc16is7xx_probe(struct device
 			return -EINVAL;
 	}
 
-	s->regmap = regmap;
+	s->regmap = regmaps[0];
 	s->devtype = devtype;
 	dev_set_drvdata(dev, s);
 	mutex_init(&s->efr_lock);
@@ -1558,8 +1546,8 @@ static int sc16is7xx_probe(struct device
 	sched_set_fifo(s->kworker_task);
 
 	/* reset device, purging any pending irq / data */
-	regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT,
-			SC16IS7XX_IOCONTROL_SRESET_BIT);
+	regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG,
+		     SC16IS7XX_IOCONTROL_SRESET_BIT);
 
 	for (i = 0; i < devtype->nr_uart; ++i) {
 		s->p[i].line		= i;
@@ -1583,6 +1571,7 @@ static int sc16is7xx_probe(struct device
 		s->p[i].port.ops	= &sc16is7xx_ops;
 		s->p[i].old_mctrl	= 0;
 		s->p[i].port.line	= sc16is7xx_alloc_line();
+		s->p[i].regmap		= regmaps[i];
 
 		if (s->p[i].port.line >= SC16IS7XX_MAX_DEVS) {
 			ret = -ENOMEM;
@@ -1611,13 +1600,13 @@ static int sc16is7xx_probe(struct device
 		sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_LCR_REG,
 				     SC16IS7XX_LCR_CONF_MODE_B);
 
-		regcache_cache_bypass(s->regmap, true);
+		regcache_cache_bypass(regmaps[i], true);
 
 		/* Enable write access to enhanced features */
 		sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_EFR_REG,
 				     SC16IS7XX_EFR_ENABLE_BIT);
 
-		regcache_cache_bypass(s->regmap, false);
+		regcache_cache_bypass(regmaps[i], false);
 
 		/* Restore access to general registers */
 		sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_LCR_REG, 0x00);
@@ -1711,19 +1700,36 @@ static const struct of_device_id __maybe
 MODULE_DEVICE_TABLE(of, sc16is7xx_dt_ids);
 
 static struct regmap_config regcfg = {
-	.reg_bits = 7,
-	.pad_bits = 1,
+	.reg_bits = 5,
+	.pad_bits = 3,
 	.val_bits = 8,
 	.cache_type = REGCACHE_RBTREE,
 	.volatile_reg = sc16is7xx_regmap_volatile,
 	.precious_reg = sc16is7xx_regmap_precious,
+	.max_register = SC16IS7XX_EFCR_REG,
 };
 
+static const char *sc16is7xx_regmap_name(unsigned int port_id)
+{
+	static char buf[6];
+
+	snprintf(buf, sizeof(buf), "port%d", port_id);
+
+	return buf;
+}
+
+static unsigned int sc16is7xx_regmap_port_mask(unsigned int port_id)
+{
+	/* CH1,CH0 are at bits 2:1. */
+	return port_id << 1;
+}
+
 #ifdef CONFIG_SERIAL_SC16IS7XX_SPI
 static int sc16is7xx_spi_probe(struct spi_device *spi)
 {
 	const struct sc16is7xx_devtype *devtype;
-	struct regmap *regmap;
+	struct regmap *regmaps[2];
+	unsigned int i;
 	int ret;
 
 	/* Setup SPI bus */
@@ -1748,11 +1754,20 @@ static int sc16is7xx_spi_probe(struct sp
 		devtype = (struct sc16is7xx_devtype *)id_entry->driver_data;
 	}
 
-	regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) |
-			      (devtype->nr_uart - 1);
-	regmap = devm_regmap_init_spi(spi, &regcfg);
+	for (i = 0; i < devtype->nr_uart; i++) {
+		regcfg.name = sc16is7xx_regmap_name(i);
+		/*
+		 * If read_flag_mask is 0, the regmap code sets it to a default
+		 * of 0x80. Since we specify our own mask, we must add the READ
+		 * bit ourselves:
+		 */
+		regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i) |
+			SC16IS7XX_SPI_READ_BIT;
+		regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
+		regmaps[i] = devm_regmap_init_spi(spi, &regcfg);
+	}
 
-	return sc16is7xx_probe(&spi->dev, devtype, regmap, spi->irq);
+	return sc16is7xx_probe(&spi->dev, devtype, regmaps, spi->irq);
 }
 
 static void sc16is7xx_spi_remove(struct spi_device *spi)
@@ -1791,7 +1806,8 @@ static int sc16is7xx_i2c_probe(struct i2
 {
 	const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
 	const struct sc16is7xx_devtype *devtype;
-	struct regmap *regmap;
+	struct regmap *regmaps[2];
+	unsigned int i;
 
 	if (i2c->dev.of_node) {
 		devtype = device_get_match_data(&i2c->dev);
@@ -1801,11 +1817,14 @@ static int sc16is7xx_i2c_probe(struct i2
 		devtype = (struct sc16is7xx_devtype *)id->driver_data;
 	}
 
-	regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) |
-			      (devtype->nr_uart - 1);
-	regmap = devm_regmap_init_i2c(i2c, &regcfg);
+	for (i = 0; i < devtype->nr_uart; i++) {
+		regcfg.name = sc16is7xx_regmap_name(i);
+		regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i);
+		regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i);
+		regmaps[i] = devm_regmap_init_i2c(i2c, &regcfg);
+	}
 
-	return sc16is7xx_probe(&i2c->dev, devtype, regmap, i2c->irq);
+	return sc16is7xx_probe(&i2c->dev, devtype, regmaps, i2c->irq);
 }
 
 static void sc16is7xx_i2c_remove(struct i2c_client *client)
author maintainer
#133 lore raw

PATCH 128/346 serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name()

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugo Villeneuve <[email protected]>

commit 6bcab3c8acc88e265c570dea969fd04f137c8a4c upstream.

Using a static buffer inside sc16is7xx_regmap_name() was a convenient and simple way to set the regmap name without having to allocate and free a buffer each time it is called. The drawback is that the static buffer wastes memory for nothing once regmap is fully initialized.

Remove static buffer and use constant strings instead.

This also avoids a truncation warning when using "%d" or "%u" in snprintf which was flagged by kernel test robot.

Fixes 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
Cc <[email protected]> # 6.1.x: 3837a03 serial: sc16is7xx: improve regmap debugfs by using one regmap per port
---
 drivers/tty/serial/sc16is7xx.c |   14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)
drivers/tty/serial/sc16is7xx.c +8 -6
@@ -1709,13 +1709,15 @@ static struct regmap_config regcfg = {
 	.max_register = SC16IS7XX_EFCR_REG,
 };
 
-static const char *sc16is7xx_regmap_name(unsigned int port_id)
+static const char *sc16is7xx_regmap_name(u8 port_id)
 {
-	static char buf[6];
-
-	snprintf(buf, sizeof(buf), "port%d", port_id);
-
-	return buf;
+	switch (port_id) {
+	case 0:	return "port0";
+	case 1:	return "port1";
+	default:
+		WARN_ON(true);
+		return NULL;
+	}
 }
 
 static unsigned int sc16is7xx_regmap_port_mask(unsigned int port_id)
author maintainer
#134 lore raw

PATCH 129/346 serial: sc16is7xx: remove global regmap from struct sc16is7xx_port

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugo Villeneuve <[email protected]>

commit f6959c5217bd799bcb770b95d3c09b3244e175c6 upstream.

Remove global struct regmap so that it is more obvious that this regmap is to be used only in the probe function.

Also add a comment to that effect in probe function.

Fixes 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
---
 drivers/tty/serial/sc16is7xx.c |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/tty/serial/sc16is7xx.c +9 -6
@@ -335,7 +335,6 @@ struct sc16is7xx_one {
 
 struct sc16is7xx_port {
 	const struct sc16is7xx_devtype	*devtype;
-	struct regmap			*regmap;
 	struct clk			*clk;
 #ifdef CONFIG_GPIOLIB
 	struct gpio_chip		gpio;
@@ -1435,7 +1434,8 @@ static void sc16is7xx_setup_irda_ports(s
 /*
  * Configure ports designated to operate as modem control lines.
  */
-static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s)
+static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s,
+				       struct regmap *regmap)
 {
 	int i;
 	int ret;
@@ -1464,7 +1464,7 @@ static int sc16is7xx_setup_mctrl_ports(s
 
 	if (s->mctrl_mask)
 		regmap_update_bits(
-			s->regmap,
+			regmap,
 			SC16IS7XX_IOCONTROL_REG,
 			SC16IS7XX_IOCONTROL_MODEM_A_BIT |
 			SC16IS7XX_IOCONTROL_MODEM_B_BIT, s->mctrl_mask);
@@ -1496,6 +1496,10 @@ static int sc16is7xx_probe(struct device
 	 * This device does not have an identification register that would
 	 * tell us if we are really connected to the correct device.
 	 * The best we can do is to check if communication is at all possible.
+	 *
+	 * Note: regmap[0] is used in the probe function to access registers
+	 * common to all channels/ports, as it is guaranteed to be present on
+	 * all variants.
 	 */
 	ret = regmap_read(regmaps[0], SC16IS7XX_LSR_REG, &val);
 	if (ret < 0)
@@ -1531,7 +1535,6 @@ static int sc16is7xx_probe(struct device
 			return -EINVAL;
 	}
 
-	s->regmap = regmaps[0];
 	s->devtype = devtype;
 	dev_set_drvdata(dev, s);
 	mutex_init(&s->efr_lock);
@@ -1546,7 +1549,7 @@ static int sc16is7xx_probe(struct device
 	sched_set_fifo(s->kworker_task);
 
 	/* reset device, purging any pending irq / data */
-	regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG,
+	regmap_write(regmaps[0], SC16IS7XX_IOCONTROL_REG,
 		     SC16IS7XX_IOCONTROL_SRESET_BIT);
 
 	for (i = 0; i < devtype->nr_uart; ++i) {
@@ -1617,7 +1620,7 @@ static int sc16is7xx_probe(struct device
 
 	sc16is7xx_setup_irda_ports(s);
 
-	ret = sc16is7xx_setup_mctrl_ports(s);
+	ret = sc16is7xx_setup_mctrl_ports(s, regmaps[0]);
 	if (ret)
 		goto out_ports;
 
author maintainer
#135 lore raw

PATCH 130/346 serial: sc16is7xx: remove unused line structure member

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugo Villeneuve <[email protected]>

commit 41a308cbedb2a68a6831f0f2e992e296c4b8aff0 upstream.

Now that the driver has been converted to use one regmap per port, the line structure member is no longer used, so remove it.

Fixes 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
---
 drivers/tty/serial/sc16is7xx.c |    2 --
 1 file changed, 2 deletions(-)
drivers/tty/serial/sc16is7xx.c +0 -2
@@ -323,7 +323,6 @@ struct sc16is7xx_one_config {
 
 struct sc16is7xx_one {
 	struct uart_port		port;
-	u8				line;
 	struct regmap			*regmap;
 	struct kthread_work		tx_work;
 	struct kthread_work		reg_work;
@@ -1553,7 +1552,6 @@ static int sc16is7xx_probe(struct device
 		     SC16IS7XX_IOCONTROL_SRESET_BIT);
 
 	for (i = 0; i < devtype->nr_uart; ++i) {
-		s->p[i].line		= i;
 		/* Initialize port data */
 		s->p[i].port.dev	= dev;
 		s->p[i].port.irq	= irq;
author maintainer
#136 lore raw

PATCH 131/346 serial: sc16is7xx: change EFR lock to operate on each channels

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugo Villeneuve <[email protected]>

commit 4409df5866b7ff7686ba27e449ca97a92ee063c9 upstream.

Now that the driver has been converted to use one regmap per port, change efr locking to operate on a channel basis instead of on the whole IC.

Fixes 3837a0379533 ("serial: sc16is7xx: improve regmap debugfs by using one regmap per port")
Cc <[email protected]> # 6.1.x: 3837a03 serial: sc16is7xx: improve regmap debugfs by using one regmap per port
---
 drivers/tty/serial/sc16is7xx.c |   49 +++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 23 deletions(-)
drivers/tty/serial/sc16is7xx.c +26 -23
@@ -324,6 +324,7 @@ struct sc16is7xx_one_config {
 struct sc16is7xx_one {
 	struct uart_port		port;
 	struct regmap			*regmap;
+	struct mutex			efr_lock; /* EFR registers access */
 	struct kthread_work		tx_work;
 	struct kthread_work		reg_work;
 	struct kthread_delayed_work	ms_work;
@@ -343,7 +344,6 @@ struct sc16is7xx_port {
 	unsigned char			buf[SC16IS7XX_FIFO_SIZE];
 	struct kthread_worker		kworker;
 	struct task_struct		*kworker_task;
-	struct mutex			efr_lock;
 	struct sc16is7xx_one		p[];
 };
 
@@ -495,7 +495,6 @@ static bool sc16is7xx_regmap_precious(st
 
 static int sc16is7xx_set_baud(struct uart_port *port, int baud)
 {
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 	u8 lcr;
 	u8 prescaler = 0;
@@ -519,7 +518,7 @@ static int sc16is7xx_set_baud(struct uar
 	 * because the bulk of the interrupt processing is run as a workqueue
 	 * job in thread context.
 	 */
-	mutex_lock(&s->efr_lock);
+	mutex_lock(&one->efr_lock);
 
 	lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG);
 
@@ -538,7 +537,7 @@ static int sc16is7xx_set_baud(struct uar
 	/* Put LCR back to the normal mode */
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
 
-	mutex_unlock(&s->efr_lock);
+	mutex_unlock(&one->efr_lock);
 
 	sc16is7xx_port_update(port, SC16IS7XX_MCR_REG,
 			      SC16IS7XX_MCR_CLKSEL_BIT,
@@ -706,11 +705,10 @@ static unsigned int sc16is7xx_get_hwmctr
 static void sc16is7xx_update_mlines(struct sc16is7xx_one *one)
 {
 	struct uart_port *port = &one->port;
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
 	unsigned long flags;
 	unsigned int status, changed;
 
-	lockdep_assert_held_once(&s->efr_lock);
+	lockdep_assert_held_once(&one->efr_lock);
 
 	status = sc16is7xx_get_hwmctrl(port);
 	changed = status ^ one->old_mctrl;
@@ -736,15 +734,20 @@ static void sc16is7xx_update_mlines(stru
 
 static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno)
 {
+	bool rc = true;
 	struct uart_port *port = &s->p[portno].port;
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
+
+	mutex_lock(&one->efr_lock);
 
 	do {
 		unsigned int iir, rxlen;
-		struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 
 		iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG);
-		if (iir & SC16IS7XX_IIR_NO_INT_BIT)
-			return false;
+		if (iir & SC16IS7XX_IIR_NO_INT_BIT) {
+			rc = false;
+			goto out_port_irq;
+		}
 
 		iir &= SC16IS7XX_IIR_ID_MASK;
 
@@ -784,15 +787,17 @@ static bool sc16is7xx_port_irq(struct sc
 			break;
 		}
 	} while (0);
-	return true;
+
+out_port_irq:
+	mutex_unlock(&one->efr_lock);
+
+	return rc;
 }
 
 static irqreturn_t sc16is7xx_irq(int irq, void *dev_id)
 {
 	struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id;
 
-	mutex_lock(&s->efr_lock);
-
 	while (1) {
 		bool keep_polling = false;
 		int i;
@@ -803,24 +808,22 @@ static irqreturn_t sc16is7xx_irq(int irq
 			break;
 	}
 
-	mutex_unlock(&s->efr_lock);
-
 	return IRQ_HANDLED;
 }
 
 static void sc16is7xx_tx_proc(struct kthread_work *ws)
 {
 	struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port);
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
+	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 	unsigned long flags;
 
 	if ((port->rs485.flags & SER_RS485_ENABLED) &&
 	    (port->rs485.delay_rts_before_send > 0))
 		msleep(port->rs485.delay_rts_before_send);
 
-	mutex_lock(&s->efr_lock);
+	mutex_lock(&one->efr_lock);
 	sc16is7xx_handle_tx(port);
-	mutex_unlock(&s->efr_lock);
+	mutex_unlock(&one->efr_lock);
 
 	uart_port_lock_irqsave(port, &flags);
 	sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT);
@@ -927,9 +930,9 @@ static void sc16is7xx_ms_proc(struct kth
 	struct sc16is7xx_port *s = dev_get_drvdata(one->port.dev);
 
 	if (one->port.state) {
-		mutex_lock(&s->efr_lock);
+		mutex_lock(&one->efr_lock);
 		sc16is7xx_update_mlines(one);
-		mutex_unlock(&s->efr_lock);
+		mutex_unlock(&one->efr_lock);
 
 		kthread_queue_delayed_work(&s->kworker, &one->ms_work, HZ);
 	}
@@ -1013,7 +1016,6 @@ static void sc16is7xx_set_termios(struct
 				  struct ktermios *termios,
 				  const struct ktermios *old)
 {
-	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 	unsigned int lcr, flow = 0;
 	int baud;
@@ -1072,7 +1074,7 @@ static void sc16is7xx_set_termios(struct
 		port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK;
 
 	/* As above, claim the mutex while accessing the EFR. */
-	mutex_lock(&s->efr_lock);
+	mutex_lock(&one->efr_lock);
 
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG,
 			     SC16IS7XX_LCR_CONF_MODE_B);
@@ -1102,7 +1104,7 @@ static void sc16is7xx_set_termios(struct
 	/* Update LCR register */
 	sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr);
 
-	mutex_unlock(&s->efr_lock);
+	mutex_unlock(&one->efr_lock);
 
 	/* Get baud rate generator configuration */
 	baud = uart_get_baud_rate(port, termios, old,
@@ -1536,7 +1538,6 @@ static int sc16is7xx_probe(struct device
 
 	s->devtype = devtype;
 	dev_set_drvdata(dev, s);
-	mutex_init(&s->efr_lock);
 
 	kthread_init_worker(&s->kworker);
 	s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker,
@@ -1579,6 +1580,8 @@ static int sc16is7xx_probe(struct device
 			goto out_ports;
 		}
 
+		mutex_init(&s->p[i].efr_lock);
+
 		ret = uart_get_rs485_mode(&s->p[i].port);
 		if (ret)
 			goto out_ports;
author maintainer
#114 lore raw

PATCH 114/346 nouveau/vmm: dont set addr on the fail path to avoid warning

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Dave Airlie <[email protected]>

commit cacea81390fd8c8c85404e5eb2adeb83d87a912e upstream.

nvif_vmm_put gets called if addr is set, but if the allocation fails we don't need to call put, otherwise we get a warning like

[523232.435671] ------------[ cut here ]------------
[523232.435674] WARNING: CPU: 8 PID: 1505697 at drivers/gpu/drm/nouveau/nvif/vmm.c:68 nvif_vmm_put+0x72/0x80 [nouveau]
[523232.435795] Modules linked in: uinput rfcomm snd_seq_dummy snd_hrtimer nf_conntrack_netbios_ns nf_conntrack_broadcast nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_ct nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 ip_set nf_tables nfnetlink qrtr bnep sunrpc binfmt_misc intel_rapl_msr intel_rapl_common intel_uncore_frequency intel_uncore_frequency_common isst_if_common iwlmvm nfit libnvdimm vfat fat x86_pkg_temp_thermal intel_powerclamp mac80211 snd_soc_avs snd_soc_hda_codec coretemp snd_hda_ext_core snd_soc_core snd_hda_codec_realtek kvm_intel snd_hda_codec_hdmi snd_compress snd_hda_codec_generic ac97_bus snd_pcm_dmaengine snd_hda_intel libarc4 snd_intel_dspcfg snd_intel_sdw_acpi snd_hda_codec kvm iwlwifi snd_hda_core btusb snd_hwdep btrtl snd_seq btintel irqbypass btbcm rapl snd_seq_device eeepc_wmi btmtk intel_cstate iTCO_wdt cfg80211 snd_pcm asus_wmi bluetooth intel_pmc_bxt iTCO_vendor_support snd_timer ledtrig_audio pktcdvd snd mei_me
[523232.435828]  sparse_keymap intel_uncore i2c_i801 platform_profile wmi_bmof mei pcspkr ioatdma soundcore i2c_smbus rfkill idma64 dca joydev acpi_tad loop zram nouveau drm_ttm_helper ttm video drm_exec drm_gpuvm gpu_sched crct10dif_pclmul i2c_algo_bit nvme crc32_pclmul crc32c_intel drm_display_helper polyval_clmulni nvme_core polyval_generic e1000e mxm_wmi cec ghash_clmulni_intel r8169 sha512_ssse3 nvme_common wmi pinctrl_sunrisepoint uas usb_storage ip6_tables ip_tables fuse
[523232.435849] CPU: 8 PID: 1505697 Comm: gnome-shell Tainted: G        W          6.6.0-rc7-nvk-uapi+ #12
[523232.435851] Hardware name: System manufacturer System Product Name/ROG STRIX X299-E GAMING II, BIOS 1301 09/24/2021
[523232.435852] RIP: 0010:nvif_vmm_put+0x72/0x80 [nouveau]
[523232.435934] Code: 00 00 48 89 e2 be 02 00 00 00 48 c7 04 24 00 00 00 00 48 89 44 24 08 e8 fc bf ff ff 85
c0 75 0a 48 c7 43 08 00 00 00 00 eb b3 <0f> 0b eb f2 e8 f5 c9 b2 e6 0f 1f 44 00 00 90 90 90 90 90 90 90 90
[523232.435936] RSP: 0018:ffffc900077ffbd8 EFLAGS: 00010282
[523232.435937] RAX: 00000000fffffffe RBX: ffffc900077ffc00 RCX: 0000000000000010
[523232.435938] RDX: 0000000000000010 RSI: ffffc900077ffb38 RDI: ffffc900077ffbd8
[523232.435940] RBP: ffff888e1c4f2140 R08: 0000000000000000 R09: 0000000000000000
[523232.435940] R10: 0000000000000000 R11: 0000000000000000 R12: ffff888503811800
[523232.435941] R13: ffffc900077ffca0 R14: ffff888e1c4f2140 R15: ffff88810317e1e0
[523232.435942] FS:  00007f933a769640(0000) GS:ffff88905fa00000(0000) knlGS:0000000000000000
[523232.435943] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[523232.435944] CR2: 00007f930bef7000 CR3: 00000005d0322001 CR4: 00000000003706e0
[523232.435945] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[523232.435946] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[523232.435964] Call Trace:
[523232.435965]  <TASK>
[523232.435966]  ? nvif_vmm_put+0x72/0x80 [nouveau]
[523232.436051]  ? __warn+0x81/0x130
[523232.436055]  ? nvif_vmm_put+0x72/0x80 [nouveau]
[523232.436138]  ? report_bug+0x171/0x1a0
[523232.436142]  ? handle_bug+0x3c/0x80
[523232.436144]  ? exc_invalid_op+0x17/0x70
[523232.436145]  ? asm_exc_invalid_op+0x1a/0x20
[523232.436149]  ? nvif_vmm_put+0x72/0x80 [nouveau]
[523232.436230]  ? nvif_vmm_put+0x64/0x80 [nouveau]
[523232.436342]  nouveau_vma_del+0x80/0xd0 [nouveau]
[523232.436506]  nouveau_vma_new+0x1a0/0x210 [nouveau]
[523232.436671]  nouveau_gem_object_open+0x1d0/0x1f0 [nouveau]
[523232.436835]  drm_gem_handle_create_tail+0xd1/0x180
[523232.436840]  drm_prime_fd_to_handle_ioctl+0x12e/0x200
[523232.436844]  ? __pfx_drm_prime_fd_to_handle_ioctl+0x10/0x10
[523232.436847]  drm_ioctl_kernel+0xd3/0x180
[523232.436849]  drm_ioctl+0x26d/0x4b0
[523232.436851]  ? __pfx_drm_prime_fd_to_handle_ioctl+0x10/0x10
[523232.436855]  nouveau_drm_ioctl+0x5a/0xb0 [nouveau]
[523232.437032]  __x64_sys_ioctl+0x94/0xd0
[523232.437036]  do_syscall_64+0x5d/0x90
[523232.437040]  ? syscall_exit_to_user_mode+0x2b/0x40
[523232.437044]  ? do_syscall_64+0x6c/0x90
[523232.437046]  entry_SYSCALL_64_after_hwframe+0x6e/0xd8
---
 drivers/gpu/drm/nouveau/nouveau_vmm.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/gpu/drm/nouveau/nouveau_vmm.c +3 -0
@@ -108,6 +108,9 @@ nouveau_vma_new(struct nouveau_bo *nvbo,
 	} else {
 		ret = nvif_vmm_get(&vmm->vmm, PTES, false, mem->mem.page, 0,
 				   mem->mem.size, &tmp);
+		if (ret)
+			goto done;
+
 		vma->addr = tmp.addr;
 	}
 
author maintainer
#137 lore raw

PATCH 132/346 serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugo Villeneuve <[email protected]>

commit dbf4ab821804df071c8b566d9813083125e6d97b upstream.

The SC16IS7XX IC supports a burst mode to access the FIFOs where the initial register address is sent ($00), followed by all the FIFO data without having to resend the register address each time. In this mode, the IC doesn't increment the register address for each R/W byte.

The regmap_raw_read() and regmap_raw_write() are functions which can perform IO over multiple registers. They are currently used to read/write from/to the FIFO, and although they operate correctly in this burst mode on the SPI bus, they would corrupt the regmap cache if it was not disabled manually. The reason is that when the R/W size is more than 1 byte, these functions assume that the register address is incremented and handle the cache accordingly.

Convert FIFO R/W functions to use the regmap _noinc_ versions in order to remove the manual cache control which was a workaround when using the _raw_ versions. FIFO registers are properly declared as volatile so cache will not be used/updated for FIFO accesses.

---
 drivers/tty/serial/sc16is7xx.c |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/tty/serial/sc16is7xx.c +11 -6
@@ -382,9 +382,7 @@ static void sc16is7xx_fifo_read(struct u
 	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
 
-	regcache_cache_bypass(one->regmap, true);
-	regmap_raw_read(one->regmap, SC16IS7XX_RHR_REG, s->buf, rxlen);
-	regcache_cache_bypass(one->regmap, false);
+	regmap_noinc_read(one->regmap, SC16IS7XX_RHR_REG, s->buf, rxlen);
 }
 
 static void sc16is7xx_fifo_write(struct uart_port *port, u8 to_send)
@@ -399,9 +397,7 @@ static void sc16is7xx_fifo_write(struct
 	if (unlikely(!to_send))
 		return;
 
-	regcache_cache_bypass(one->regmap, true);
-	regmap_raw_write(one->regmap, SC16IS7XX_THR_REG, s->buf, to_send);
-	regcache_cache_bypass(one->regmap, false);
+	regmap_noinc_write(one->regmap, SC16IS7XX_THR_REG, s->buf, to_send);
 }
 
 static void sc16is7xx_port_update(struct uart_port *port, u8 reg,
@@ -493,6 +489,11 @@ static bool sc16is7xx_regmap_precious(st
 	return false;
 }
 
+static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg)
+{
+	return reg == SC16IS7XX_RHR_REG;
+}
+
 static int sc16is7xx_set_baud(struct uart_port *port, int baud)
 {
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
@@ -1710,6 +1711,10 @@ static struct regmap_config regcfg = {
 	.cache_type = REGCACHE_RBTREE,
 	.volatile_reg = sc16is7xx_regmap_volatile,
 	.precious_reg = sc16is7xx_regmap_precious,
+	.writeable_noinc_reg = sc16is7xx_regmap_noinc,
+	.readable_noinc_reg = sc16is7xx_regmap_noinc,
+	.max_raw_read = SC16IS7XX_FIFO_SIZE,
+	.max_raw_write = SC16IS7XX_FIFO_SIZE,
 	.max_register = SC16IS7XX_EFCR_REG,
 };
 
author maintainer
#138 lore raw

PATCH 133/346 serial: sc16is7xx: fix unconditional activation of THRI interrupt

In reply to Greg Kroah-Hartman

6.7-stable review patch. If anyone has any objections, please let me know.

------------------

From: Hugo Villeneuve <[email protected]>

commit 9915753037eba7135b209fef4f2afeca841af816 upstream.

Commit cc4c1d05eb10 ("sc16is7xx: Properly resume TX after stop") changed behavior to unconditionnaly set the THRI interrupt in sc16is7xx_tx_proc().

For example when sending a 65 bytes message, and assuming the Tx FIFO is initially empty, sc16is7xx_handle_tx() will write the first 64 bytes of the message to the FIFO and sc16is7xx_tx_proc() will then activate THRI. When the THRI IRQ is fired, the driver will write the remaining byte of the message to the FIFO, and disable THRI by calling sc16is7xx_stop_tx().

When sending a 2 bytes message, sc16is7xx_handle_tx() will write the 2 bytes of the message to the FIFO and call sc16is7xx_stop_tx(), disabling THRI. After sc16is7xx_handle_tx() exits, control returns to sc16is7xx_tx_proc() which will unconditionally set THRI. When the THRI IRQ is fired, the driver simply acknowledges the interrupt and does nothing more, since all the data has already been written to the FIFO. This results in 2 register writes and 4 register reads all for nothing and taking precious cycles from the I2C/SPI bus.

Fix this by enabling the THRI interrupt only when we fill the Tx FIFO to its maximum capacity and there are remaining bytes to send in the message.

---
 drivers/tty/serial/sc16is7xx.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
drivers/tty/serial/sc16is7xx.c +2 -5
@@ -688,6 +688,8 @@ static void sc16is7xx_handle_tx(struct u
 
 	if (uart_circ_empty(xmit))
 		sc16is7xx_stop_tx(port);
+	else
+		sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT);
 	uart_port_unlock_irqrestore(port, flags);
 }
 
@@ -816,7 +818,6 @@ static void sc16is7xx_tx_proc(struct kth
 {
 	struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port);
 	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
-	unsigned long flags;
 
 	if ((port->rs485.flags & SER_RS485_ENABLED) &&
 	    (port->rs485.delay_rts_before_send > 0))
@@ -825,10 +826,6 @@ static void sc16is7xx_tx_proc(struct kth
 	mutex_lock(&one->efr_lock);
 	sc16is7xx_handle_tx(port);
 	mutex_unlock(&one->efr_lock);
-
-	uart_port_lock_irqsave(port, &flags);
-	sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT);
-	uart_port_unlock_irqrestore(port, flags);
 }
 
 static void sc16is7xx_reconf_rs485(struct uart_port *port)