Skip to contentSkip to conversation

5.15.54-rc1 review

PATCH In review Greg Kroah-Hartman 8 participants 244 messages Jul 11, 2022 – Jan 15, 2023 Page 2 of 2

Subsystems (2)
lore
Share & tools
lore
author maintainer
#117 lore raw

PATCH 114/230 ASoC: rt5682: move clk related code to rt5682_i2c_probe

In reply to Greg Kroah-Hartman

From: Jack Yu <[email protected]>

[ Upstream commit 57589f82762e40bdaa975d840fa2bc5157b5be95 ]

The DAI clock is only used in I2S mode, to make it clear and to fix clock resource release issue, we move CCF clock related code to rt5682_i2c_probe to fix clock register/unregister issue.

---
 sound/soc/codecs/rt5682-i2c.c | 22 +++++++++++
 sound/soc/codecs/rt5682.c     | 70 +++++++++++++----------------------
 sound/soc/codecs/rt5682.h     |  3 ++
 3 files changed, 51 insertions(+), 44 deletions(-)
sound/soc/codecs/rt5682-i2c.c +22 -0
index 74a1fee071dd..3d2d7c9ce66d 100644
@@ -133,6 +133,8 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
 
 	i2c_set_clientdata(i2c, rt5682);
 
+	rt5682->i2c_dev = &i2c->dev;
+
 	rt5682->pdata = i2s_default_platform_data;
 
 	if (pdata)
@@ -270,6 +272,26 @@ static int rt5682_i2c_probe(struct i2c_client *i2c,
 			dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
 	}
 
+#ifdef CONFIG_COMMON_CLK
+	/* Check if MCLK provided */
+	rt5682->mclk = devm_clk_get(&i2c->dev, "mclk");
+	if (IS_ERR(rt5682->mclk)) {
+		if (PTR_ERR(rt5682->mclk) != -ENOENT) {
+			ret = PTR_ERR(rt5682->mclk);
+			return ret;
+		}
+		rt5682->mclk = NULL;
+	}
+
+	/* Register CCF DAI clock control */
+	ret = rt5682_register_dai_clks(rt5682);
+	if (ret)
+		return ret;
+
+	/* Initial setup for CCF */
+	rt5682->lrck[RT5682_AIF1] = 48000;
+#endif
+
 	return devm_snd_soc_register_component(&i2c->dev,
 					       &rt5682_soc_component_dev,
 					       rt5682_dai, ARRAY_SIZE(rt5682_dai));
sound/soc/codecs/rt5682.c +26 -44

193 lines not on this page · raw message

sound/soc/codecs/rt5682.h +3 -0
index 539a9fe26294..52ff0d9c36c5 100644
@@ -1428,6 +1428,7 @@ enum {
 
 struct rt5682_priv {
 	struct snd_soc_component *component;
+	struct device *i2c_dev;
 	struct rt5682_platform_data pdata;
 	struct regmap *regmap;
 	struct regmap *sdw_regmap;
@@ -1481,6 +1482,8 @@ void rt5682_calibrate(struct rt5682_priv *rt5682);
 void rt5682_reset(struct rt5682_priv *rt5682);
 int rt5682_parse_dt(struct rt5682_priv *rt5682, struct device *dev);
 
+int rt5682_register_dai_clks(struct rt5682_priv *rt5682);
+
 #define RT5682_REG_NUM 318
 extern const struct reg_default rt5682_reg[RT5682_REG_NUM];
 
Signature · 1 line
2.35.1
author maintainer
#118 lore raw

PATCH 115/230 ASoC: rt5682: fix an incorrect NULL check on list iterator

In reply to Greg Kroah-Hartman

From: Xiaomeng Tong <[email protected]>

[ Upstream commit c8618d65007ba68d7891130642d73e89372101e8 ]

The bug is here:

	if (!dai) {

The list iterator value 'dai' will *always* be set and non-NULL by for_each_component_dais(), so it is incorrect to assume that the iterator value will be NULL if the list is empty or no element is found (In fact, it will be a bogus pointer to an invalid struct object containing the HEAD). Otherwise it will bypass the check 'if (!dai) {' (never call dev_err() and never return -ENODEV;) and lead to invalid memory access lately when calling 'rt5682_set_bclk1_ratio(dai, factor);'.

To fix the bug, just return rt5682_set_bclk1_ratio(dai, factor); when found the 'dai', otherwise dev_err() and return -ENODEV;

Fixes ebbfabc16d23d ("ASoC: rt5682: Add CCF usage for providing I2S clks")
---
 sound/soc/codecs/rt5682.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)
sound/soc/codecs/rt5682.c +4 -7
index 80d199843b8c..8a9e1a4fa03e 100644
@@ -2822,14 +2822,11 @@ static int rt5682_bclk_set_rate(struct clk_hw *hw, unsigned long rate,
 
 	for_each_component_dais(component, dai)
 		if (dai->id == RT5682_AIF1)
-			break;
-	if (!dai) {
-		dev_err(rt5682->i2c_dev, "dai %d not found in component\n",
-			RT5682_AIF1);
-		return -ENODEV;
-	}
+			return rt5682_set_bclk1_ratio(dai, factor);
 
-	return rt5682_set_bclk1_ratio(dai, factor);
+	dev_err(rt5682->i2c_dev, "dai %d not found in component\n",
+		RT5682_AIF1);
+	return -ENODEV;
 }
 
 static const struct clk_ops rt5682_dai_clk_ops[RT5682_DAI_NUM_CLKS] = {
Signature · 1 line
2.35.1
author maintainer
#119 lore raw

PATCH 116/230 drm/amd/vcn: fix an error msg on vcn 3.0

In reply to Greg Kroah-Hartman

From: tiancyin <[email protected]>

[ Upstream commit 425d7a87e54ee358f580eaf10cf28dc95f7121c1 ]

Some video card has more than one vcn instance, passing 0 to vcn_v3_0_pause_dpg_mode is incorrect.

Error msg:
Register(1) [mmUVD_POWER_STATUS] failed to reach value 0x00000001 != 0x00000002

---
 drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +1 -1
index 6e56bef4fdf8..1310617f030f 100644
@@ -1511,7 +1511,7 @@ static int vcn_v3_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
 	struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE};
 	uint32_t tmp;
 
-	vcn_v3_0_pause_dpg_mode(adev, 0, &state);
+	vcn_v3_0_pause_dpg_mode(adev, inst_idx, &state);
 
 	/* Wait for power status to be 1 */
 	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
Signature · 1 line
2.35.1
author maintainer
#120 lore raw

PATCH 117/230 KVM: Dont create VM debugfs files outside of the VM directory

In reply to Greg Kroah-Hartman

From: Oliver Upton <[email protected]>

[ Upstream commit a44a4cc1c969afec97dbb2aedaf6f38eaa6253bb ]

Unfortunately, there is no guarantee that KVM was able to instantiate a debugfs directory for a particular VM. To that end, KVM shouldn't even attempt to create new debugfs files in this case. If the specified parent dentry is NULL, debugfs_create_file() will instantiate files at the root of debugfs.

For arm64, it is possible to create the vgic-state file outside of a VM directory, the file is not cleaned up when a VM is destroyed. Nonetheless, the corresponding struct kvm is freed when the VM is destroyed.

Nip the problem in the bud for all possible errant debugfs file creations by initializing kvm->debugfs_dentry to -ENOENT. In so doing, debugfs_create_file() will fail instead of creating the file in the root directory.

Fixes 929f45e32499 ("kvm: no need to check return value of debugfs_create functions")
---
 virt/kvm/kvm_main.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
virt/kvm/kvm_main.c +8 -2
index 99c591569815..9134ae252d7c 100644
@@ -911,7 +911,7 @@ static void kvm_destroy_vm_debugfs(struct kvm *kvm)
 	int kvm_debugfs_num_entries = kvm_vm_stats_header.num_desc +
 				      kvm_vcpu_stats_header.num_desc;
 
-	if (!kvm->debugfs_dentry)
+	if (IS_ERR(kvm->debugfs_dentry))
 		return;
 
 	debugfs_remove_recursive(kvm->debugfs_dentry);
@@ -934,6 +934,12 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
 	int kvm_debugfs_num_entries = kvm_vm_stats_header.num_desc +
 				      kvm_vcpu_stats_header.num_desc;
 
+	/*
+	 * Force subsequent debugfs file creations to fail if the VM directory
+	 * is not created.
+	 */
+	kvm->debugfs_dentry = ERR_PTR(-ENOENT);
+
 	if (!debugfs_initialized())
 		return 0;
 
@@ -5373,7 +5379,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm)
 	}
 	add_uevent_var(env, "PID=%d", kvm->userspace_pid);
 
-	if (kvm->debugfs_dentry) {
+	if (!IS_ERR(kvm->debugfs_dentry)) {
 		char *tmp, *p = kmalloc(PATH_MAX, GFP_KERNEL_ACCOUNT);
 
 		if (p) {
Signature · 1 line
2.35.1
author maintainer
#121 lore raw

PATCH 118/230 tty: n_gsm: Modify CR,PF bit when config requester

In reply to Greg Kroah-Hartman

From: Zhenguo Zhao <[email protected]>

[ Upstream commit cc0f42122a7e7a5ede9c5f2a41199128b8449eda ]

When n_gsm config "initiator=0",as requester,gsmld receives dlci SABM/DISC control command frame,but send UA frame is error.

Example:
Gsmld receive dlc0 SABM frame "f9 03 3f 01 1c f9",now it sends UA frame "f9 01 63 01 a3 f9",CR and PF bit are 0,but it should be set 1 from requster to initiator.

Kernel test log as follows:

Before modify

[  271.732031] c1 gsmld_receive: 00000000: f9 03 3f 01 1c f9
[  271.741719] c1 <-- 0) C: SABM(P)
[  271.749483] c1 gsmld_output: 00000000: f9 01 63 01 a3 f9
[  271.758337] c1 --> 0) R: UA(F)

After modify

[  261.233188] c0 gsmld_receive: 00000000: f9 03 3f 01 1c f9
[  261.242767] c0 <-- 0) C: SABM(P)
[  261.250497] c0 gsmld_output: 00000000: f9 03 73 01 d7 f9
[  261.259759] c0 --> 0) C: UA(P)
---
 drivers/tty/n_gsm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/tty/n_gsm.c +5 -5
index 6734ef22c304..91ce8e6e889a 100644
@@ -625,7 +625,7 @@ static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
 
 static inline void gsm_response(struct gsm_mux *gsm, int addr, int control)
 {
-	gsm_send(gsm, addr, 0, control);
+	gsm_send(gsm, addr, 1, control);
 }
 
 /**
@@ -1818,9 +1818,9 @@ static void gsm_queue(struct gsm_mux *gsm)
 		if (dlci == NULL)
 			return;
 		if (dlci->dead)
-			gsm_response(gsm, address, DM);
+			gsm_response(gsm, address, DM|PF);
 		else {
-			gsm_response(gsm, address, UA);
+			gsm_response(gsm, address, UA|PF);
 			gsm_dlci_open(dlci);
 		}
 		break;
@@ -1828,11 +1828,11 @@ static void gsm_queue(struct gsm_mux *gsm)
 		if (cr == 0)
 			goto invalid;
 		if (dlci == NULL || dlci->state == DLCI_CLOSED) {
-			gsm_response(gsm, address, DM);
+			gsm_response(gsm, address, DM|PF);
 			return;
 		}
 		/* Real close complete */
-		gsm_response(gsm, address, UA);
+		gsm_response(gsm, address, UA|PF);
 		gsm_dlci_close(dlci);
 		break;
 	case UA|PF:
Signature · 1 line
2.35.1
author maintainer
#122 lore raw

PATCH 119/230 tty: n_gsm: Save dlci address open status when config requester

In reply to Greg Kroah-Hartman

From: Zhenguo Zhao <[email protected]>

[ Upstream commit 0b91b5332368f2fb0c3e5cfebc6aff9e167acd8b ]

When n_gsm config "initiator=0",as requester ,receive SABM frame,n_gsm register gsmtty dev,and save dlci open address status,if receive DLC0 DISC or CLD frame,it can unregister the gsmtty dev by saving dlci address.

---
 drivers/tty/n_gsm.c | 57 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 53 insertions(+), 4 deletions(-)
drivers/tty/n_gsm.c +53 -4
index 91ce8e6e889a..3038e5631be5 100644
@@ -274,6 +274,10 @@ static DEFINE_SPINLOCK(gsm_mux_lock);
 
 static struct tty_driver *gsm_tty_driver;
 
+/* Save dlci open address */
+static int addr_open[256] = { 0 };
+/* Save dlci open count */
+static int addr_cnt;
 /*
  *	This section of the driver logic implements the GSM encodings
  *	both the basic and the 'advanced'. Reliable transport is not
@@ -1191,6 +1195,7 @@ static void gsm_control_rls(struct gsm_mux *gsm, const u8 *data, int clen)
 }
 
 static void gsm_dlci_begin_close(struct gsm_dlci *dlci);
+static void gsm_dlci_close(struct gsm_dlci *dlci);
 
 /**
  *	gsm_control_message	-	DLCI 0 control processing
@@ -1209,15 +1214,28 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
 {
 	u8 buf[1];
 	unsigned long flags;
+	struct gsm_dlci *dlci;
+	int i;
+	int address;
 
 	switch (command) {
 	case CMD_CLD: {
-		struct gsm_dlci *dlci = gsm->dlci[0];
+		if (addr_cnt > 0) {
+			for (i = 0; i < addr_cnt; i++) {
+				address = addr_open[i];
+				dlci = gsm->dlci[address];
+				gsm_dlci_close(dlci);
+				addr_open[i] = 0;
+			}
+		}
 		/* Modem wishes to close down */
+		dlci = gsm->dlci[0];
 		if (dlci) {
 			dlci->dead = true;
 			gsm->dead = true;
-			gsm_dlci_begin_close(dlci);
+			gsm_dlci_close(dlci);
+			addr_cnt = 0;
+			gsm_response(gsm, 0, UA|PF);
 		}
 		}
 		break;
@@ -1780,6 +1798,7 @@ static void gsm_queue(struct gsm_mux *gsm)
 	struct gsm_dlci *dlci;
 	u8 cr;
 	int address;
+	int i, j, k, address_tmp;
 	/* We have to sneak a look at the packet body to do the FCS.
 	   A somewhat layering violation in the spec */
 
@@ -1822,6 +1841,11 @@ static void gsm_queue(struct gsm_mux *gsm)
 		else {
 			gsm_response(gsm, address, UA|PF);
 			gsm_dlci_open(dlci);
+			/* Save dlci open address */
+			if (address) {
+				addr_open[addr_cnt] = address;
+				addr_cnt++;
+			}
 		}
 		break;
 	case DISC|PF:
@@ -1832,8 +1856,33 @@ static void gsm_queue(struct gsm_mux *gsm)
 			return;
 		}
 		/* Real close complete */
-		gsm_response(gsm, address, UA|PF);
-		gsm_dlci_close(dlci);
+		if (!address) {
+			if (addr_cnt > 0) {
+				for (i = 0; i < addr_cnt; i++) {
+					address = addr_open[i];
+					dlci = gsm->dlci[address];
+					gsm_dlci_close(dlci);
+					addr_open[i] = 0;
+				}
+			}
+			dlci = gsm->dlci[0];
+			gsm_dlci_close(dlci);
+			addr_cnt = 0;
+			gsm_response(gsm, 0, UA|PF);
+		} else {
+			gsm_response(gsm, address, UA|PF);
+			gsm_dlci_close(dlci);
+			/* clear dlci address */
+			for (j = 0; j < addr_cnt; j++) {
+				address_tmp = addr_open[j];
+				if (address_tmp == address) {
+					for (k = j; k < addr_cnt; k++)
+						addr_open[k] = addr_open[k+1];
+				addr_cnt--;
+				break;
+				}
+			}
+		}
 		break;
 	case UA|PF:
 		if (cr == 0 || dlci == NULL)
Signature · 1 line
2.35.1
author maintainer
#123 lore raw

PATCH 120/230 tty: n_gsm: fix frame reception handling

In reply to Greg Kroah-Hartman

From: Daniel Starke <[email protected]>

[ Upstream commit 7a0e4b1733b635026a87c023f6d703faf0095e39 ]

The frame checksum (FCS) is currently handled in gsm_queue() after reception of a frame. However, this breaks layering. A workaround with 'received_fcs' was implemented so far.
Furthermore, frames are handled as such even if no end flag was received. Move FCS calculation from gsm_queue() to gsm0_receive() and gsm1_receive(). Also delay gsm_queue() call there until a full frame was received to fix both points.

---
 drivers/tty/n_gsm.c | 53 +++++++++++++++++++++++++--------------------
 1 file changed, 30 insertions(+), 23 deletions(-)
drivers/tty/n_gsm.c +30 -23
index 3038e5631be5..d3d5308daf35 100644
@@ -221,7 +221,6 @@ struct gsm_mux {
 	int encoding;
 	u8 control;
 	u8 fcs;
-	u8 received_fcs;
 	u8 *txframe;			/* TX framing buffer */
 
 	/* Method for the receiver side */
@@ -1799,18 +1798,7 @@ static void gsm_queue(struct gsm_mux *gsm)
 	u8 cr;
 	int address;
 	int i, j, k, address_tmp;
-	/* We have to sneak a look at the packet body to do the FCS.
-	   A somewhat layering violation in the spec */
 
-	if ((gsm->control & ~PF) == UI)
-		gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
-	if (gsm->encoding == 0) {
-		/* WARNING: gsm->received_fcs is used for
-		gsm->encoding = 0 only.
-		In this case it contain the last piece of data
-		required to generate final CRC */
-		gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs);
-	}
 	if (gsm->fcs != GOOD_FCS) {
 		gsm->bad_fcs++;
 		if (debug & 4)
@@ -1997,19 +1985,25 @@ static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
 		break;
 	case GSM_DATA:		/* Data */
 		gsm->buf[gsm->count++] = c;
-		if (gsm->count == gsm->len)
+		if (gsm->count == gsm->len) {
+			/* Calculate final FCS for UI frames over all data */
+			if ((gsm->control & ~PF) != UIH) {
+				gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf,
+							     gsm->count);
+			}
 			gsm->state = GSM_FCS;
+		}
 		break;
 	case GSM_FCS:		/* FCS follows the packet */
-		gsm->received_fcs = c;
-		gsm_queue(gsm);
+		gsm->fcs = gsm_fcs_add(gsm->fcs, c);
 		gsm->state = GSM_SSOF;
 		break;
 	case GSM_SSOF:
-		if (c == GSM0_SOF) {
-			gsm->state = GSM_SEARCH;
-			break;
-		}
+		gsm->state = GSM_SEARCH;
+		if (c == GSM0_SOF)
+			gsm_queue(gsm);
+		else
+			gsm->bad_size++;
 		break;
 	default:
 		pr_debug("%s: unhandled state: %d\n", __func__, gsm->state);
@@ -2038,11 +2032,24 @@ static void gsm1_receive(struct gsm_mux *gsm, unsigned char c)
 		return;
 	}
 	if (c == GSM1_SOF) {
-		/* EOF is only valid in frame if we have got to the data state
-		   and received at least one byte (the FCS) */
-		if (gsm->state == GSM_DATA && gsm->count) {
-			/* Extract the FCS */
+		/* EOF is only valid in frame if we have got to the data state */
+		if (gsm->state == GSM_DATA) {
+			if (gsm->count < 1) {
+				/* Missing FSC */
+				gsm->malformed++;
+				gsm->state = GSM_START;
+				return;
+			}
+			/* Remove the FCS from data */
 			gsm->count--;
+			if ((gsm->control & ~PF) != UIH) {
+				/* Calculate final FCS for UI frames over all
+				 * data but FCS
+				 */
+				gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf,
+							     gsm->count);
+			}
+			/* Add the FCS itself to test against GOOD_FCS */
 			gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->buf[gsm->count]);
 			gsm->len = gsm->count;
 			gsm_queue(gsm);
Signature · 1 line
2.35.1
author maintainer
#124 lore raw

PATCH 121/230 ALSA: usb-audio: add mapping for MSI MPG X570S Carbon Max Wifi.

In reply to Greg Kroah-Hartman

From: Johannes Schickel <[email protected]>

[ Upstream commit 5762f980ca10dcfe5eead7c40d1c34cae61f409b ]

The USB audio device 0db0:419c based on the Realtek ALC4080 chip exposes all playback volume controls as "PCM". This is makes distinguishing the individual functions hard.

The added mapping distinguishes all playback volume controls as their respective function:
- Speaker - for back panel output
- Frontpanel Headphone - for front panel output
- IEC958 - for digital output on the back panel

This clarifies the individual volume control functions for users.

---
 sound/usb/mixer_maps.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
sound/usb/mixer_maps.c +12 -0
index 6ffd23f2ee65..64fdca76b40e 100644
@@ -423,6 +423,14 @@ static const struct usbmix_name_map aorus_master_alc1220vb_map[] = {
 	{}
 };
 
+/* MSI MPG X570S Carbon Max Wifi with ALC4080  */
+static const struct usbmix_name_map msi_mpg_x570s_carbon_max_wifi_alc4080_map[] = {
+	{ 29, "Speaker Playback" },
+	{ 30, "Front Headphone Playback" },
+	{ 32, "IEC958 Playback" },
+	{}
+};
+
 /*
  * Control map entries
  */
@@ -574,6 +582,10 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
 		.map = trx40_mobo_map,
 		.connector_map = trx40_mobo_connector_map,
 	},
+	{	/* MSI MPG X570S Carbon Max Wifi */
+		.id = USB_ID(0x0db0, 0x419c),
+		.map = msi_mpg_x570s_carbon_max_wifi_alc4080_map,
+	},
 	{	/* MSI TRX40 */
 		.id = USB_ID(0x0db0, 0x543d),
 		.map = trx40_mobo_map,
Signature · 1 line
2.35.1
author maintainer
#125 lore raw

PATCH 122/230 ALSA: usb-audio: add mapping for MSI MAG X570S Torpedo MAX.

In reply to Greg Kroah-Hartman

From: Maurizio Avogadro <[email protected]>

[ Upstream commit 4ddef9c4d70aae0c9029bdec7c3f7f1c1c51ff8c ]

The USB audio device 0db0:a073 based on the Realtek ALC4080 chipset exposes all playback volume controls as "PCM". This makes distinguishing the individual functions hard.
The mapping already adopted for device 0db0:419c based on the same chipset fixes the issue, apply it for this device too.

---
 sound/usb/mixer_maps.c | 4 ++++
 1 file changed, 4 insertions(+)
sound/usb/mixer_maps.c +4 -0
index 64fdca76b40e..997425ef0a29 100644
@@ -586,6 +586,10 @@ static const struct usbmix_ctl_map usbmix_ctl_maps[] = {
 		.id = USB_ID(0x0db0, 0x419c),
 		.map = msi_mpg_x570s_carbon_max_wifi_alc4080_map,
 	},
+	{	/* MSI MAG X570S Torpedo Max */
+		.id = USB_ID(0x0db0, 0xa073),
+		.map = msi_mpg_x570s_carbon_max_wifi_alc4080_map,
+	},
 	{	/* MSI TRX40 */
 		.id = USB_ID(0x0db0, 0x543d),
 		.map = trx40_mobo_map,
Signature · 1 line
2.35.1
author maintainer
#126 lore raw

PATCH 123/230 tty: n_gsm: fix missing update of modem controls after DLCI open

In reply to Greg Kroah-Hartman

From: Daniel Starke <[email protected]>

[ Upstream commit 48473802506d2d6151f59e0e764932b33b53cb3b ]

Currently the peer is not informed about the initial state of the modem control lines after a new DLCI has been opened.
Fix this by sending the initial modem control line states after DLCI open.

---
 drivers/tty/n_gsm.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/tty/n_gsm.c +4 -0
index d3d5308daf35..c52d5e0d5c6f 100644
@@ -371,6 +371,7 @@ static const u8 gsm_fcs8[256] = {
 #define GOOD_FCS	0xCF
 
 static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
+static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk);
 
 /**
  *	gsm_fcs_add	-	update FCS
@@ -1489,6 +1490,9 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
 	dlci->state = DLCI_OPEN;
 	if (debug & 8)
 		pr_debug("DLCI %d goes open.\n", dlci->addr);
+	/* Send current modem state */
+	if (dlci->addr)
+		gsmtty_modem_update(dlci, 0);
 	wake_up(&dlci->gsm->event);
 }
 
Signature · 1 line
2.35.1
author maintainer
#127 lore raw

PATCH 124/230 btrfs: zoned: encapsulate inode locking for zoned relocation

In reply to Greg Kroah-Hartman

From: Johannes Thumshirn <[email protected]>

[ Upstream commit 869f4cdc73f9378986755030c684c011f0b71517 ]

Encapsulate the inode lock needed for serializing the data relocation writes on a zoned filesystem into a helper.

This streamlines the code reading flow and hides special casing for zoned filesystems.

---
 fs/btrfs/extent_io.c |  8 ++------
 fs/btrfs/zoned.h     | 17 +++++++++++++++++
 2 files changed, 19 insertions(+), 6 deletions(-)
fs/btrfs/extent_io.c +2 -6
index 6dd375ed6e3d..059bd0753e27 100644
@@ -5139,8 +5139,6 @@ int extent_writepages(struct address_space *mapping,
 		      struct writeback_control *wbc)
 {
 	struct inode *inode = mapping->host;
-	const bool data_reloc = btrfs_is_data_reloc_root(BTRFS_I(inode)->root);
-	const bool zoned = btrfs_is_zoned(BTRFS_I(inode)->root->fs_info);
 	int ret = 0;
 	struct extent_page_data epd = {
 		.bio_ctrl = { 0 },
@@ -5152,11 +5150,9 @@ int extent_writepages(struct address_space *mapping,
 	 * Allow only a single thread to do the reloc work in zoned mode to
 	 * protect the write pointer updates.
 	 */
-	if (data_reloc && zoned)
-		btrfs_inode_lock(inode, 0);
+	btrfs_zoned_data_reloc_lock(BTRFS_I(inode));
 	ret = extent_write_cache_pages(mapping, wbc, &epd);
-	if (data_reloc && zoned)
-		btrfs_inode_unlock(inode, 0);
+	btrfs_zoned_data_reloc_unlock(BTRFS_I(inode));
 	ASSERT(ret <= 0);
 	if (ret < 0) {
 		end_write_bio(&epd, ret);
fs/btrfs/zoned.h +17 -0
index 813aa3cddc11..d680c3ee918a 100644
@@ -8,6 +8,7 @@
 #include "volumes.h"
 #include "disk-io.h"
 #include "block-group.h"
+#include "btrfs_inode.h"
 
 /*
  * Block groups with more than this value (percents) of unusable space will be
@@ -324,4 +325,20 @@ static inline void btrfs_clear_treelog_bg(struct btrfs_block_group *bg)
 	spin_unlock(&fs_info->treelog_bg_lock);
 }
 
+static inline void btrfs_zoned_data_reloc_lock(struct btrfs_inode *inode)
+{
+	struct btrfs_root *root = inode->root;
+
+	if (btrfs_is_data_reloc_root(root) && btrfs_is_zoned(root->fs_info))
+		btrfs_inode_lock(&inode->vfs_inode, 0);
+}
+
+static inline void btrfs_zoned_data_reloc_unlock(struct btrfs_inode *inode)
+{
+	struct btrfs_root *root = inode->root;
+
+	if (btrfs_is_data_reloc_root(root) && btrfs_is_zoned(root->fs_info))
+		btrfs_inode_unlock(&inode->vfs_inode, 0);
+}
+
 #endif
Signature · 1 line
2.35.1
author maintainer
#128 lore raw

PATCH 125/230 btrfs: zoned: use dedicated lock for data relocation

In reply to Greg Kroah-Hartman

From: Naohiro Aota <[email protected]>

[ Upstream commit 5f0addf7b89085f8e0a2593faa419d6111612b9b ]

Currently, we use btrfs_inode_{lock,unlock}() to grant an exclusive writeback of the relocation data inode in btrfs_zoned_data_reloc_{lock,unlock}(). However, that can cause a deadlock in the following path.

Thread A takes btrfs_inode_lock() and waits for metadata reservation by e.g, waiting for writeback:

prealloc_file_extent_cluster()
- btrfs_inode_lock(&inode->vfs_inode, 0);
- btrfs_prealloc_file_range()
...
- btrfs_replace_file_extents()
- btrfs_start_transaction
...
- btrfs_reserve_metadata_bytes()

Thread B (e.g, doing a writeback work) needs to wait for the inode lock to continue writeback process:

do_writepages
- btrfs_writepages
- extent_writpages
- btrfs_zoned_data_reloc_lock(BTRFS_I(inode));
- btrfs_inode_lock()

The deadlock is caused by relying on the vfs_inode's lock. By using it, we introduced unnecessary exclusion of writeback and btrfs_prealloc_file_range(). Also, the lock at this point is useless as we don't have any dirty pages in the inode yet.

Introduce fs_info->zoned_data_reloc_io_lock and use it for the exclusive writeback.

Fixes 35156d852762 ("btrfs: zoned: only allow one process to add pages to a relocation inode")
CC [email protected] # 5.16.x: 869f4cdc73f9: btrfs: zoned: encapsulate inode locking for zoned relocation
CC [email protected] # 5.16.x
Cc Johannes Thumshirn <[email protected]>
---
 fs/btrfs/ctree.h   | 1 +
 fs/btrfs/disk-io.c | 1 +
 fs/btrfs/zoned.h   | 4 ++--
 3 files changed, 4 insertions(+), 2 deletions(-)
fs/btrfs/ctree.h +1 -0
index cc72d8981c47..d1838de0b39c 100644
@@ -1027,6 +1027,7 @@ struct btrfs_fs_info {
 	 */
 	spinlock_t relocation_bg_lock;
 	u64 data_reloc_bg;
+	struct mutex zoned_data_reloc_io_lock;
 
 #ifdef CONFIG_BTRFS_FS_REF_VERIFY
 	spinlock_t ref_verify_lock;
fs/btrfs/disk-io.c +1 -0
index 233d894f6feb..909d19656316 100644
@@ -2914,6 +2914,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
 	mutex_init(&fs_info->reloc_mutex);
 	mutex_init(&fs_info->delalloc_root_mutex);
 	mutex_init(&fs_info->zoned_meta_io_lock);
+	mutex_init(&fs_info->zoned_data_reloc_io_lock);
 	seqlock_init(&fs_info->profiles_lock);
 
 	INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
fs/btrfs/zoned.h +2 -2
index d680c3ee918a..3a826f7c2040 100644
@@ -330,7 +330,7 @@ static inline void btrfs_zoned_data_reloc_lock(struct btrfs_inode *inode)
 	struct btrfs_root *root = inode->root;
 
 	if (btrfs_is_data_reloc_root(root) && btrfs_is_zoned(root->fs_info))
-		btrfs_inode_lock(&inode->vfs_inode, 0);
+		mutex_lock(&root->fs_info->zoned_data_reloc_io_lock);
 }
 
 static inline void btrfs_zoned_data_reloc_unlock(struct btrfs_inode *inode)
@@ -338,7 +338,7 @@ static inline void btrfs_zoned_data_reloc_unlock(struct btrfs_inode *inode)
 	struct btrfs_root *root = inode->root;
 
 	if (btrfs_is_data_reloc_root(root) && btrfs_is_zoned(root->fs_info))
-		btrfs_inode_unlock(&inode->vfs_inode, 0);
+		mutex_unlock(&root->fs_info->zoned_data_reloc_io_lock);
 }
 
 #endif
Signature · 1 line
2.35.1
author maintainer
#129 lore raw

PATCH 126/230 KVM: Initialize debugfs_dentry when a VM is created to avoid NULL deref

In reply to Greg Kroah-Hartman

From: Sean Christopherson <[email protected]>

[ Upstream commit 5c697c367a66307a5d943c3449421aff2aa3ca4a ]

Initialize debugfs_entry to its semi-magical -ENOENT value when the VM is created. KVM's teardown when VM creation fails is kludgy and calls kvm_uevent_notify_change() and kvm_destroy_vm_debugfs() even if KVM never attempted kvm_create_vm_debugfs(). Because debugfs_entry is zero initialized, the IS_ERR() checks pass and KVM derefs a NULL pointer.

  BUG: kernel NULL pointer dereference, address: 0000000000000018
  #PF: supervisor read access in kernel mode
  #PF: error_code(0x0000) - not-present page
  PGD 1068b1067 P4D 1068b1067 PUD 1068b0067 PMD 0
  Oops: 0000 [#1] SMP
  CPU: 0 PID: 871 Comm: repro Not tainted 5.18.0-rc1+ #825
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
  RIP: 0010:__dentry_path+0x7b/0x130
  Call Trace:
   <TASK>
   dentry_path_raw+0x42/0x70
   kvm_uevent_notify_change.part.0+0x10c/0x200 [kvm]
   kvm_put_kvm+0x63/0x2b0 [kvm]
   kvm_dev_ioctl+0x43a/0x920 [kvm]
   __x64_sys_ioctl+0x83/0xb0
   do_syscall_64+0x31/0x50
   entry_SYSCALL_64_after_hwframe+0x44/0xae
   </TASK>
  Modules linked in: kvm_intel kvm irqbypass
Fixes a44a4cc1c969 ("KVM: Don't create VM debugfs files outside of the VM directory")
Cc Marc Zyngier <[email protected]>
Cc Oliver Upton <[email protected]>
Reported-by [email protected]

Message-Id: <[email protected]>

---
 virt/kvm/kvm_main.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
virt/kvm/kvm_main.c +6 -6
index 9134ae252d7c..9eac68ae291e 100644
@@ -934,12 +934,6 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, int fd)
 	int kvm_debugfs_num_entries = kvm_vm_stats_header.num_desc +
 				      kvm_vcpu_stats_header.num_desc;
 
-	/*
-	 * Force subsequent debugfs file creations to fail if the VM directory
-	 * is not created.
-	 */
-	kvm->debugfs_dentry = ERR_PTR(-ENOENT);
-
 	if (!debugfs_initialized())
 		return 0;
 
@@ -1055,6 +1049,12 @@ static struct kvm *kvm_create_vm(unsigned long type)
 
 	BUILD_BUG_ON(KVM_MEM_SLOTS_NUM > SHRT_MAX);
 
+	/*
+	 * Force subsequent debugfs file creations to fail if the VM directory
+	 * is not created (by kvm_create_vm_debugfs()).
+	 */
+	kvm->debugfs_dentry = ERR_PTR(-ENOENT);
+
 	if (init_srcu_struct(&kvm->srcu))
 		goto out_err_no_srcu;
 	if (init_srcu_struct(&kvm->irq_srcu))
Signature · 1 line
2.35.1
author maintainer
#130 lore raw

PATCH 127/230 mm/hwpoison: mf_mutex for soft offline and unpoison

In reply to Greg Kroah-Hartman

From: Naoya Horiguchi <[email protected]>

[ Upstream commit 91d005479e06392617bacc114509d611b705eaac ]

Patch series "mm/hwpoison: fix unpoison_memory()", v4.

The main purpose of this series is to sync unpoison code to recent changes around how hwpoison code takes page refcount. Unpoison should work or simply fail (without crash) if impossible.

The recent works of keeping hwpoison pages in shmem pagecache introduce a new state of hwpoisoned pages, but unpoison for such pages is not supported yet with this series.

It seems that soft-offline and unpoison can be used as general purpose page offline/online mechanism (not in the context of memory error). I think that we need some additional works to realize it because currently soft-offline and unpoison are assumed not to happen so frequently (print out too many messages for aggressive usecases). But anyway this could be another interesting next topic.

v1: https://lore.kernel.org/linux-mm/[email protected]/
v2: https://lore.kernel.org/linux-mm/[email protected]/
v3: https://lore.kernel.org/linux-mm/[email protected]/

This patch (of 3):

Originally mf_mutex is introduced to serialize multiple MCE events, but it is not that useful to allow unpoison to run in parallel with memory_failure() and soft offline. So apply mf_mutex to soft offline and unpoison. The memory failure handler and soft offline handler get simpler with this.

---
 mm/memory-failure.c | 62 +++++++++++++--------------------------------
 1 file changed, 18 insertions(+), 44 deletions(-)
mm/memory-failure.c +18 -44
index c3ceb7436933..e6425d959fa9 100644
@@ -1463,14 +1463,6 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
 	lock_page(head);
 	page_flags = head->flags;
 
-	if (!PageHWPoison(head)) {
-		pr_err("Memory failure: %#lx: just unpoisoned\n", pfn);
-		num_poisoned_pages_dec();
-		unlock_page(head);
-		put_page(head);
-		return 0;
-	}
-
 	/*
 	 * TODO: hwpoison for pud-sized hugetlb doesn't work right now, so
 	 * simply disable it. In order to make it work properly, we need
@@ -1584,6 +1576,8 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags,
 	return rc;
 }
 
+static DEFINE_MUTEX(mf_mutex);
+
 /**
  * memory_failure - Handle memory failure of a page.
  * @pfn: Page Number of the corrupted page
@@ -1610,7 +1604,6 @@ int memory_failure(unsigned long pfn, int flags)
 	int res = 0;
 	unsigned long page_flags;
 	bool retry = true;
-	static DEFINE_MUTEX(mf_mutex);
 
 	if (!sysctl_memory_failure_recovery)
 		panic("Memory failure on page %lx", pfn);
@@ -1744,16 +1737,6 @@ int memory_failure(unsigned long pfn, int flags)
 	 */
 	page_flags = p->flags;
 
-	/*
-	 * unpoison always clear PG_hwpoison inside page lock
-	 */
-	if (!PageHWPoison(p)) {
-		pr_err("Memory failure: %#lx: just unpoisoned\n", pfn);
-		num_poisoned_pages_dec();
-		unlock_page(p);
-		put_page(p);
-		goto unlock_mutex;
-	}
 	if (hwpoison_filter(p)) {
 		if (TestClearPageHWPoison(p))
 			num_poisoned_pages_dec();
@@ -1934,6 +1917,7 @@ int unpoison_memory(unsigned long pfn)
 	struct page *page;
 	struct page *p;
 	int freeit = 0;
+	int ret = 0;
 	unsigned long flags = 0;
 	static DEFINE_RATELIMIT_STATE(unpoison_rs, DEFAULT_RATELIMIT_INTERVAL,
 					DEFAULT_RATELIMIT_BURST);
@@ -1944,39 +1928,30 @@ int unpoison_memory(unsigned long pfn)
 	p = pfn_to_page(pfn);
 	page = compound_head(p);
 
+	mutex_lock(&mf_mutex);
+
 	if (!PageHWPoison(p)) {
 		unpoison_pr_info("Unpoison: Page was already unpoisoned %#lx\n",
 				 pfn, &unpoison_rs);
-		return 0;
+		goto unlock_mutex;
 	}
 
 	if (page_count(page) > 1) {
 		unpoison_pr_info("Unpoison: Someone grabs the hwpoison page %#lx\n",
 				 pfn, &unpoison_rs);
-		return 0;
+		goto unlock_mutex;
 	}
 
 	if (page_mapped(page)) {
 		unpoison_pr_info("Unpoison: Someone maps the hwpoison page %#lx\n",
 				 pfn, &unpoison_rs);
-		return 0;
+		goto unlock_mutex;
 	}
 
 	if (page_mapping(page)) {
 		unpoison_pr_info("Unpoison: the hwpoison page has non-NULL mapping %#lx\n",
 				 pfn, &unpoison_rs);
-		return 0;
-	}
-
-	/*
-	 * unpoison_memory() can encounter thp only when the thp is being
-	 * worked by memory_failure() and the page lock is not held yet.
-	 * In such case, we yield to memory_failure() and make unpoison fail.
-	 */
-	if (!PageHuge(page) && PageTransHuge(page)) {
-		unpoison_pr_info("Unpoison: Memory failure is now running on %#lx\n",
-				 pfn, &unpoison_rs);
-		return 0;
+		goto unlock_mutex;
 	}
 
 	if (!get_hwpoison_page(p, flags)) {
@@ -1984,29 +1959,23 @@ int unpoison_memory(unsigned long pfn)
 			num_poisoned_pages_dec();
 		unpoison_pr_info("Unpoison: Software-unpoisoned free page %#lx\n",
 				 pfn, &unpoison_rs);
-		return 0;
+		goto unlock_mutex;
 	}
 
-	lock_page(page);
-	/*
-	 * This test is racy because PG_hwpoison is set outside of page lock.
-	 * That's acceptable because that won't trigger kernel panic. Instead,
-	 * the PG_hwpoison page will be caught and isolated on the entrance to
-	 * the free buddy page pool.
-	 */
 	if (TestClearPageHWPoison(page)) {
 		unpoison_pr_info("Unpoison: Software-unpoisoned page %#lx\n",
 				 pfn, &unpoison_rs);
 		num_poisoned_pages_dec();
 		freeit = 1;
 	}
-	unlock_page(page);
 
 	put_page(page);
 	if (freeit && !(pfn == my_zero_pfn(0) && page_count(p) == 1))
 		put_page(page);
 
-	return 0;
+unlock_mutex:
+	mutex_unlock(&mf_mutex);
+	return ret;
 }
 EXPORT_SYMBOL(unpoison_memory);
 
@@ -2187,9 +2156,12 @@ int soft_offline_page(unsigned long pfn, int flags)
 		return -EIO;
 	}
 
+	mutex_lock(&mf_mutex);
+
 	if (PageHWPoison(page)) {
 		pr_info("%s: %#lx page already poisoned\n", __func__, pfn);
 		put_ref_page(ref_page);
+		mutex_unlock(&mf_mutex);
 		return 0;
 	}
 
@@ -2208,5 +2180,7 @@ int soft_offline_page(unsigned long pfn, int flags)
 		}
 	}
 
+	mutex_unlock(&mf_mutex);
+
 	return ret;
 }
Signature · 1 line
2.35.1
author maintainer
#131 lore raw

PATCH 128/230 mm/hwpoison: avoid the impact of hwpoison_filter() return value on mce handler

In reply to Greg Kroah-Hartman

From: luofei <[email protected]>

[ Upstream commit d1fe111fb62a1cf0446a2919f5effbb33ad0702c ]

When the hwpoison page meets the filter conditions, it should not be regarded as successful memory_failure() processing for mce handler, but should return a distinct value, otherwise mce handler regards the error page has been identified and isolated, which may lead to calling set_mce_nospec() to change page attribute, etc.

Here memory_failure() return -EOPNOTSUPP to indicate that the error event is filtered, mce handler should not take any action for this situation and hwpoison injector should treat as correct.

---
 arch/x86/kernel/cpu/mce/core.c | 8 +++++---
 drivers/base/memory.c          | 2 ++
 mm/hwpoison-inject.c           | 3 ++-
 mm/madvise.c                   | 2 ++
 mm/memory-failure.c            | 9 +++++++--
 5 files changed, 18 insertions(+), 6 deletions(-)
arch/x86/kernel/cpu/mce/core.c +5 -3
index e23e74e2f928..848cfb013f58 100644
@@ -1297,10 +1297,12 @@ static void kill_me_maybe(struct callback_head *cb)
 
 	/*
 	 * -EHWPOISON from memory_failure() means that it already sent SIGBUS
-	 * to the current process with the proper error info, so no need to
-	 * send SIGBUS here again.
+	 * to the current process with the proper error info,
+	 * -EOPNOTSUPP means hwpoison_filter() filtered the error event,
+	 *
+	 * In both cases, no further processing is required.
 	 */
-	if (ret == -EHWPOISON)
+	if (ret == -EHWPOISON || ret == -EOPNOTSUPP)
 		return;
 
 	if (p->mce_vaddr != (void __user *)-1l) {
drivers/base/memory.c +2 -0
index c0d501a3a714..c778d1df7455 100644
@@ -555,6 +555,8 @@ static ssize_t hard_offline_page_store(struct device *dev,
 		return -EINVAL;
 	pfn >>= PAGE_SHIFT;
 	ret = memory_failure(pfn, 0);
+	if (ret == -EOPNOTSUPP)
+		ret = 0;
 	return ret ? ret : count;
 }
 
mm/hwpoison-inject.c +2 -1
index aff4d27ec235..a1d6fc3c78b9 100644
@@ -48,7 +48,8 @@ static int hwpoison_inject(void *data, u64 val)
 
 inject:
 	pr_info("Injecting memory failure at pfn %#lx\n", pfn);
-	return memory_failure(pfn, 0);
+	err = memory_failure(pfn, 0);
+	return (err == -EOPNOTSUPP) ? 0 : err;
 }
 
 static int hwpoison_unpoison(void *data, u64 val)
mm/madvise.c +2 -0
index 8e5ca01a6cc0..882767d58c27 100644
@@ -968,6 +968,8 @@ static int madvise_inject_error(int behavior,
 			pr_info("Injecting memory failure for pfn %#lx at process virtual address %#lx\n",
 				 pfn, start);
 			ret = memory_failure(pfn, MF_COUNT_INCREASED);
+			if (ret == -EOPNOTSUPP)
+				ret = 0;
 		}
 
 		if (ret)
mm/memory-failure.c +7 -2
index e6425d959fa9..5664bafd5e77 100644
@@ -1444,7 +1444,7 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
 				if (TestClearPageHWPoison(head))
 					num_poisoned_pages_dec();
 				unlock_page(head);
-				return 0;
+				return -EOPNOTSUPP;
 			}
 			unlock_page(head);
 			res = MF_FAILED;
@@ -1525,7 +1525,7 @@ static int memory_failure_dev_pagemap(unsigned long pfn, int flags,
 		goto out;
 
 	if (hwpoison_filter(page)) {
-		rc = 0;
+		rc = -EOPNOTSUPP;
 		goto unlock;
 	}
 
@@ -1594,6 +1594,10 @@ static DEFINE_MUTEX(mf_mutex);
  *
  * Must run in process context (e.g. a work queue) with interrupts
  * enabled and no spinlocks hold.
+ *
+ * Return: 0 for successfully handled the memory error,
+ *         -EOPNOTSUPP for memory_filter() filtered the error event,
+ *         < 0(except -EOPNOTSUPP) on failure.
  */
 int memory_failure(unsigned long pfn, int flags)
 {
@@ -1742,6 +1746,7 @@ int memory_failure(unsigned long pfn, int flags)
 			num_poisoned_pages_dec();
 		unlock_page(p);
 		put_page(p);
+		res = -EOPNOTSUPP;
 		goto unlock_mutex;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#132 lore raw

PATCH 129/230 mm/memory-failure.c: fix race with changing page compound again

In reply to Greg Kroah-Hartman

From: Miaohe Lin <[email protected]>

[ Upstream commit 888af2701db79b9b27c7e37f9ede528a5ca53b76 ]

Patch series "A few fixup patches for memory failure", v2.

This series contains a few patches to fix the race with changing page compound page, make non-LRU movable pages unhandlable and so on. More details can be found in the respective changelogs.

There is a race window where we got the compound_head, the hugetlb page could be freed to buddy, or even changed to another compound page just before we try to get hwpoison page. Think about the below race window:

CPU 1 CPU 2
memory_failure_hugetlb
struct page *head = compound_head(p);
hugetlb page might be freed to buddy, or even changed to another compound page.

get_hwpoison_page -- page is not what we want now...

If this race happens, just bail out. Also MF_MSG_DIFFERENT_PAGE_SIZE is introduced to record this event.

[[email protected]: s@/**@/*@, per Naoya Horiguchi]

---
 include/linux/mm.h      |  1 +
 include/ras/ras_event.h |  1 +
 mm/memory-failure.c     | 12 ++++++++++++
 3 files changed, 14 insertions(+)
include/linux/mm.h +1 -0
index 85205adcdd0d..7a80a08eec84 100644
@@ -3167,6 +3167,7 @@ enum mf_action_page_type {
 	MF_MSG_BUDDY_2ND,
 	MF_MSG_DAX,
 	MF_MSG_UNSPLIT_THP,
+	MF_MSG_DIFFERENT_PAGE_SIZE,
 	MF_MSG_UNKNOWN,
 };
 
include/ras/ras_event.h +1 -0
index 0bdbc0d17d2f..cac13ff1d6eb 100644
@@ -376,6 +376,7 @@ TRACE_EVENT(aer_event,
 	EM ( MF_MSG_BUDDY_2ND, "free buddy page (2nd try)" )		\
 	EM ( MF_MSG_DAX, "dax page" )					\
 	EM ( MF_MSG_UNSPLIT_THP, "unsplit thp" )			\
+	EM ( MF_MSG_DIFFERENT_PAGE_SIZE, "different page size" )	\
 	EMe ( MF_MSG_UNKNOWN, "unknown page" )
 
 /*
mm/memory-failure.c +12 -0
index 5664bafd5e77..a4d70c21c146 100644
@@ -741,6 +741,7 @@ static const char * const action_page_types[] = {
 	[MF_MSG_BUDDY_2ND]		= "free buddy page (2nd try)",
 	[MF_MSG_DAX]			= "dax page",
 	[MF_MSG_UNSPLIT_THP]		= "unsplit thp",
+	[MF_MSG_DIFFERENT_PAGE_SIZE]	= "different page size",
 	[MF_MSG_UNKNOWN]		= "unknown page",
 };
 
@@ -1461,6 +1462,17 @@ static int memory_failure_hugetlb(unsigned long pfn, int flags)
 	}
 
 	lock_page(head);
+
+	/*
+	 * The page could have changed compound pages due to race window.
+	 * If this happens just bail out.
+	 */
+	if (!PageHuge(p) || compound_head(p) != head) {
+		action_result(pfn, MF_MSG_DIFFERENT_PAGE_SIZE, MF_IGNORED);
+		res = -EBUSY;
+		goto out;
+	}
+
 	page_flags = head->flags;
 
 	/*
Signature · 1 line
2.35.1
author maintainer
#133 lore raw

PATCH 130/230 mm/hwpoison: fix race between hugetlb free/demotion and memory_failure_hugetlb()

In reply to Greg Kroah-Hartman

From: Naoya Horiguchi <[email protected]>

[ Upstream commit 405ce051236cc65b30bbfe490b28ce60ae6aed85 ]

There is a race condition between memory_failure_hugetlb() and hugetlb free/demotion, which causes setting PageHWPoison flag on the wrong page. The one simple result is that wrong processes can be killed, but another (more serious) one is that the actual error is left unhandled, so no one prevents later access to it, and that might lead to more serious results like consuming corrupted data.

Think about the below race window:

CPU 1 CPU 2
memory_failure_hugetlb
struct page *head = compound_head(p);
hugetlb page might be freed to buddy, or even changed to another compound page.

get_hwpoison_page -- page is not what we want now...

The current code first does prechecks roughly and then reconfirms after taking refcount, but it's found that it makes code overly complicated, so move the prechecks in a single hugetlb_lock range.

A newly introduced function, try_memory_failure_hugetlb(), always takes hugetlb_lock (even for non-hugetlb pages). That can be improved, but memory_failure() is rare in principle, so should not be a big problem.

---
 include/linux/hugetlb.h |   6 ++
 include/linux/mm.h      |   8 +++
 mm/hugetlb.c            |  10 +++
 mm/memory-failure.c     | 137 ++++++++++++++++++++++++++++++----------
 4 files changed, 127 insertions(+), 34 deletions(-)
include/linux/hugetlb.h +6 -0
index 1faebe1cd0ed..22c1d935e22d 100644
@@ -167,6 +167,7 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
 						long freed);
 bool isolate_huge_page(struct page *page, struct list_head *list);
 int get_hwpoison_huge_page(struct page *page, bool *hugetlb);
+int get_huge_page_for_hwpoison(unsigned long pfn, int flags);
 void putback_active_hugepage(struct page *page);
 void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason);
 void free_huge_page(struct page *page);
@@ -362,6 +363,11 @@ static inline int get_hwpoison_huge_page(struct page *page, bool *hugetlb)
 	return 0;
 }
 
+static inline int get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+{
+	return 0;
+}
+
 static inline void putback_active_hugepage(struct page *page)
 {
 }
include/linux/mm.h +8 -0
index 7a80a08eec84..c5fa46e9c0ca 100644
@@ -3132,6 +3132,14 @@ extern int sysctl_memory_failure_recovery;
 extern void shake_page(struct page *p);
 extern atomic_long_t num_poisoned_pages __read_mostly;
 extern int soft_offline_page(unsigned long pfn, int flags);
+#ifdef CONFIG_MEMORY_FAILURE
+extern int __get_huge_page_for_hwpoison(unsigned long pfn, int flags);
+#else
+static inline int __get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+{
+	return 0;
+}
+#endif
 
 
 /*
mm/hugetlb.c +10 -0
index e4c717b08cfe..eed96302897a 100644
@@ -6290,6 +6290,16 @@ int get_hwpoison_huge_page(struct page *page, bool *hugetlb)
 	return ret;
 }
 
+int get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+{
+	int ret;
+
+	spin_lock_irq(&hugetlb_lock);
+	ret = __get_huge_page_for_hwpoison(pfn, flags);
+	spin_unlock_irq(&hugetlb_lock);
+	return ret;
+}
+
 void putback_active_hugepage(struct page *page)
 {
 	spin_lock_irq(&hugetlb_lock);
mm/memory-failure.c +103 -34

175 lines not on this page · raw message

Signature · 1 line
2.35.1
author maintainer
#134 lore raw

PATCH 131/230 tty: n_gsm: fix invalid use of MSC in advanced option

In reply to Greg Kroah-Hartman

From: Daniel Starke <[email protected]>

[ Upstream commit c19ffe00fed6bb423d81406d2a7e5793074c7d83 ]

n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
the newer 27.010 here. Chapter 5.4.6.3.7 states that the Modem Status
Command (MSC) shall only be used if the basic option was chosen.
The current implementation uses MSC frames even if advanced option was
chosen to inform the peer about modem line state updates. A standard
conform peer may choose to discard these frames in advanced option mode.
Furthermore, gsmtty_modem_update() is not part of the 'tty_operations'
functions despite its name.
Rename gsmtty_modem_update() to gsm_modem_update() to clarify this. Split
its function into gsm_modem_upd_via_data() and gsm_modem_upd_via_msc()
depending on the encoding and adaption. Introduce gsm_dlci_modem_output()
as adaption of gsm_dlci_data_output() to encode and queue empty frames in
advanced option mode. Use it in gsm_modem_upd_via_data().
gsm_modem_upd_via_msc() is based on the initial gsmtty_modem_update()
function which used only MSC frames to update modem states.

---
 drivers/tty/n_gsm.c | 125 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 117 insertions(+), 8 deletions(-)
drivers/tty/n_gsm.c +117 -8
index c52d5e0d5c6f..c8ca00fad8e4 100644
@@ -371,7 +371,7 @@ static const u8 gsm_fcs8[256] = {
 #define GOOD_FCS	0xCF
 
 static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
-static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk);
+static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
 
 /**
  *	gsm_fcs_add	-	update FCS
@@ -928,6 +928,63 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
 	return size;
 }
 
+/**
+ *	gsm_dlci_modem_output	-	try and push modem status out of a DLCI
+ *	@gsm: mux
+ *	@dlci: the DLCI to pull modem status from
+ *	@brk: break signal
+ *
+ *	Push an empty frame in to the transmit queue to update the modem status
+ *	bits and to transmit an optional break.
+ *
+ *	Caller must hold the tx_lock of the mux.
+ */
+
+static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
+				 u8 brk)
+{
+	u8 *dp = NULL;
+	struct gsm_msg *msg;
+	int size;
+
+	/* for modem bits without break data */
+	if (dlci->adaption == 1) {
+		size = 0;
+	} else if (dlci->adaption == 2) {
+		size = 1;
+		if (brk > 0)
+			size++;
+	} else {
+		pr_err("%s: unsupported adaption %d\n", __func__,
+		       dlci->adaption);
+	}
+
+	msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
+	if (!msg) {
+		pr_err("%s: gsm_data_alloc error", __func__);
+		return -ENOMEM;
+	}
+	dp = msg->data;
+	switch (dlci->adaption) {
+	case 1: /* Unstructured */
+		break;
+	case 2: /* Unstructured with modem bits. */
+		if (brk == 0) {
+			*dp++ = (gsm_encode_modem(dlci) << 1) | EA;
+		} else {
+			*dp++ = gsm_encode_modem(dlci) << 1;
+			*dp++ = (brk << 4) | 2 | EA; /* Length, Break, EA */
+		}
+		break;
+	default:
+		/* Handled above */
+		break;
+	}
+
+	__gsm_data_queue(dlci, msg);
+	return size;
+}
+
 /**
  *	gsm_dlci_data_sweep		-	look for data to send
  *	@gsm: the GSM mux
@@ -1492,7 +1549,7 @@ static void gsm_dlci_open(struct gsm_dlci *dlci)
 		pr_debug("DLCI %d goes open.\n", dlci->addr);
 	/* Send current modem state */
 	if (dlci->addr)
-		gsmtty_modem_update(dlci, 0);
+		gsm_modem_update(dlci, 0);
 	wake_up(&dlci->gsm->event);
 }
 
@@ -2977,12 +3034,43 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
 
 #define TX_SIZE		512
 
-static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
+/**
+ *	gsm_modem_upd_via_data	-	send modem bits via convergence layer
+ *	@dlci: channel
+ *	@brk: break signal
+ *
+ *	Send an empty frame to signal mobile state changes and to transmit the
+ *	break signal for adaption 2.
+ */
+
+static void gsm_modem_upd_via_data(struct gsm_dlci *dlci, u8 brk)
+{
+	struct gsm_mux *gsm = dlci->gsm;
+	unsigned long flags;
+
+	if (dlci->state != DLCI_OPEN || dlci->adaption != 2)
+		return;
+
+	spin_lock_irqsave(&gsm->tx_lock, flags);
+	gsm_dlci_modem_output(gsm, dlci, brk);
+	spin_unlock_irqrestore(&gsm->tx_lock, flags);
+}
+
+/**
+ *	gsm_modem_upd_via_msc	-	send modem bits via control frame
+ *	@dlci: channel
+ *	@brk: break signal
+ */
+
+static int gsm_modem_upd_via_msc(struct gsm_dlci *dlci, u8 brk)
 {
 	u8 modembits[3];
 	struct gsm_control *ctrl;
 	int len = 2;
 
+	if (dlci->gsm->encoding != 0)
+		return 0;
+
 	modembits[0] = (dlci->addr << 2) | 2 | EA;  /* DLCI, Valid, EA */
 	if (!brk) {
 		modembits[1] = (gsm_encode_modem(dlci) << 1) | EA;
@@ -2997,6 +3085,27 @@ static int gsmtty_modem_update(struct gsm_dlci *dlci, u8 brk)
 	return gsm_control_wait(dlci->gsm, ctrl);
 }
 
+/**
+ *	gsm_modem_update	-	send modem status line state
+ *	@dlci: channel
+ *	@brk: break signal
+ */
+
+static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk)
+{
+	if (dlci->adaption == 2) {
+		/* Send convergence layer type 2 empty data frame. */
+		gsm_modem_upd_via_data(dlci, brk);
+		return 0;
+	} else if (dlci->gsm->encoding == 0) {
+		/* Send as MSC control message. */
+		return gsm_modem_upd_via_msc(dlci, brk);
+	}
+
+	/* Modem status lines are not supported. */
+	return -EPROTONOSUPPORT;
+}
+
 static int gsm_carrier_raised(struct tty_port *port)
 {
 	struct gsm_dlci *dlci = container_of(port, struct gsm_dlci, port);
@@ -3029,7 +3138,7 @@ static void gsm_dtr_rts(struct tty_port *port, int onoff)
 		modem_tx &= ~(TIOCM_DTR | TIOCM_RTS);
 	if (modem_tx != dlci->modem_tx) {
 		dlci->modem_tx = modem_tx;
-		gsmtty_modem_update(dlci, 0);
+		gsm_modem_update(dlci, 0);
 	}
 }
 
@@ -3218,7 +3327,7 @@ static int gsmtty_tiocmset(struct tty_struct *tty,
 
 	if (modem_tx != dlci->modem_tx) {
 		dlci->modem_tx = modem_tx;
-		return gsmtty_modem_update(dlci, 0);
+		return gsm_modem_update(dlci, 0);
 	}
 	return 0;
 }
@@ -3279,7 +3388,7 @@ static void gsmtty_throttle(struct tty_struct *tty)
 		dlci->modem_tx &= ~TIOCM_RTS;
 	dlci->throttled = true;
 	/* Send an MSC with RTS cleared */
-	gsmtty_modem_update(dlci, 0);
+	gsm_modem_update(dlci, 0);
 }
 
 static void gsmtty_unthrottle(struct tty_struct *tty)
@@ -3291,7 +3400,7 @@ static void gsmtty_unthrottle(struct tty_struct *tty)
 		dlci->modem_tx |= TIOCM_RTS;
 	dlci->throttled = false;
 	/* Send an MSC with RTS set */
-	gsmtty_modem_update(dlci, 0);
+	gsm_modem_update(dlci, 0);
 }
 
 static int gsmtty_break_ctl(struct tty_struct *tty, int state)
@@ -3309,7 +3418,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state)
 		if (encode > 0x0F)
 			encode = 0x0F;	/* Best effort */
 	}
-	return gsmtty_modem_update(dlci, encode);
+	return gsm_modem_update(dlci, encode);
 }
 
 static void gsmtty_cleanup(struct tty_struct *tty)
Signature · 1 line
2.35.1
author maintainer
#135 lore raw

PATCH 132/230 tty: n_gsm: fix sometimes uninitialized warning in gsm_dlci_modem_output()

In reply to Greg Kroah-Hartman

From: Daniel Starke <[email protected]>

[ Upstream commit 19317433057dc1f2ca9a975e4e6b547282c2a5ef ]

'size' may be used uninitialized in gsm_dlci_modem_output() if called with an adaption that is neither 1 nor 2. The function is currently only called by gsm_modem_upd_via_data() and only for adaption 2.
Properly handle every invalid case by returning -EINVAL to silence the compiler warning and avoid future regressions.

---
 drivers/tty/n_gsm.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/tty/n_gsm.c +9 -6
index c8ca00fad8e4..fd4a86111a6e 100644
@@ -945,18 +945,21 @@ static int gsm_dlci_modem_output(struct gsm_mux *gsm, struct gsm_dlci *dlci,
 {
 	u8 *dp = NULL;
 	struct gsm_msg *msg;
-	int size;
+	int size = 0;
 
 	/* for modem bits without break data */
-	if (dlci->adaption == 1) {
-		size = 0;
-	} else if (dlci->adaption == 2) {
-		size = 1;
+	switch (dlci->adaption) {
+	case 1: /* Unstructured */
+		break;
+	case 2: /* Unstructured with modem bits. */
+		size++;
 		if (brk > 0)
 			size++;
-	} else {
+		break;
+	default:
 		pr_err("%s: unsupported adaption %d\n", __func__,
 		       dlci->adaption);
+		return -EINVAL;
 	}
 
 	msg = gsm_data_alloc(gsm, dlci->addr, size, gsm->ftype);
Signature · 1 line
2.35.1
author maintainer
#136 lore raw

PATCH 133/230 powerpc/vdso: Remove cvdso_call_time macro

In reply to Greg Kroah-Hartman

From: Christophe Leroy <[email protected]>

[ Upstream commit 9b97bea90072a075363a200dd7b54ad4a24e9491 ]

cvdso_call_time macro is very similar to cvdso_call macro.

Add a call_time argument to cvdso_call which is 0 by default and set to 1 when using cvdso_call to call __c_kernel_time().

Return returned value as is with CR[SO] cleared when it is used for time().

---
 arch/powerpc/include/asm/vdso/gettimeofday.h | 37 ++++++--------------
 arch/powerpc/kernel/vdso32/gettimeofday.S    |  2 +-
 2 files changed, 11 insertions(+), 28 deletions(-)
arch/powerpc/include/asm/vdso/gettimeofday.h +10 -27
index 1faff0be1111..df00e91c9a90 100644
@@ -9,12 +9,12 @@
 #include <asm/ppc_asm.h>
 
 /*
- * The macros sets two stack frames, one for the caller and one for the callee
+ * The macro sets two stack frames, one for the caller and one for the callee
  * because there are no requirement for the caller to set a stack frame when
  * calling VDSO so it may have omitted to set one, especially on PPC64
  */
 
-.macro cvdso_call funct
+.macro cvdso_call funct call_time=0
   .cfi_startproc
 	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
 	mflr		r0
@@ -25,45 +25,28 @@
 	PPC_STL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
 #endif
 	get_datapage	r5
+	.ifeq	\call_time
 	addi		r5, r5, VDSO_DATA_OFFSET
+	.else
+	addi		r4, r5, VDSO_DATA_OFFSET
+	.endif
 	bl		DOTSYM(\funct)
 	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
 #ifdef __powerpc64__
 	PPC_LL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
 #endif
+	.ifeq	\call_time
 	cmpwi		r3, 0
+	.endif
 	mtlr		r0
   .cfi_restore lr
 	addi		r1, r1, 2 * PPC_MIN_STKFRM
 	crclr		so
+	.ifeq	\call_time
 	beqlr+
 	crset		so
 	neg		r3, r3
-	blr
-  .cfi_endproc
-.endm
-
-.macro cvdso_call_time funct
-  .cfi_startproc
-	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
-	mflr		r0
-  .cfi_register lr, r0
-	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
-	PPC_STL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
-#ifdef __powerpc64__
-	PPC_STL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
-#endif
-	get_datapage	r4
-	addi		r4, r4, VDSO_DATA_OFFSET
-	bl		DOTSYM(\funct)
-	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
-#ifdef __powerpc64__
-	PPC_LL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
-#endif
-	crclr		so
-	mtlr		r0
-  .cfi_restore lr
-	addi		r1, r1, 2 * PPC_MIN_STKFRM
+	.endif
 	blr
   .cfi_endproc
 .endm
arch/powerpc/kernel/vdso32/gettimeofday.S +1 -1
index d21d08140a5e..9b3ac09423c8 100644
@@ -63,7 +63,7 @@ V_FUNCTION_END(__kernel_clock_getres)
  *
  */
 V_FUNCTION_BEGIN(__kernel_time)
-	cvdso_call_time __c_kernel_time
+	cvdso_call __c_kernel_time call_time=1
 V_FUNCTION_END(__kernel_time)
 
 /* Routines for restoring integer registers, called by the compiler.  */
Signature · 1 line
2.35.1
author maintainer
#137 lore raw

PATCH 134/230 powerpc/vdso: Move cvdso_call macro into gettimeofday.S

In reply to Greg Kroah-Hartman

From: Christophe Leroy <[email protected]>

[ Upstream commit 692b21d78046851e75dc25bba773189c670b49c2 ]

Now that gettimeofday.S is unique, move cvdso_call macro into that file which is the only user.

---
 arch/powerpc/include/asm/vdso/gettimeofday.h | 52 +-------------------
 arch/powerpc/kernel/vdso32/gettimeofday.S    | 44 ++++++++++++++++-
 2 files changed, 45 insertions(+), 51 deletions(-)
arch/powerpc/include/asm/vdso/gettimeofday.h +2 -50
index df00e91c9a90..f0a4cf01e85c 100644
@@ -2,57 +2,9 @@
 #ifndef _ASM_POWERPC_VDSO_GETTIMEOFDAY_H
 #define _ASM_POWERPC_VDSO_GETTIMEOFDAY_H
 
-#include <asm/page.h>
-
-#ifdef __ASSEMBLY__
-
-#include <asm/ppc_asm.h>
-
-/*
- * The macro sets two stack frames, one for the caller and one for the callee
- * because there are no requirement for the caller to set a stack frame when
- * calling VDSO so it may have omitted to set one, especially on PPC64
- */
-
-.macro cvdso_call funct call_time=0
-  .cfi_startproc
-	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
-	mflr		r0
-  .cfi_register lr, r0
-	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
-	PPC_STL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
-#ifdef __powerpc64__
-	PPC_STL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
-#endif
-	get_datapage	r5
-	.ifeq	\call_time
-	addi		r5, r5, VDSO_DATA_OFFSET
-	.else
-	addi		r4, r5, VDSO_DATA_OFFSET
-	.endif
-	bl		DOTSYM(\funct)
-	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
-#ifdef __powerpc64__
-	PPC_LL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
-#endif
-	.ifeq	\call_time
-	cmpwi		r3, 0
-	.endif
-	mtlr		r0
-  .cfi_restore lr
-	addi		r1, r1, 2 * PPC_MIN_STKFRM
-	crclr		so
-	.ifeq	\call_time
-	beqlr+
-	crset		so
-	neg		r3, r3
-	.endif
-	blr
-  .cfi_endproc
-.endm
-
-#else
+#ifndef __ASSEMBLY__
 
+#include <asm/page.h>
 #include <asm/vdso/timebase.h>
 #include <asm/barrier.h>
 #include <asm/unistd.h>
arch/powerpc/kernel/vdso32/gettimeofday.S +43 -1

50 lines not on this page · raw message

Signature · 1 line
2.35.1
author maintainer
#138 lore raw

PATCH 135/230 powerpc/vdso: Fix incorrect CFI in gettimeofday.S

In reply to Greg Kroah-Hartman

From: Michael Ellerman <[email protected]>

[ Upstream commit 6d65028eb67dbb7627651adfc460d64196d38bd8 ]

As reported by Alan, the CFI (Call Frame Information) in the VDSO time routines is incorrect since commit ce7d8056e38b ("powerpc/vdso: Prepare for switching VDSO to generic C implementation.").

DWARF has a concept called the CFA (Canonical Frame Address), which on powerpc is calculated as an offset from the stack pointer (r1). That means when the stack pointer is changed there must be a corresponding CFI directive to update the calculation of the CFA.

The current code is missing those directives for the changes to r1, which prevents gdb from being able to generate a backtrace from inside VDSO functions, eg:

Breakpoint 1, 0x00007ffff7f804dc in __kernel_clock_gettime () (gdb) bt

  #0  0x00007ffff7f804dc in __kernel_clock_gettime ()
  #1  0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6
  #2  0x00007fffffffd960 in ?? ()
  #3  0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6

Backtrace stopped: frame did not save the PC

Alan helpfully describes some rules for correctly maintaining the CFI information:

1) Every adjustment to the current frame address reg (ie. r1) must be described, and exactly at the instruction where r1 changes. Why? Because stack unwinding might want to access previous frames.

2) If a function changes LR or any non-volatile register, the save location for those regs must be given. The CFI can be at any instruction after the saves up to the point that the reg is changed.
(Exception: LR save should be described before a bl. not after)

3) If asychronous unwind info is needed then restores of LR and non-volatile regs must also be described. The CFI can be at any instruction after the reg is restored up to the point where the save location is (potentially) trashed.

Fix the inability to backtrace by adding CFI directives describing the changes to r1, ie. satisfying rule 1.

Also change the information for LR to point to the copy saved on the stack, not the value in r0 that will be overwritten by the function call.

Finally, add CFI directives describing the save/restore of r2.

With the fix gdb can correctly back trace and navigate up and down the stack:

Breakpoint 1, 0x00007ffff7f804dc in __kernel_clock_gettime () (gdb) bt

  #0  0x00007ffff7f804dc in __kernel_clock_gettime ()
  #1  0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6
  #2  0x0000000100015b60 in gettime ()
  #3  0x000000010000c8bc in print_long_format ()
  #4  0x000000010000d180 in print_current_files ()
  #5  0x00000001000054ac in main ()

(gdb) up
#1 0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6 (gdb)
#2 0x0000000100015b60 in gettime ()
(gdb)
#3 0x000000010000c8bc in print_long_format ()
(gdb)
#4 0x000000010000d180 in print_current_files ()
(gdb)
#5 0x00000001000054ac in main ()
(gdb)
Initial frame selected; you cannot go up.
(gdb) down
#4 0x000000010000d180 in print_current_files ()
(gdb)
#3 0x000000010000c8bc in print_long_format ()
(gdb)
#2 0x0000000100015b60 in gettime ()
(gdb)
#1 0x00007ffff7d8872c in clock_gettime@@GLIBC_2.17 () from /lib64/libc.so.6 (gdb)
#0 0x00007ffff7f804dc in __kernel_clock_gettime ()
(gdb)

Fixes ce7d8056e38b ("powerpc/vdso: Prepare for switching VDSO to generic C implementation.")
Cc [email protected] # v5.11+
---
 arch/powerpc/kernel/vdso32/gettimeofday.S | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
arch/powerpc/kernel/vdso32/gettimeofday.S +7 -2
index dd2099128b8f..42d40f895c1f 100644
@@ -22,12 +22,15 @@
 .macro cvdso_call funct call_time=0
   .cfi_startproc
 	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
+  .cfi_adjust_cfa_offset PPC_MIN_STKFRM
 	mflr		r0
-  .cfi_register lr, r0
 	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
+  .cfi_adjust_cfa_offset PPC_MIN_STKFRM
 	PPC_STL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
+  .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF
 #ifdef __powerpc64__
 	PPC_STL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
+  .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
 #endif
 	get_datapage	r5
 	.ifeq	\call_time
@@ -39,13 +42,15 @@
 	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
 #ifdef __powerpc64__
 	PPC_LL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
+  .cfi_restore r2
 #endif
 	.ifeq	\call_time
 	cmpwi		r3, 0
 	.endif
 	mtlr		r0
-  .cfi_restore lr
 	addi		r1, r1, 2 * PPC_MIN_STKFRM
+  .cfi_restore lr
+  .cfi_def_cfa_offset 0
 	crclr		so
 	.ifeq	\call_time
 	beqlr+
Signature · 1 line
2.35.1
author maintainer
#139 lore raw

PATCH 136/230 serial: 8250_mtk: Make sure to select the right FEATURE_SEL

In reply to Greg Kroah-Hartman

From: AngeloGioacchino Del Regno <[email protected]>

[ Upstream commit 6f81fdded0d024c7d4084d434764f30bca1cd6b1 ]

Set the FEATURE_SEL at probe time to make sure that BIT(0) is enabled:
this guarantees that when the port is configured as AP UART, the right register layout is interpreted by the UART IP.

---
 drivers/tty/serial/8250/8250_mtk.c | 7 +++++++
 1 file changed, 7 insertions(+)
drivers/tty/serial/8250/8250_mtk.c +7 -0
index de48a58460f4..de57f47635cd 100644
@@ -57,6 +57,9 @@
 #define MTK_UART_XON1		40	/* I/O: Xon character 1 */
 #define MTK_UART_XOFF1		42	/* I/O: Xoff character 1 */
 
+#define MTK_UART_FEATURE_SEL	39	/* Feature Selection register */
+#define MTK_UART_FEAT_NEWRMAP	BIT(0)	/* Use new register map */
+
 #ifdef CONFIG_SERIAL_8250_DMA
 enum dma_rx_status {
 	DMA_RX_START = 0,
@@ -572,6 +575,10 @@ static int mtk8250_probe(struct platform_device *pdev)
 		uart.dma = data->dma;
 #endif
 
+	/* Set AP UART new register map */
+	writel(MTK_UART_FEAT_NEWRMAP, uart.port.membase +
+	       (MTK_UART_FEATURE_SEL << uart.port.regshift));
+
 	/* Disable Rate Fix function */
 	writel(0x0, uart.port.membase +
 			(MTK_UART_RATE_FIX << uart.port.regshift));
Signature · 1 line
2.35.1
author maintainer
#140 lore raw

PATCH 137/230 tty: n_gsm: fix invalid gsmtty_write_room() result

In reply to Greg Kroah-Hartman

From: Daniel Starke <[email protected]>

[ Upstream commit 9361ebfbb79fd1bc8594a487c01ad52cdaa391ea ]

gsmtty_write() does not prevent the user to use the full fifo size of 4096 bytes as allocated in gsm_dlci_alloc(). However, gsmtty_write_room() tries to limit the return value by 'TX_SIZE' and returns a negative value if the fifo has more than 'TX_SIZE' bytes stored. This is obviously wrong as 'TX_SIZE' is defined as 512.
Define 'TX_SIZE' to the fifo size and use it accordingly for allocation to keep the current behavior. Return the correct remaining size of the fifo in gsmtty_write_room() via kfifo_avail().

---
 drivers/tty/n_gsm.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/tty/n_gsm.c +3 -4
index fd4a86111a6e..4a430f6ca170 100644
@@ -137,6 +137,7 @@ struct gsm_dlci {
 	int retries;
 	/* Uplink tty if active */
 	struct tty_port port;	/* The tty bound to this DLCI if there is one */
+#define TX_SIZE		4096    /* Must be power of 2. */
 	struct kfifo fifo;	/* Queue fifo for the DLCI */
 	int adaption;		/* Adaption layer in use */
 	int prev_adaption;
@@ -1758,7 +1759,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr)
 		return NULL;
 	spin_lock_init(&dlci->lock);
 	mutex_init(&dlci->mutex);
-	if (kfifo_alloc(&dlci->fifo, 4096, GFP_KERNEL) < 0) {
+	if (kfifo_alloc(&dlci->fifo, TX_SIZE, GFP_KERNEL) < 0) {
 		kfree(dlci);
 		return NULL;
 	}
@@ -3035,8 +3036,6 @@ static struct tty_ldisc_ops tty_ldisc_packet = {
  *	Virtual tty side
  */
 
-#define TX_SIZE		512
-
 /**
  *	gsm_modem_upd_via_data	-	send modem bits via convergence layer
  *	@dlci: channel
@@ -3274,7 +3273,7 @@ static unsigned int gsmtty_write_room(struct tty_struct *tty)
 	struct gsm_dlci *dlci = tty->driver_data;
 	if (dlci->state == DLCI_CLOSED)
 		return 0;
-	return TX_SIZE - kfifo_len(&dlci->fifo);
+	return kfifo_avail(&dlci->fifo);
 }
 
 static unsigned int gsmtty_chars_in_buffer(struct tty_struct *tty)
Signature · 1 line
2.35.1
author maintainer
#141 lore raw

PATCH 138/230 drm/amdgpu: bind to any 0x1002 PCI diplay class device

In reply to Greg Kroah-Hartman

From: Alex Deucher <[email protected]>

[ Upstream commit eb4fd29afd4aa1c98d882800ceeee7d1f5262803 ]

Bind to all 0x1002 GPU devices.

For now we explicitly return -ENODEV for generic bindings. Remove this check once IP discovery based checking is in place.

v2: rebase (Alex)

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +15 -0
index f65b4b233ffb..c294081022bd 100644
@@ -1952,6 +1952,16 @@ static const struct pci_device_id pciidlist[] = {
 	{0x1002, 0x7424, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
 	{0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
 
+	{ PCI_DEVICE(0x1002, PCI_ANY_ID),
+	  .class = PCI_CLASS_DISPLAY_VGA << 8,
+	  .class_mask = 0xffffff,
+	  .driver_data = 0 },
+
+	{ PCI_DEVICE(0x1002, PCI_ANY_ID),
+	  .class = PCI_CLASS_DISPLAY_OTHER << 8,
+	  .class_mask = 0xffffff,
+	  .driver_data = 0 },
+
 	{0, 0, 0}
 };
 
@@ -1999,6 +2009,11 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
 			return -ENODEV;
 	}
 
+	if (flags == 0) {
+		DRM_INFO("Unsupported asic.  Remove me when IP discovery init is in place.\n");
+		return -ENODEV;
+	}
+
 	if (amdgpu_virtual_display ||
 	    amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
 		supports_atomic = true;
Signature · 1 line
2.35.1
#142 lore raw

Re: [PATCH 5.15 138/230] drm/amdgpu: bind to any 0x1002 PCI diplay class device

Hi Greg & Alex

why is that patch picked up for stable? Or are we backporting IP based discovery?

If yes, is that wise? IIRC we had quite a number of typos etc.. in the initial patches.

Regards,
Christian.

Am 11.07.22 um 11:06 schrieb Greg Kroah-Hartman:

Quoted 51 lines

From: Alex Deucher <[email protected]>

[ Upstream commit eb4fd29afd4aa1c98d882800ceeee7d1f5262803 ]

Bind to all 0x1002 GPU devices.

For now we explicitly return -ENODEV for generic bindings. Remove this check once IP discovery based checking is in place.

v2: rebase (Alex)

---
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 15 +++++++++++++++
  1 file changed, 15 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +15 -0
index f65b4b233ffb..c294081022bd 100644
@@ -1952,6 +1952,16 @@ static const struct pci_device_id pciidlist[] = {
  	{0x1002, 0x7424, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
  	{0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
 
+	{ PCI_DEVICE(0x1002, PCI_ANY_ID),
+	  .class = PCI_CLASS_DISPLAY_VGA << 8,
+	  .class_mask = 0xffffff,
+	  .driver_data = 0 },
+
+	{ PCI_DEVICE(0x1002, PCI_ANY_ID),
+	  .class = PCI_CLASS_DISPLAY_OTHER << 8,
+	  .class_mask = 0xffffff,
+	  .driver_data = 0 },
+
  	{0, 0, 0}
  };
 
@@ -1999,6 +2009,11 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
  			return -ENODEV;
  	}
 
+	if (flags == 0) {
+		DRM_INFO("Unsupported asic.  Remove me when IP discovery init is in place.\n");
+		return -ENODEV;
+	}
+
  	if (amdgpu_virtual_display ||
  	    amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
  		supports_atomic = true;
author maintainer
#143 lore raw

Re: [PATCH 5.15 138/230] drm/amdgpu: bind to any 0x1002 PCI diplay class device

Quoted 4 lines · Christian König

Hi Greg & Alex

why is that patch picked up for stable? Or are we backporting IP based discovery?

New device ids are usually added to stable trees as they are "trivial".

Quoted 2 lines

If yes, is that wise? IIRC we had quite a number of typos etc.. in the initial patches.

If this commit is incorrect, we will be glad to drop it, or add any needed add-on commits. Which do you want to see happen here?

thanks,

greg k-h

#144 lore raw

Re: [PATCH 5.15 138/230] drm/amdgpu: bind to any 0x1002 PCI diplay class device

Am 11.07.22 um 11:37 schrieb Greg Kroah-Hartman:

Quoted 6 lines · Christian König
Quoted 4 lines

Hi Greg & Alex

why is that patch picked up for stable? Or are we backporting IP based discovery?

New device ids are usually added to stable trees as they are "trivial".

Ah! Ok, sounds like a misunderstanding.

For the background this is *not* a new device id, but rather changes the way the existing device ids are discovered.

Instead of a table with device ids and hard coded list of hw blocks inside a device, we now look at a VBIOS table to determine which hw version/blocks are present.

So yes, this might enable new hardware but it's most likely not trivial enough to be backported.

Quoted 4 lines
Quoted 2 lines

If yes, is that wise? IIRC we had quite a number of typos etc.. in the initial patches.

If this commit is incorrect, we will be glad to drop it, or add any needed add-on commits. Which do you want to see happen here?

Alex, that is mostly a question for you.

Thanks,
Christian.

Quoted 4 lines

thanks,

greg k-h

#145 lore raw

RE: [PATCH 5.15 138/230] drm/amdgpu: bind to any 0x1002 PCI diplay class device

In reply to Christian König

[Public]

Quoted 9 lines

-----Original Message-----
From: Koenig, Christian <[email protected]>
Sent: Monday, July 11, 2022 5:30 AM
To: Greg Kroah-Hartman <[email protected]>; Deucher, Alexander <[email protected]>; [email protected]
Cc: [email protected]; Sasha Levin <[email protected]>
Subject: Re: [PATCH 5.15 138/230] drm/amdgpu: bind to any 0x1002 PCI diplay class device

Quoted 5 lines

Hi Greg & Alex

why is that patch picked up for stable? Or are we backporting IP based discovery?

Looks like Sasha picked it up. This should not go to stable.

Alex

Quoted 61 lines

If yes, is that wise? IIRC we had quite a number of typos etc.. in the initial patches.

Regards,
Christian.

Am 11.07.22 um 11:06 schrieb Greg Kroah-Hartman:

drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c static int amdgpu_pci_probe(struct pci_dev

Quoted 41 lines

From: Alex Deucher <[email protected]>

[ Upstream commit eb4fd29afd4aa1c98d882800ceeee7d1f5262803 ]

Bind to all 0x1002 GPU devices.

For now we explicitly return -ENODEV for generic bindings. Remove this check once IP discovery based checking is in place.

v2: rebase (Alex)

---
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 15 +++++++++++++++
  1 file changed, 15 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +10 -0
index f65b4b233ffb..c294081022bd 100644
@@ -1952,6 +1952,16 @@ static const struct pci_device_id pciidlist[] = {
  	{0x1002, 0x7424, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
  	{0x1002, 0x743F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_BEIGE_GOBY},
 
+	{ PCI_DEVICE(0x1002, PCI_ANY_ID),
+	  .class = PCI_CLASS_DISPLAY_VGA << 8,
+	  .class_mask = 0xffffff,
+	  .driver_data = 0 },
+
+	{ PCI_DEVICE(0x1002, PCI_ANY_ID),
+	  .class = PCI_CLASS_DISPLAY_OTHER << 8,
+	  .class_mask = 0xffffff,
+	  .driver_data = 0 },
+
  	{0, 0, 0}
  };
 
@@ -1999,6 +2009,11 @@ static int amdgpu_pci_probe(struct pci_dev

*pdev,

drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c static int amdgpu_pci_probe(struct pci_dev *pdev,

Quoted 5 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +2 -0
  			return -ENODEV;
  	}
 
+	if (flags == 0) {
+		DRM_INFO("Unsupported asic.  Remove me when IP

discovery init is in place.\n");

Quoted 6 lines
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +3 -0
+		return -ENODEV;
+	}
+
  	if (amdgpu_virtual_display ||
  	    amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
  		supports_atomic = true;
author maintainer
#146 lore raw

Re: [PATCH 5.15 138/230] drm/amdgpu: bind to any 0x1002 PCI diplay class device

Quoted 11 lines · Alexander

[Public]

Quoted 9 lines

-----Original Message-----
From: Koenig, Christian <[email protected]>
Sent: Monday, July 11, 2022 5:30 AM
To: Greg Kroah-Hartman <[email protected]>; Deucher, Alexander <[email protected]>; [email protected]
Cc: [email protected]; Sasha Levin <[email protected]>
Subject: Re: [PATCH 5.15 138/230] drm/amdgpu: bind to any 0x1002 PCI diplay class device

Quoted 7 lines
Quoted 5 lines

Hi Greg & Alex

why is that patch picked up for stable? Or are we backporting IP based discovery?

Looks like Sasha picked it up. This should not go to stable.

Ok, will go and drop it now, thanks for letting us know.

greg k-h

author maintainer
#147 lore raw

PATCH 139/230 drm/amdgpu: Fix rejecting Tahiti GPUs

In reply to Greg Kroah-Hartman

From: Lukas Fink <[email protected]>

[ Upstream commit 3993a799fc971bc9b918bd969aa55864447b5dde ] [ Upstream commit 5f0754ab2751d1935818459e8e71a8fe26f6403c ]

eb4fd29afd4a ("drm/amdgpu: bind to any 0x1002 PCI diplay class device") added generic bindings to amdgpu so that that it binds to all display class devices with VID 0x1002 and then rejects those in amdgpu_pci_probe.

Unfortunately it reuses a driver_data value of 0 to detect those new bindings, which is already used to denote CHIP_TAHITI ASICs.

The driver_data value given to those new bindings was changed in dd0761fd24ea1 ("drm/amdgpu: set CHIP_IP_DISCOVERY as the asic type by default") to CHIP_IP_DISCOVERY (=36), but it seems that the check in amdgpu_pci_probe was forgotten to be changed. Therefore, it still rejects Tahiti GPUs.

Fixes eb4fd29afd4a ("drm/amdgpu: bind to any 0x1002 PCI diplay class device")
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +1 -1
@@ -2009,7 +2009,7 @@ static int amdgpu_pci_probe(struct pci_d
 			return -ENODEV;
 	}
 
-	if (flags == 0) {
+	if (flags == CHIP_IP_DISCOVERY) {
 		DRM_INFO("Unsupported asic.  Remove me when IP discovery init is in place.\n");
 		return -ENODEV;
 	}
author maintainer
#148 lore raw

PATCH 140/230 drm/amdgpu: drop flags check for CHIP_IP_DISCOVERY

In reply to Greg Kroah-Hartman

From: Alex Deucher <[email protected]>

[ Upstream commit d82ce3cd30aa28db3e94ffc36ebf0af2ff12801d ]

Support for IP based discovery is in place now so this check is no longer required.

---
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 5 -----
 1 file changed, 5 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +0 -5
index cb0b5972e7fd..a0dd4b41ba4a 100644
@@ -2009,11 +2009,6 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
 			return -ENODEV;
 	}
 
-	if (flags == CHIP_IP_DISCOVERY) {
-		DRM_INFO("Unsupported asic.  Remove me when IP discovery init is in place.\n");
-		return -ENODEV;
-	}
-
 	if (amdgpu_virtual_display ||
 	    amdgpu_device_asic_has_dc_support(flags & AMD_ASIC_MASK))
 		supports_atomic = true;
Signature · 1 line
2.35.1
author maintainer
#149 lore raw

PATCH 141/230 drm/amd: Refactor `amdgpu_aspm` to be evaluated per device

In reply to Greg Kroah-Hartman

From: Mario Limonciello <[email protected]>

[ Upstream commit 0ab5d711ec74d9e60673900974806b7688857947 ]

Evaluating pcie_aspm_enabled as part of driver probe has the implication that if one PCIe bridge with an AMD GPU connected doesn't support ASPM then none of them do. This is an invalid assumption as the PCIe core will configure ASPM for individual PCIe bridges.

Create a new helper function that can be called by individual dGPUs to react to the amdgpu_aspm module parameter without having negative results for other dGPUs on the PCIe bus.

---
 drivers/gpu/drm/amd/amdgpu/amdgpu.h           |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 25 +++++++++++++++++++
 drivers/gpu/drm/amd/amdgpu/cik.c              |  2 +-
 drivers/gpu/drm/amd/amdgpu/nv.c               |  2 +-
 drivers/gpu/drm/amd/amdgpu/si.c               |  2 +-
 drivers/gpu/drm/amd/amdgpu/soc15.c            |  2 +-
 drivers/gpu/drm/amd/amdgpu/vi.c               |  2 +-
 .../amd/pm/swsmu/smu11/sienna_cichlid_ppt.c   |  2 +-
 8 files changed, 32 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu.h +1 -0
index 2eebefd26fa8..5f95d03fd46a 100644
@@ -1285,6 +1285,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
 void amdgpu_device_pci_config_reset(struct amdgpu_device *adev);
 int amdgpu_device_pci_reset(struct amdgpu_device *adev);
 bool amdgpu_device_need_post(struct amdgpu_device *adev);
+bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev);
 
 void amdgpu_cs_report_moved_bytes(struct amdgpu_device *adev, u64 num_bytes,
 				  u64 num_vis_bytes);
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +25 -0
index a926b5ebbfdf..d1af709cc7dc 100644
@@ -1309,6 +1309,31 @@ bool amdgpu_device_need_post(struct amdgpu_device *adev)
 	return true;
 }
 
+/**
+ * amdgpu_device_should_use_aspm - check if the device should program ASPM
+ *
+ * @adev: amdgpu_device pointer
+ *
+ * Confirm whether the module parameter and pcie bridge agree that ASPM should
+ * be set for this device.
+ *
+ * Returns true if it should be used or false if not.
+ */
+bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev)
+{
+	switch (amdgpu_aspm) {
+	case -1:
+		break;
+	case 0:
+		return false;
+	case 1:
+		return true;
+	default:
+		return false;
+	}
+	return pcie_aspm_enabled(adev->pdev);
+}
+
 /* if we get transitioned to only one device, take VGA back */
 /**
  * amdgpu_device_vga_set_decode - enable/disable vga decode
drivers/gpu/drm/amd/amdgpu/cik.c +1 -1
index f10ce740a29c..de6d10390ab2 100644
@@ -1719,7 +1719,7 @@ static void cik_program_aspm(struct amdgpu_device *adev)
 	bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
 	bool disable_clkreq = false;
 
-	if (amdgpu_aspm == 0)
+	if (!amdgpu_device_should_use_aspm(adev))
 		return;
 
 	if (pci_is_root_bus(adev->pdev->bus))
drivers/gpu/drm/amd/amdgpu/nv.c +1 -1
index 9cbed9a8f1c0..6e277236b44f 100644
@@ -584,7 +584,7 @@ static void nv_pcie_gen3_enable(struct amdgpu_device *adev)
 
 static void nv_program_aspm(struct amdgpu_device *adev)
 {
-	if (!amdgpu_aspm)
+	if (!amdgpu_device_should_use_aspm(adev))
 		return;
 
 	if (!(adev->flags & AMD_IS_APU) &&
drivers/gpu/drm/amd/amdgpu/si.c +1 -1
index e6d2f74a7976..7f99e130acd0 100644
@@ -2453,7 +2453,7 @@ static void si_program_aspm(struct amdgpu_device *adev)
 	bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
 	bool disable_clkreq = false;
 
-	if (amdgpu_aspm == 0)
+	if (!amdgpu_device_should_use_aspm(adev))
 		return;
 
 	if (adev->flags & AMD_IS_APU)
drivers/gpu/drm/amd/amdgpu/soc15.c +1 -1
index 6439d5c3d8d8..bdb47ae96ce6 100644
@@ -689,7 +689,7 @@ static void soc15_pcie_gen3_enable(struct amdgpu_device *adev)
 
 static void soc15_program_aspm(struct amdgpu_device *adev)
 {
-	if (!amdgpu_aspm)
+	if (!amdgpu_device_should_use_aspm(adev))
 		return;
 
 	if (!(adev->flags & AMD_IS_APU) &&
drivers/gpu/drm/amd/amdgpu/vi.c +1 -1
index 6645ebbd2696..039b90cdc3bc 100644
@@ -1140,7 +1140,7 @@ static void vi_program_aspm(struct amdgpu_device *adev)
 	bool bL1SS = false;
 	bool bClkReqSupport = true;
 
-	if (!amdgpu_aspm)
+	if (!amdgpu_device_should_use_aspm(adev))
 		return;
 
 	if (adev->flags & AMD_IS_APU ||
drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +1 -1
index 574a9d7f7a5e..918d5c7c2328 100644
@@ -338,7 +338,7 @@ sienna_cichlid_get_allowed_feature_mask(struct smu_context *smu,
 	if (smu->dc_controlled_by_gpio)
        *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ACDC_BIT);
 
-	if (amdgpu_aspm)
+	if (amdgpu_device_should_use_aspm(adev))
 		*(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_LCLK_BIT);
 
 	return 0;
Signature · 1 line
2.35.1
author maintainer
#150 lore raw

PATCH 142/230 drm/amdgpu: vi: disable ASPM on Intel Alder Lake based systems

In reply to Greg Kroah-Hartman

From: Richard Gong <[email protected]>

[ Upstream commit aa482ddca85a3485be0e7b83a0789dc4d987670b ]

Active State Power Management (ASPM) feature is enabled since kernel 5.14. There are some AMD Volcanic Islands (VI) GFX cards, such as the WX3200 and RX640, that do not work with ASPM-enabled Intel Alder Lake based systems. Using these GFX cards as video/display output, Intel Alder Lake based systems will freeze after suspend/resume.

The issue was originally reported on one system (Dell Precision 3660 with BIOS version 0.14.81), but was later confirmed to affect at least 4 pre-production Alder Lake based systems.

Add an extra check to disable ASPM on Intel Alder Lake based systems with the problematic AMD Volcanic Islands GFX cards.

---
 drivers/gpu/drm/amd/amdgpu/vi.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/vi.c +16 -1
index 039b90cdc3bc..45f0188c4273 100644
@@ -81,6 +81,10 @@
 #include "mxgpu_vi.h"
 #include "amdgpu_dm.h"
 
+#if IS_ENABLED(CONFIG_X86)
+#include <asm/intel-family.h>
+#endif
+
 #define ixPCIE_LC_L1_PM_SUBSTATE	0x100100C6
 #define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK	0x00000001L
 #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK	0x00000002L
@@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct amdgpu_device *adev)
 		WREG32_PCIE(ixPCIE_LC_CNTL, data);
 }
 
+static bool aspm_support_quirk_check(void)
+{
+#if IS_ENABLED(CONFIG_X86)
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE);
+#else
+	return true;
+#endif
+}
+
 static void vi_program_aspm(struct amdgpu_device *adev)
 {
 	u32 data, data1, orig;
 	bool bL1SS = false;
 	bool bClkReqSupport = true;
 
-	if (!amdgpu_device_should_use_aspm(adev))
+	if (!amdgpu_device_should_use_aspm(adev) || !aspm_support_quirk_check())
 		return;
 
 	if (adev->flags & AMD_IS_APU ||
Signature · 1 line
2.35.1
author maintainer
#151 lore raw

PATCH 143/230 drm/i915: Fix a race between vma / object destruction and unbinding

In reply to Greg Kroah-Hartman

From: Thomas Hellström <[email protected]>

[ Upstream commit bc1922e5d349db4be14c55513102c024c2ae8a50 ]

The vma destruction code was using an unlocked advisory check for drm_mm_node_allocated() to avoid racing with eviction code unbinding the vma.

This is very fragile and prohibits the dereference of non-refcounted pointers of dying vmas after a call to __i915_vma_unbind(). It also prohibits the dereference of vma->obj of refcounted pointers of dying vmas after a call to __i915_vma_unbind(), since even if a refcount is held on the vma, that won't guarantee that its backing object doesn't get destroyed.

So introduce an unbind under the vm mutex at object destroy time, removing all weak references of the vma and its object from the object vma list and from the vm bound list.

---
 drivers/gpu/drm/i915/gem/i915_gem_object.c | 6 ++++++
 1 file changed, 6 insertions(+)
drivers/gpu/drm/i915/gem/i915_gem_object.c +6 -0
index 6fb9afb65034..5f48d5ea5c15 100644
@@ -224,6 +224,12 @@ void __i915_gem_free_object(struct drm_i915_gem_object *obj)
 			GEM_BUG_ON(vma->obj != obj);
 			spin_unlock(&obj->vma.lock);
 
+			/* Verify that the vma is unbound under the vm mutex. */
+			mutex_lock(&vma->vm->mutex);
+			atomic_and(~I915_VMA_PIN_MASK, &vma->flags);
+			__i915_vma_unbind(vma);
+			mutex_unlock(&vma->vm->mutex);
+
 			__i915_vma_put(vma);
 
 			spin_lock(&obj->vma.lock);
Signature · 1 line
2.35.1
author maintainer
#152 lore raw

PATCH 144/230 drm/mediatek: Use mailbox rx_callback instead of cmdq_task_cb

In reply to Greg Kroah-Hartman

From: Chun-Kuang Hu <[email protected]>

[ Upstream commit 1ee07a683b7e4e6ad9ad4f77fce4751741bc8ceb ]

rx_callback is a standard mailbox callback mechanism and could cover the function of proprietary cmdq_task_cb, so use the standard one instead of the proprietary one.

---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_crtc.c +13 -3
index a4e80e499674..369d3e68c0b6 100644
@@ -4,6 +4,8 @@
  */
 
 #include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/mailbox_controller.h>
 #include <linux/pm_runtime.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
 #include <linux/soc/mediatek/mtk-mmsys.h>
@@ -222,9 +224,11 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
 }
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-static void ddp_cmdq_cb(struct cmdq_cb_data data)
+static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 {
-	cmdq_pkt_destroy(data.data);
+	struct cmdq_cb_data *data = mssg;
+
+	cmdq_pkt_destroy(data->pkt);
 }
 #endif
 
@@ -475,7 +479,12 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 		cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
 		mtk_crtc_ddp_config(crtc, cmdq_handle);
 		cmdq_pkt_finalize(cmdq_handle);
-		cmdq_pkt_flush_async(cmdq_handle, ddp_cmdq_cb, cmdq_handle);
+		dma_sync_single_for_device(mtk_crtc->cmdq_client->chan->mbox->dev,
+					   cmdq_handle->pa_base,
+					   cmdq_handle->cmd_buf_size,
+					   DMA_TO_DEVICE);
+		mbox_send_message(mtk_crtc->cmdq_client->chan, cmdq_handle);
+		mbox_client_txdone(mtk_crtc->cmdq_client->chan, 0);
 	}
 #endif
 	mtk_crtc->config_updating = false;
@@ -839,6 +848,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	}
 
 	if (mtk_crtc->cmdq_client) {
+		mtk_crtc->cmdq_client->client.rx_callback = ddp_cmdq_cb;
 		ret = of_property_read_u32_index(priv->mutex_node,
 						 "mediatek,gce-events",
 						 drm_crtc_index(&mtk_crtc->base),
Signature · 1 line
2.35.1
author maintainer
#153 lore raw

PATCH 145/230 drm/mediatek: Remove the pointer of struct cmdq_client

In reply to Greg Kroah-Hartman

From: Chun-Kuang Hu <[email protected]>

[ Upstream commit 563c9d4a5b117552150efbecbaf0877947e98a32 ]

In mailbox rx_callback, it pass struct mbox_client to callback function, but it could not map back to mtk_drm_crtc instance because struct cmdq_client use a pointer to struct mbox_client:

struct cmdq_client {
	struct mbox_client client;
	struct mbox_chan *chan;
};
struct mtk_drm_crtc {
	/* client instance data */
	struct cmdq_client *cmdq_client;
};

so remove the pointer of struct cmdq_client and let mtk_drm_crtc instance define cmdq_client as:

struct mtk_drm_crtc {
	/* client instance data */
	struct cmdq_client cmdq_client;
};

and in rx_callback function, use struct mbox_client to get struct mtk_drm_crtc.

---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 37 +++++++++++++------------
 1 file changed, 20 insertions(+), 17 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_crtc.c +20 -17
index 369d3e68c0b6..e23e3224ac67 100644
@@ -52,7 +52,7 @@ struct mtk_drm_crtc {
 	bool				pending_async_planes;
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	struct cmdq_client		*cmdq_client;
+	struct cmdq_client		cmdq_client;
 	u32				cmdq_event;
 #endif
 
@@ -472,19 +472,19 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 		mtk_mutex_release(mtk_crtc->mutex);
 	}
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	if (mtk_crtc->cmdq_client) {
-		mbox_flush(mtk_crtc->cmdq_client->chan, 2000);
-		cmdq_handle = cmdq_pkt_create(mtk_crtc->cmdq_client, PAGE_SIZE);
+	if (mtk_crtc->cmdq_client.chan) {
+		mbox_flush(mtk_crtc->cmdq_client.chan, 2000);
+		cmdq_handle = cmdq_pkt_create(&mtk_crtc->cmdq_client, PAGE_SIZE);
 		cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
 		cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
 		mtk_crtc_ddp_config(crtc, cmdq_handle);
 		cmdq_pkt_finalize(cmdq_handle);
-		dma_sync_single_for_device(mtk_crtc->cmdq_client->chan->mbox->dev,
+		dma_sync_single_for_device(mtk_crtc->cmdq_client.chan->mbox->dev,
 					   cmdq_handle->pa_base,
 					   cmdq_handle->cmd_buf_size,
 					   DMA_TO_DEVICE);
-		mbox_send_message(mtk_crtc->cmdq_client->chan, cmdq_handle);
-		mbox_client_txdone(mtk_crtc->cmdq_client->chan, 0);
+		mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
+		mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
 	}
 #endif
 	mtk_crtc->config_updating = false;
@@ -498,7 +498,7 @@ static void mtk_crtc_ddp_irq(void *data)
 	struct mtk_drm_private *priv = crtc->dev->dev_private;
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client)
+	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
 #else
 	if (!priv->data->shadow_register)
 #endif
@@ -838,17 +838,20 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 	mutex_init(&mtk_crtc->hw_lock);
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	mtk_crtc->cmdq_client =
-			cmdq_mbox_create(mtk_crtc->mmsys_dev,
-					 drm_crtc_index(&mtk_crtc->base));
-	if (IS_ERR(mtk_crtc->cmdq_client)) {
+	mtk_crtc->cmdq_client.client.dev = mtk_crtc->mmsys_dev;
+	mtk_crtc->cmdq_client.client.tx_block = false;
+	mtk_crtc->cmdq_client.client.knows_txdone = true;
+	mtk_crtc->cmdq_client.client.rx_callback = ddp_cmdq_cb;
+	mtk_crtc->cmdq_client.chan =
+			mbox_request_channel(&mtk_crtc->cmdq_client.client,
+					     drm_crtc_index(&mtk_crtc->base));
+	if (IS_ERR(mtk_crtc->cmdq_client.chan)) {
 		dev_dbg(dev, "mtk_crtc %d failed to create mailbox client, writing register by CPU now\n",
 			drm_crtc_index(&mtk_crtc->base));
-		mtk_crtc->cmdq_client = NULL;
+		mtk_crtc->cmdq_client.chan = NULL;
 	}
 
-	if (mtk_crtc->cmdq_client) {
-		mtk_crtc->cmdq_client->client.rx_callback = ddp_cmdq_cb;
+	if (mtk_crtc->cmdq_client.chan) {
 		ret = of_property_read_u32_index(priv->mutex_node,
 						 "mediatek,gce-events",
 						 drm_crtc_index(&mtk_crtc->base),
@@ -856,8 +859,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 		if (ret) {
 			dev_dbg(dev, "mtk_crtc %d failed to get mediatek,gce-events property\n",
 				drm_crtc_index(&mtk_crtc->base));
-			cmdq_mbox_destroy(mtk_crtc->cmdq_client);
-			mtk_crtc->cmdq_client = NULL;
+			mbox_free_channel(mtk_crtc->cmdq_client.chan);
+			mtk_crtc->cmdq_client.chan = NULL;
 		}
 	}
 #endif
Signature · 1 line
2.35.1
author maintainer
#154 lore raw

PATCH 146/230 drm/mediatek: Detect CMDQ execution timeout

In reply to Greg Kroah-Hartman

From: Chun-Kuang Hu <[email protected]>

[ Upstream commit eaf80126aba6fd1754837eec91e4c8bbd58ae52e ]

CMDQ is used to update display register in vblank period, so it should be execute in next 2 vblank. One vblank interrupt before send message (occasionally) and one vblank interrupt after cmdq done. If it fail to execute in next 3 vblank, tiemout happen.

---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_crtc.c +18 -2
index e23e3224ac67..dad1f85ee315 100644
@@ -54,6 +54,7 @@ struct mtk_drm_crtc {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	struct cmdq_client		cmdq_client;
 	u32				cmdq_event;
+	u32				cmdq_vblank_cnt;
 #endif
 
 	struct device			*mmsys_dev;
@@ -227,7 +228,10 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
 static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 {
 	struct cmdq_cb_data *data = mssg;
+	struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, client);
+	struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
 
+	mtk_crtc->cmdq_vblank_cnt = 0;
 	cmdq_pkt_destroy(data->pkt);
 }
 #endif
@@ -483,6 +487,15 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 					   cmdq_handle->pa_base,
 					   cmdq_handle->cmd_buf_size,
 					   DMA_TO_DEVICE);
+		/*
+		 * CMDQ command should execute in next 3 vblank.
+		 * One vblank interrupt before send message (occasionally)
+		 * and one vblank interrupt after cmdq done,
+		 * so it's timeout after 3 vblank interrupt.
+		 * If it fail to execute in next 3 vblank, timeout happen.
+		 */
+		mtk_crtc->cmdq_vblank_cnt = 3;
+
 		mbox_send_message(mtk_crtc->cmdq_client.chan, cmdq_handle);
 		mbox_client_txdone(mtk_crtc->cmdq_client.chan, 0);
 	}
@@ -499,11 +512,14 @@ static void mtk_crtc_ddp_irq(void *data)
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (!priv->data->shadow_register && !mtk_crtc->cmdq_client.chan)
+		mtk_crtc_ddp_config(crtc, NULL);
+	else if (mtk_crtc->cmdq_vblank_cnt > 0 && --mtk_crtc->cmdq_vblank_cnt == 0)
+		DRM_ERROR("mtk_crtc %d CMDQ execute command timeout!\n",
+			  drm_crtc_index(&mtk_crtc->base));
 #else
 	if (!priv->data->shadow_register)
-#endif
 		mtk_crtc_ddp_config(crtc, NULL);
-
+#endif
 	mtk_drm_finish_page_flip(mtk_crtc);
 }
 
Signature · 1 line
2.35.1
author maintainer
#155 lore raw

PATCH 147/230 drm/mediatek: Add cmdq_handle in mtk_crtc

In reply to Greg Kroah-Hartman

From: Chun-Kuang Hu <[email protected]>

[ Upstream commit 7627122fd1c06800a1fe624e9fb3c269796115e8 ]

One mtk_crtc need just one cmdq_handle, so add one cmdq_handle in mtk_crtc to prevent frequently allocation and free of cmdq_handle.

---
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c | 62 +++++++++++++++++++++++--
 1 file changed, 57 insertions(+), 5 deletions(-)
drivers/gpu/drm/mediatek/mtk_drm_crtc.c +57 -5
index dad1f85ee315..ffa54b416ca7 100644
@@ -53,6 +53,7 @@ struct mtk_drm_crtc {
 
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	struct cmdq_client		cmdq_client;
+	struct cmdq_pkt			cmdq_handle;
 	u32				cmdq_event;
 	u32				cmdq_vblank_cnt;
 #endif
@@ -107,12 +108,55 @@ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
 	}
 }
 
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+static int mtk_drm_cmdq_pkt_create(struct cmdq_client *client, struct cmdq_pkt *pkt,
+				   size_t size)
+{
+	struct device *dev;
+	dma_addr_t dma_addr;
+
+	pkt->va_base = kzalloc(size, GFP_KERNEL);
+	if (!pkt->va_base) {
+		kfree(pkt);
+		return -ENOMEM;
+	}
+	pkt->buf_size = size;
+	pkt->cl = (void *)client;
+
+	dev = client->chan->mbox->dev;
+	dma_addr = dma_map_single(dev, pkt->va_base, pkt->buf_size,
+				  DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, dma_addr)) {
+		dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size);
+		kfree(pkt->va_base);
+		kfree(pkt);
+		return -ENOMEM;
+	}
+
+	pkt->pa_base = dma_addr;
+
+	return 0;
+}
+
+static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
+{
+	struct cmdq_client *client = (struct cmdq_client *)pkt->cl;
+
+	dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size,
+			 DMA_TO_DEVICE);
+	kfree(pkt->va_base);
+	kfree(pkt);
+}
+#endif
+
 static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 
 	mtk_mutex_put(mtk_crtc->mutex);
-
+#if IS_REACHABLE(CONFIG_MTK_CMDQ)
+	mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
+#endif
 	drm_crtc_cleanup(crtc);
 }
 
@@ -227,12 +271,10 @@ struct mtk_ddp_comp *mtk_drm_ddp_comp_for_plane(struct drm_crtc *crtc,
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 static void ddp_cmdq_cb(struct mbox_client *cl, void *mssg)
 {
-	struct cmdq_cb_data *data = mssg;
 	struct cmdq_client *cmdq_cl = container_of(cl, struct cmdq_client, client);
 	struct mtk_drm_crtc *mtk_crtc = container_of(cmdq_cl, struct mtk_drm_crtc, cmdq_client);
 
 	mtk_crtc->cmdq_vblank_cnt = 0;
-	cmdq_pkt_destroy(data->pkt);
 }
 #endif
 
@@ -438,7 +480,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 				       bool needs_vblank)
 {
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
-	struct cmdq_pkt *cmdq_handle;
+	struct cmdq_pkt *cmdq_handle = &mtk_crtc->cmdq_handle;
 #endif
 	struct drm_crtc *crtc = &mtk_crtc->base;
 	struct mtk_drm_private *priv = crtc->dev->dev_private;
@@ -478,7 +520,7 @@ static void mtk_drm_crtc_update_config(struct mtk_drm_crtc *mtk_crtc,
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	if (mtk_crtc->cmdq_client.chan) {
 		mbox_flush(mtk_crtc->cmdq_client.chan, 2000);
-		cmdq_handle = cmdq_pkt_create(&mtk_crtc->cmdq_client, PAGE_SIZE);
+		cmdq_handle->cmd_buf_size = 0;
 		cmdq_pkt_clear_event(cmdq_handle, mtk_crtc->cmdq_event);
 		cmdq_pkt_wfe(cmdq_handle, mtk_crtc->cmdq_event, false);
 		mtk_crtc_ddp_config(crtc, cmdq_handle);
@@ -877,6 +919,16 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 				drm_crtc_index(&mtk_crtc->base));
 			mbox_free_channel(mtk_crtc->cmdq_client.chan);
 			mtk_crtc->cmdq_client.chan = NULL;
+		} else {
+			ret = mtk_drm_cmdq_pkt_create(&mtk_crtc->cmdq_client,
+						      &mtk_crtc->cmdq_handle,
+						      PAGE_SIZE);
+			if (ret) {
+				dev_dbg(dev, "mtk_crtc %d failed to create cmdq packet\n",
+					drm_crtc_index(&mtk_crtc->base));
+				mbox_free_channel(mtk_crtc->cmdq_client.chan);
+				mtk_crtc->cmdq_client.chan = NULL;
+			}
 		}
 	}
 #endif
Signature · 1 line
2.35.1
author maintainer
#156 lore raw

PATCH 148/230 drm/mediatek: Add vblank register/unregister callback functions

In reply to Greg Kroah-Hartman

From: Rex-BC Chen <[email protected]>

[ Upstream commit b74d921b900b6ce38c6247c0a1c86be9f3746493 ]

We encountered a kernel panic issue that callback data will be NULL when it's using in ovl irq handler. There is a timing issue between mtk_disp_ovl_irq_handler() and mtk_ovl_disable_vblank().

To resolve this issue, we use the flow to register/unregister vblank cb:
- Register callback function and callback data when crtc creates.
- Unregister callback function and callback data when crtc destroies.

With this solution, we can assure callback data will not be NULL when vblank is disable.

---
 drivers/gpu/drm/mediatek/mtk_disp_drv.h     | 16 +++++++-----
 drivers/gpu/drm/mediatek/mtk_disp_ovl.c     | 22 ++++++++++++----
 drivers/gpu/drm/mediatek/mtk_disp_rdma.c    | 20 +++++++++-----
 drivers/gpu/drm/mediatek/mtk_drm_crtc.c     | 14 +++++++++-
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c |  4 +++
 drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h | 29 ++++++++++++++++-----
 6 files changed, 80 insertions(+), 25 deletions(-)
drivers/gpu/drm/mediatek/mtk_disp_drv.h +10 -6
index 86c3068894b1..974462831133 100644
@@ -76,9 +76,11 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx,
 void mtk_ovl_start(struct device *dev);
 void mtk_ovl_stop(struct device *dev);
 unsigned int mtk_ovl_supported_rotations(struct device *dev);
-void mtk_ovl_enable_vblank(struct device *dev,
-			   void (*vblank_cb)(void *),
-			   void *vblank_cb_data);
+void mtk_ovl_register_vblank_cb(struct device *dev,
+				void (*vblank_cb)(void *),
+				void *vblank_cb_data);
+void mtk_ovl_unregister_vblank_cb(struct device *dev);
+void mtk_ovl_enable_vblank(struct device *dev);
 void mtk_ovl_disable_vblank(struct device *dev);
 
 void mtk_rdma_bypass_shadow(struct device *dev);
@@ -93,9 +95,11 @@ void mtk_rdma_layer_config(struct device *dev, unsigned int idx,
 			   struct cmdq_pkt *cmdq_pkt);
 void mtk_rdma_start(struct device *dev);
 void mtk_rdma_stop(struct device *dev);
-void mtk_rdma_enable_vblank(struct device *dev,
-			    void (*vblank_cb)(void *),
-			    void *vblank_cb_data);
+void mtk_rdma_register_vblank_cb(struct device *dev,
+				 void (*vblank_cb)(void *),
+				 void *vblank_cb_data);
+void mtk_rdma_unregister_vblank_cb(struct device *dev);
+void mtk_rdma_enable_vblank(struct device *dev);
 void mtk_rdma_disable_vblank(struct device *dev);
 
 #endif
drivers/gpu/drm/mediatek/mtk_disp_ovl.c +17 -5
index 5326989d5206..411cf0f21661 100644
@@ -96,14 +96,28 @@ static irqreturn_t mtk_disp_ovl_irq_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-void mtk_ovl_enable_vblank(struct device *dev,
-			   void (*vblank_cb)(void *),
-			   void *vblank_cb_data)
+void mtk_ovl_register_vblank_cb(struct device *dev,
+				void (*vblank_cb)(void *),
+				void *vblank_cb_data)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 
 	ovl->vblank_cb = vblank_cb;
 	ovl->vblank_cb_data = vblank_cb_data;
+}
+
+void mtk_ovl_unregister_vblank_cb(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
+	ovl->vblank_cb = NULL;
+	ovl->vblank_cb_data = NULL;
+}
+
+void mtk_ovl_enable_vblank(struct device *dev)
+{
+	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
+
 	writel(0x0, ovl->regs + DISP_REG_OVL_INTSTA);
 	writel_relaxed(OVL_FME_CPL_INT, ovl->regs + DISP_REG_OVL_INTEN);
 }
@@ -112,8 +126,6 @@ void mtk_ovl_disable_vblank(struct device *dev)
 {
 	struct mtk_disp_ovl *ovl = dev_get_drvdata(dev);
 
-	ovl->vblank_cb = NULL;
-	ovl->vblank_cb_data = NULL;
 	writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN);
 }
 
drivers/gpu/drm/mediatek/mtk_disp_rdma.c +14 -6
index 75d7f45579e2..a6a6cb5f75af 100644
@@ -94,24 +94,32 @@ static void rdma_update_bits(struct device *dev, unsigned int reg,
 	writel(tmp, rdma->regs + reg);
 }
 
-void mtk_rdma_enable_vblank(struct device *dev,
-			    void (*vblank_cb)(void *),
-			    void *vblank_cb_data)
+void mtk_rdma_register_vblank_cb(struct device *dev,
+				 void (*vblank_cb)(void *),
+				 void *vblank_cb_data)
 {
 	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
 
 	rdma->vblank_cb = vblank_cb;
 	rdma->vblank_cb_data = vblank_cb_data;
-	rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
-			 RDMA_FRAME_END_INT);
 }
 
-void mtk_rdma_disable_vblank(struct device *dev)
+void mtk_rdma_unregister_vblank_cb(struct device *dev)
 {
 	struct mtk_disp_rdma *rdma = dev_get_drvdata(dev);
 
 	rdma->vblank_cb = NULL;
 	rdma->vblank_cb_data = NULL;
+}
+
+void mtk_rdma_enable_vblank(struct device *dev)
+{
+	rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT,
+			 RDMA_FRAME_END_INT);
+}
+
+void mtk_rdma_disable_vblank(struct device *dev)
+{
 	rdma_update_bits(dev, DISP_REG_RDMA_INT_ENABLE, RDMA_FRAME_END_INT, 0);
 }
 
drivers/gpu/drm/mediatek/mtk_drm_crtc.c +13 -1
index ffa54b416ca7..34bb6c713a90 100644
@@ -152,11 +152,20 @@ static void mtk_drm_cmdq_pkt_destroy(struct cmdq_pkt *pkt)
 static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
+	int i;
 
 	mtk_mutex_put(mtk_crtc->mutex);
 #if IS_REACHABLE(CONFIG_MTK_CMDQ)
 	mtk_drm_cmdq_pkt_destroy(&mtk_crtc->cmdq_handle);
 #endif
+
+	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
+		struct mtk_ddp_comp *comp;
+
+		comp = mtk_crtc->ddp_comp[i];
+		mtk_ddp_comp_unregister_vblank_cb(comp);
+	}
+
 	drm_crtc_cleanup(crtc);
 }
 
@@ -570,7 +579,7 @@ static int mtk_drm_crtc_enable_vblank(struct drm_crtc *crtc)
 	struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
 	struct mtk_ddp_comp *comp = mtk_crtc->ddp_comp[0];
 
-	mtk_ddp_comp_enable_vblank(comp, mtk_crtc_ddp_irq, &mtk_crtc->base);
+	mtk_ddp_comp_enable_vblank(comp);
 
 	return 0;
 }
@@ -870,6 +879,9 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
 			if (comp->funcs->ctm_set)
 				has_ctm = true;
 		}
+
+		mtk_ddp_comp_register_vblank_cb(comp, mtk_crtc_ddp_irq,
+						&mtk_crtc->base);
 	}
 
 	for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c +4 -0
index 99cbf44463e4..22d23668b484 100644
@@ -276,6 +276,8 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = {
 	.config = mtk_ovl_config,
 	.start = mtk_ovl_start,
 	.stop = mtk_ovl_stop,
+	.register_vblank_cb = mtk_ovl_register_vblank_cb,
+	.unregister_vblank_cb = mtk_ovl_unregister_vblank_cb,
 	.enable_vblank = mtk_ovl_enable_vblank,
 	.disable_vblank = mtk_ovl_disable_vblank,
 	.supported_rotations = mtk_ovl_supported_rotations,
@@ -292,6 +294,8 @@ static const struct mtk_ddp_comp_funcs ddp_rdma = {
 	.config = mtk_rdma_config,
 	.start = mtk_rdma_start,
 	.stop = mtk_rdma_stop,
+	.register_vblank_cb = mtk_rdma_register_vblank_cb,
+	.unregister_vblank_cb = mtk_rdma_unregister_vblank_cb,
 	.enable_vblank = mtk_rdma_enable_vblank,
 	.disable_vblank = mtk_rdma_disable_vblank,
 	.layer_nr = mtk_rdma_layer_nr,
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.h +22 -7
index bb914d976cf5..25cb50f2391f 100644
@@ -47,9 +47,11 @@ struct mtk_ddp_comp_funcs {
 		       unsigned int bpc, struct cmdq_pkt *cmdq_pkt);
 	void (*start)(struct device *dev);
 	void (*stop)(struct device *dev);
-	void (*enable_vblank)(struct device *dev,
-			      void (*vblank_cb)(void *),
-			      void *vblank_cb_data);
+	void (*register_vblank_cb)(struct device *dev,
+				   void (*vblank_cb)(void *),
+				   void *vblank_cb_data);
+	void (*unregister_vblank_cb)(struct device *dev);
+	void (*enable_vblank)(struct device *dev);
 	void (*disable_vblank)(struct device *dev);
 	unsigned int (*supported_rotations)(struct device *dev);
 	unsigned int (*layer_nr)(struct device *dev);
@@ -110,12 +112,25 @@ static inline void mtk_ddp_comp_stop(struct mtk_ddp_comp *comp)
 		comp->funcs->stop(comp->dev);
 }
 
-static inline void mtk_ddp_comp_enable_vblank(struct mtk_ddp_comp *comp,
-					      void (*vblank_cb)(void *),
-					      void *vblank_cb_data)
+static inline void mtk_ddp_comp_register_vblank_cb(struct mtk_ddp_comp *comp,
+						   void (*vblank_cb)(void *),
+						   void *vblank_cb_data)
+{
+	if (comp->funcs && comp->funcs->register_vblank_cb)
+		comp->funcs->register_vblank_cb(comp->dev, vblank_cb,
+						vblank_cb_data);
+}
+
+static inline void mtk_ddp_comp_unregister_vblank_cb(struct mtk_ddp_comp *comp)
+{
+	if (comp->funcs && comp->funcs->unregister_vblank_cb)
+		comp->funcs->unregister_vblank_cb(comp->dev);
+}
+
+static inline void mtk_ddp_comp_enable_vblank(struct mtk_ddp_comp *comp)
 {
 	if (comp->funcs && comp->funcs->enable_vblank)
-		comp->funcs->enable_vblank(comp->dev, vblank_cb, vblank_cb_data);
+		comp->funcs->enable_vblank(comp->dev);
 }
 
 static inline void mtk_ddp_comp_disable_vblank(struct mtk_ddp_comp *comp)
Signature · 1 line
2.35.1
author maintainer
#157 lore raw

PATCH 149/230 Bluetooth: protect le accept and resolv lists with hdev->lock

In reply to Greg Kroah-Hartman

From: Niels Dossche <[email protected]>

[ Upstream commit 5e2b6064cbc5fd582396768c5f9583f65085e368 ]

Concurrent operations from events on le_{accept,resolv}_list are currently unprotected by hdev->lock.
Most existing code do already protect the lists with that lock. This can be observed in hci_debugfs and hci_sync.
Add the protection for these events too.

Fixes b950aa88638c ("Bluetooth: Add definitions and track LE resolve list modification")
Fixes 0f36b589e4ee ("Bluetooth: Track LE white list modification via HCI commands")
---
 net/bluetooth/hci_event.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
net/bluetooth/hci_event.c +12 -0
index 5ac3aca6deeb..2337e9275863 100644
@@ -1559,7 +1559,9 @@ static void hci_cc_le_clear_accept_list(struct hci_dev *hdev,
 	if (status)
 		return;
 
+	hci_dev_lock(hdev);
 	hci_bdaddr_list_clear(&hdev->le_accept_list);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_add_to_accept_list(struct hci_dev *hdev,
@@ -1577,8 +1579,10 @@ static void hci_cc_le_add_to_accept_list(struct hci_dev *hdev,
 	if (!sent)
 		return;
 
+	hci_dev_lock(hdev);
 	hci_bdaddr_list_add(&hdev->le_accept_list, &sent->bdaddr,
 			    sent->bdaddr_type);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_del_from_accept_list(struct hci_dev *hdev,
@@ -1596,8 +1600,10 @@ static void hci_cc_le_del_from_accept_list(struct hci_dev *hdev,
 	if (!sent)
 		return;
 
+	hci_dev_lock(hdev);
 	hci_bdaddr_list_del(&hdev->le_accept_list, &sent->bdaddr,
 			    sent->bdaddr_type);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
@@ -1661,9 +1667,11 @@ static void hci_cc_le_add_to_resolv_list(struct hci_dev *hdev,
 	if (!sent)
 		return;
 
+	hci_dev_lock(hdev);
 	hci_bdaddr_list_add_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
 				sent->bdaddr_type, sent->peer_irk,
 				sent->local_irk);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_del_from_resolv_list(struct hci_dev *hdev,
@@ -1681,8 +1689,10 @@ static void hci_cc_le_del_from_resolv_list(struct hci_dev *hdev,
 	if (!sent)
 		return;
 
+	hci_dev_lock(hdev);
 	hci_bdaddr_list_del_with_irk(&hdev->le_resolv_list, &sent->bdaddr,
 			    sent->bdaddr_type);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_clear_resolv_list(struct hci_dev *hdev,
@@ -1695,7 +1705,9 @@ static void hci_cc_le_clear_resolv_list(struct hci_dev *hdev,
 	if (status)
 		return;
 
+	hci_dev_lock(hdev);
 	hci_bdaddr_list_clear(&hdev->le_resolv_list);
+	hci_dev_unlock(hdev);
 }
 
 static void hci_cc_le_read_resolv_list_size(struct hci_dev *hdev,
Signature · 1 line
2.35.1
author maintainer
#158 lore raw

PATCH 150/230 Bluetooth: btmtksdio: fix use-after-free at btmtksdio_recv_event

In reply to Greg Kroah-Hartman

From: Sean Wang <[email protected]>

[ Upstream commit 0fab6361c4ba17d1b43a991bef4238a3c1754d35 ]

We should not access skb buffer data anymore after hci_recv_frame was called.

[   39.634809] BUG: KASAN: use-after-free in btmtksdio_recv_event+0x1b0
[   39.634855] Read of size 1 at addr ffffff80cf28a60d by task kworker
[   39.634962] Call trace:
[   39.634974]  dump_backtrace+0x0/0x3b8
[   39.634999]  show_stack+0x20/0x2c
[   39.635016]  dump_stack_lvl+0x60/0x78
[   39.635040]  print_address_description+0x70/0x2f0
[   39.635062]  kasan_report+0x154/0x194
[   39.635079]  __asan_report_load1_noabort+0x44/0x50
[   39.635099]  btmtksdio_recv_event+0x1b0/0x1c4
[   39.635129]  btmtksdio_txrx_work+0x6cc/0xac4
[   39.635157]  process_one_work+0x560/0xc5c
[   39.635177]  worker_thread+0x7ec/0xcc0
[   39.635195]  kthread+0x2d0/0x3d0
[   39.635215]  ret_from_fork+0x10/0x20
[   39.635247] Allocated by task 0:
[   39.635260] (stack is not available)
[   39.635281] Freed by task 2392:
[   39.635295]  kasan_save_stack+0x38/0x68
[   39.635319]  kasan_set_track+0x28/0x3c
[   39.635338]  kasan_set_free_info+0x28/0x4c
[   39.635357]  ____kasan_slab_free+0x104/0x150
[   39.635374]  __kasan_slab_free+0x18/0x28
[   39.635391]  slab_free_freelist_hook+0x114/0x248
[   39.635410]  kfree+0xf8/0x2b4
[   39.635427]  skb_free_head+0x58/0x98
[   39.635447]  skb_release_data+0x2f4/0x410
[   39.635464]  skb_release_all+0x50/0x60
[   39.635481]  kfree_skb+0xc8/0x25c
[   39.635498]  hci_event_packet+0x894/0xca4 [bluetooth]
[   39.635721]  hci_rx_work+0x1c8/0x68c [bluetooth]
[   39.635925]  process_one_work+0x560/0xc5c
[   39.635951]  worker_thread+0x7ec/0xcc0
[   39.635970]  kthread+0x2d0/0x3d0
[   39.635990]  ret_from_fork+0x10/0x20
[   39.636021] The buggy address belongs to the object at ffffff80cf28a600
                which belongs to the cache kmalloc-512 of size 512
[   39.636039] The buggy address is located 13 bytes inside of
                512-byte region [ffffff80cf28a600, ffffff80cf28a800)
Fixes 9aebfd4a2200 ("Bluetooth: mediatek: add support for MediaTek MT7663S and MT7668S SDIO devices")
---
 drivers/bluetooth/btmtksdio.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/bluetooth/btmtksdio.c +2 -1
index ff1f5dfbb6db..d66e4df171d2 100644
@@ -331,6 +331,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct btmtksdio_dev *bdev = hci_get_drvdata(hdev);
 	struct hci_event_hdr *hdr = (void *)skb->data;
+	u8 evt = hdr->evt;
 	int err;
 
 	/* Fix up the vendor event id with 0xff for vendor specific instead
@@ -355,7 +356,7 @@ static int btmtksdio_recv_event(struct hci_dev *hdev, struct sk_buff *skb)
 	if (err < 0)
 		goto err_free_skb;
 
-	if (hdr->evt == HCI_EV_VENDOR) {
+	if (evt == HCI_EV_VENDOR) {
 		if (test_and_clear_bit(BTMTKSDIO_TX_WAIT_VND_EVT,
 				       &bdev->tx_state)) {
 			/* Barrier to sync with other CPUs */
Signature · 1 line
2.35.1
author maintainer
#159 lore raw

PATCH 151/230 io_uring: avoid io-wq -EAGAIN looping for !IOPOLL

In reply to Greg Kroah-Hartman

From: Pavel Begunkov <[email protected]>

[ Upstream commit e0deb6a025ae8c850dc8685be39fb27b06c88736 ]

If an opcode handler semi-reliably returns -EAGAIN, io_wq_submit_work() might continue busily hammer the same handler over and over again, which is not ideal. The -EAGAIN handling in question was put there only for IOPOLL, so restrict it to IOPOLL mode only where there is no other recourse than to retry as we cannot wait.

---
 fs/io_uring.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/io_uring.c +1 -1
index 0c5dcda0b622..9bff14c5e2b2 100644
@@ -6866,7 +6866,7 @@ static void io_wq_submit_work(struct io_wq_work *work)
 			 * forcing a sync submission from here, since we can't
 			 * wait for request slots on the block side.
 			 */
-			if (ret != -EAGAIN)
+			if (ret != -EAGAIN || !(req->ctx->flags & IORING_SETUP_IOPOLL))
 				break;
 			cond_resched();
 		} while (1);
Signature · 1 line
2.35.1
author maintainer
#160 lore raw

PATCH 152/230 irqchip/gic-v3: Ensure pseudo-NMIs have an ISB between ack and handling

In reply to Greg Kroah-Hartman

From: Mark Rutland <[email protected]>

[ Upstream commit adf14453d2c037ab529040c1186ea32e277e783a ]

There are cases where a context synchronization event is necessary between an IRQ being raised and being handled, and there are races such that we cannot rely upon the exception entry being subsequent to the interrupt being raised.

We identified and fixes this for regular IRQs in commit:

39a06b67c2c1256b ("irqchip/gic: Ensure we have an ISB between ack and ->handle_irq")

Unfortunately, we forgot to do the same for psuedo-NMIs when support for those was added in commit:

f32c926651dcd168 ("irqchip/gic-v3: Handle pseudo-NMIs")

Which means that when pseudo-NMIs are used for PMU support, we'll hit the same problem.

Apply the same fix as for regular IRQs. Note that when EOI mode 1 is in use, the call to gic_write_eoir() will provide an ISB.

Fixes f32c926651dcd168 ("irqchip/gic-v3: Handle pseudo-NMIs")
Cc Marc Zyngier <[email protected]>
Cc Thomas Gleixner <[email protected]>
Cc Will Deacon <[email protected]>
---
 drivers/irqchip/irq-gic-v3.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/irqchip/irq-gic-v3.c +3 -0
index fd4fb1b35787..d8ea330454f4 100644
@@ -654,6 +654,9 @@ static inline void gic_handle_nmi(u32 irqnr, struct pt_regs *regs)
 
 	if (static_branch_likely(&supports_deactivate_key))
 		gic_write_eoir(irqnr);
+	else
+		isb()
+
 	/*
 	 * Leave the PSR.I bit set to prevent other NMIs to be
 	 * received while handling this one.
Signature · 1 line
2.35.1
author maintainer
#161 lore raw

PATCH 153/230 rxrpc: Fix locking issue

In reply to Greg Kroah-Hartman

From: David Howells <[email protected]>

[ Upstream commit ad25f5cb39872ca14bcbe00816ae65c22fe04b89 ]

There's a locking issue with the per-netns list of calls in rxrpc. The pieces of code that add and remove a call from the list use write_lock() and the calls procfile uses read_lock() to access it. However, the timer callback function may trigger a removal by trying to queue a call for processing and finding that it's already queued - at which point it has a spare refcount that it has to do something with. Unfortunately, if it puts the call and this reduces the refcount to 0, the call will be removed from the list. Unfortunately, since the _bh variants of the locking functions aren't used, this can deadlock.

================================
WARNING: inconsistent lock state
5.18.0-rc3-build4+ #10 Not tainted
--------------------------------
inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
ksoftirqd/2/25 [HC0[0]:SC1[1]:HE1:SE0] takes:
ffff888107ac4038 (&rxnet->call_lock){+.?.}-{2:2}, at: rxrpc_put_call+0x103/0x14b {SOFTIRQ-ON-W} state was registered at:
...

 Possible unsafe locking scenario:
       CPU0
       ----
  lock(&rxnet->call_lock);
  <Interrupt>
    lock(&rxnet->call_lock);

*** DEADLOCK ***

1 lock held by ksoftirqd/2/25:
#0: ffff8881008ffdb0 ((&call->timer)){+.-.}-{0:0}, at: call_timer_fn+0x5/0x23d

Changes
=======
ver #2)
- Changed to using list_next_rcu() rather than rcu_dereference() directly.

Fixes 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
cc Marc Dionne <[email protected]>
---
 fs/seq_file.c            | 32 ++++++++++++++++++++++++++++++++
 include/linux/list.h     | 10 ++++++++++
 include/linux/seq_file.h |  4 ++++
 net/rxrpc/ar-internal.h  |  2 +-
 net/rxrpc/call_accept.c  |  6 +++---
 net/rxrpc/call_object.c  | 18 +++++++++---------
 net/rxrpc/net_ns.c       |  2 +-
 net/rxrpc/proc.c         | 10 ++--------
 8 files changed, 62 insertions(+), 22 deletions(-)
fs/seq_file.c +32 -0
index 4a2cda04d3e2..b17ee4c4f618 100644
@@ -947,6 +947,38 @@ struct list_head *seq_list_next(void *v, struct list_head *head, loff_t *ppos)
 }
 EXPORT_SYMBOL(seq_list_next);
 
+struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos)
+{
+	struct list_head *lh;
+
+	list_for_each_rcu(lh, head)
+		if (pos-- == 0)
+			return lh;
+
+	return NULL;
+}
+EXPORT_SYMBOL(seq_list_start_rcu);
+
+struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos)
+{
+	if (!pos)
+		return head;
+
+	return seq_list_start_rcu(head, pos - 1);
+}
+EXPORT_SYMBOL(seq_list_start_head_rcu);
+
+struct list_head *seq_list_next_rcu(void *v, struct list_head *head,
+				    loff_t *ppos)
+{
+	struct list_head *lh;
+
+	lh = list_next_rcu((struct list_head *)v);
+	++*ppos;
+	return lh == head ? NULL : lh;
+}
+EXPORT_SYMBOL(seq_list_next_rcu);
+
 /**
  * seq_hlist_start - start an iteration of a hlist
  * @head: the head of the hlist
include/linux/list.h +10 -0
index a119dd1990d4..d206ae93c06d 100644
@@ -577,6 +577,16 @@ static inline void list_splice_tail_init(struct list_head *list,
 #define list_for_each(pos, head) \
 	for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)
 
+/**
+ * list_for_each_rcu - Iterate over a list in an RCU-safe fashion
+ * @pos:	the &struct list_head to use as a loop cursor.
+ * @head:	the head for your list.
+ */
+#define list_for_each_rcu(pos, head)		  \
+	for (pos = rcu_dereference((head)->next); \
+	     !list_is_head(pos, (head)); \
+	     pos = rcu_dereference(pos->next))
+
 /**
  * list_for_each_continue - continue iteration over a list
  * @pos:	the &struct list_head to use as a loop cursor.
include/linux/seq_file.h +4 -0
index 5733890df64f..0b429111f85e 100644
@@ -261,6 +261,10 @@ extern struct list_head *seq_list_start_head(struct list_head *head,
 extern struct list_head *seq_list_next(void *v, struct list_head *head,
 		loff_t *ppos);
 
+extern struct list_head *seq_list_start_rcu(struct list_head *head, loff_t pos);
+extern struct list_head *seq_list_start_head_rcu(struct list_head *head, loff_t pos);
+extern struct list_head *seq_list_next_rcu(void *v, struct list_head *head, loff_t *ppos);
+
 /*
  * Helpers for iteration over hlist_head-s in seq_files
  */
net/rxrpc/ar-internal.h +1 -1
index dce056adb78c..f2d593e27b64 100644
@@ -68,7 +68,7 @@ struct rxrpc_net {
 	struct proc_dir_entry	*proc_net;	/* Subdir in /proc/net */
 	u32			epoch;		/* Local epoch for detecting local-end reset */
 	struct list_head	calls;		/* List of calls active in this namespace */
-	rwlock_t		call_lock;	/* Lock for ->calls */
+	spinlock_t		call_lock;	/* Lock for ->calls */
 	atomic_t		nr_calls;	/* Count of allocated calls */
 
 	atomic_t		nr_conns;
net/rxrpc/call_accept.c +3 -3
index 1ae90fb97936..8b24ffbc72ef 100644
@@ -140,9 +140,9 @@ static int rxrpc_service_prealloc_one(struct rxrpc_sock *rx,
 	write_unlock(&rx->call_lock);
 
 	rxnet = call->rxnet;
-	write_lock(&rxnet->call_lock);
-	list_add_tail(&call->link, &rxnet->calls);
-	write_unlock(&rxnet->call_lock);
+	spin_lock_bh(&rxnet->call_lock);
+	list_add_tail_rcu(&call->link, &rxnet->calls);
+	spin_unlock_bh(&rxnet->call_lock);
 
 	b->call_backlog[call_head] = call;
 	smp_store_release(&b->call_backlog_head, (call_head + 1) & (size - 1));
net/rxrpc/call_object.c +9 -9
index 043508fd8d8a..25c9a2cbf048 100644
@@ -337,9 +337,9 @@ struct rxrpc_call *rxrpc_new_client_call(struct rxrpc_sock *rx,
 	write_unlock(&rx->call_lock);
 
 	rxnet = call->rxnet;
-	write_lock(&rxnet->call_lock);
-	list_add_tail(&call->link, &rxnet->calls);
-	write_unlock(&rxnet->call_lock);
+	spin_lock_bh(&rxnet->call_lock);
+	list_add_tail_rcu(&call->link, &rxnet->calls);
+	spin_unlock_bh(&rxnet->call_lock);
 
 	/* From this point on, the call is protected by its own lock. */
 	release_sock(&rx->sk);
@@ -631,9 +631,9 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
 		ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
 
 		if (!list_empty(&call->link)) {
-			write_lock(&rxnet->call_lock);
+			spin_lock_bh(&rxnet->call_lock);
 			list_del_init(&call->link);
-			write_unlock(&rxnet->call_lock);
+			spin_unlock_bh(&rxnet->call_lock);
 		}
 
 		rxrpc_cleanup_call(call);
@@ -705,7 +705,7 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)
 	_enter("");
 
 	if (!list_empty(&rxnet->calls)) {
-		write_lock(&rxnet->call_lock);
+		spin_lock_bh(&rxnet->call_lock);
 
 		while (!list_empty(&rxnet->calls)) {
 			call = list_entry(rxnet->calls.next,
@@ -720,12 +720,12 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet)
 			       rxrpc_call_states[call->state],
 			       call->flags, call->events);
 
-			write_unlock(&rxnet->call_lock);
+			spin_unlock_bh(&rxnet->call_lock);
 			cond_resched();
-			write_lock(&rxnet->call_lock);
+			spin_lock_bh(&rxnet->call_lock);
 		}
 
-		write_unlock(&rxnet->call_lock);
+		spin_unlock_bh(&rxnet->call_lock);
 	}
 
 	atomic_dec(&rxnet->nr_calls);
net/rxrpc/net_ns.c +1 -1
index cc7e30733feb..e4d6d432515b 100644
@@ -50,7 +50,7 @@ static __net_init int rxrpc_init_net(struct net *net)
 	rxnet->epoch |= RXRPC_RANDOM_EPOCH;
 
 	INIT_LIST_HEAD(&rxnet->calls);
-	rwlock_init(&rxnet->call_lock);
+	spin_lock_init(&rxnet->call_lock);
 	atomic_set(&rxnet->nr_calls, 1);
 
 	atomic_set(&rxnet->nr_conns, 1);
net/rxrpc/proc.c +2 -8
index e2f990754f88..5a67955cc00f 100644
@@ -26,29 +26,23 @@ static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES] = {
  */
 static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos)
 	__acquires(rcu)
-	__acquires(rxnet->call_lock)
 {
 	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
 
 	rcu_read_lock();
-	read_lock(&rxnet->call_lock);
-	return seq_list_start_head(&rxnet->calls, *_pos);
+	return seq_list_start_head_rcu(&rxnet->calls, *_pos);
 }
 
 static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 {
 	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
 
-	return seq_list_next(v, &rxnet->calls, pos);
+	return seq_list_next_rcu(v, &rxnet->calls, pos);
 }
 
 static void rxrpc_call_seq_stop(struct seq_file *seq, void *v)
-	__releases(rxnet->call_lock)
 	__releases(rcu)
 {
-	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
-
-	read_unlock(&rxnet->call_lock);
 	rcu_read_unlock();
 }
 
Signature · 1 line
2.35.1
author maintainer
#162 lore raw

PATCH 154/230 dt-bindings: soc: qcom: smd-rpm: Add compatible for MSM8953 SoC

In reply to Greg Kroah-Hartman

From: Vladimir Lypak <[email protected]>

[ Upstream commit 96c42812f798c5e48d55cd6fc2101ce99af19608 ]

Document compatible for MSM8953 SoC.

---
 Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml | 2 ++
 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml +2 -0
index cc3fe5ed7421..77963b86b714 100644
@@ -34,6 +34,7 @@ properties:
       - qcom,rpm-ipq6018
       - qcom,rpm-msm8226
       - qcom,rpm-msm8916
+      - qcom,rpm-msm8953
       - qcom,rpm-msm8974
       - qcom,rpm-msm8976
       - qcom,rpm-msm8996
@@ -57,6 +58,7 @@ if:
           - qcom,rpm-apq8084
           - qcom,rpm-msm8916
           - qcom,rpm-msm8974
+          - qcom,rpm-msm8953
 then:
   required:
     - qcom,smd-channels
Signature · 1 line
2.35.1
author maintainer
#163 lore raw

PATCH 155/230 dt-bindings: soc: qcom: smd-rpm: Fix missing MSM8936 compatible

In reply to Greg Kroah-Hartman

From: Bryan O'Donoghue <[email protected]>

[ Upstream commit e930244918092d44b60a7b538cf60d737010ceef ]

Add compatible msm8936. msm8936 covers both msm8936 and msm8939. The relevant driver already has the compat string but, we haven't documented it.

---
 Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml | 1 +
 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/soc/qcom/qcom,smd-rpm.yaml +1 -0
index 77963b86b714..1b0062e3c1a4 100644
@@ -34,6 +34,7 @@ properties:
       - qcom,rpm-ipq6018
       - qcom,rpm-msm8226
       - qcom,rpm-msm8916
+      - qcom,rpm-msm8936
       - qcom,rpm-msm8953
       - qcom,rpm-msm8974
       - qcom,rpm-msm8976
Signature · 1 line
2.35.1
author maintainer
#164 lore raw

PATCH 156/230 module: change to print useful messages from elf_validity_check()

In reply to Greg Kroah-Hartman

From: Shuah Khan <[email protected]>

[ Upstream commit 7fd982f394c42f25a73fe9dfbf1e6b11fa26b40a ]

elf_validity_check() checks ELF headers for errors and ELF Spec. compliance and if any of them fail it returns -ENOEXEC from all of these error paths. Almost all of them don't print any messages.

When elf_validity_check() returns an error, load_module() prints an error message without error code. It is hard to determine why the module ELF structure is invalid, even if load_module() prints the error code which is -ENOEXEC in all of these cases.

Change to print useful error messages from elf_validity_check() to clearly say what went wrong and why the ELF validity checks failed.

Remove the load_module() error message which is no longer needed. This patch includes changes to fix build warns on 32-bit platforms:

warning: format '%llu' expects argument of type 'long long unsigned int', but argument 3 has type 'Elf32_Off' {aka 'unsigned int'}

---
 kernel/module.c | 75 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 54 insertions(+), 21 deletions(-)
kernel/module.c +54 -21
index 83991c2d5af9..256b3c80a771 100644
@@ -2967,14 +2967,29 @@ static int elf_validity_check(struct load_info *info)
 	Elf_Shdr *shdr, *strhdr;
 	int err;
 
-	if (info->len < sizeof(*(info->hdr)))
-		return -ENOEXEC;
+	if (info->len < sizeof(*(info->hdr))) {
+		pr_err("Invalid ELF header len %lu\n", info->len);
+		goto no_exec;
+	}
 
-	if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0
-	    || info->hdr->e_type != ET_REL
-	    || !elf_check_arch(info->hdr)
-	    || info->hdr->e_shentsize != sizeof(Elf_Shdr))
-		return -ENOEXEC;
+	if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0) {
+		pr_err("Invalid ELF header magic: != %s\n", ELFMAG);
+		goto no_exec;
+	}
+	if (info->hdr->e_type != ET_REL) {
+		pr_err("Invalid ELF header type: %u != %u\n",
+		       info->hdr->e_type, ET_REL);
+		goto no_exec;
+	}
+	if (!elf_check_arch(info->hdr)) {
+		pr_err("Invalid architecture in ELF header: %u\n",
+		       info->hdr->e_machine);
+		goto no_exec;
+	}
+	if (info->hdr->e_shentsize != sizeof(Elf_Shdr)) {
+		pr_err("Invalid ELF section header size\n");
+		goto no_exec;
+	}
 
 	/*
 	 * e_shnum is 16 bits, and sizeof(Elf_Shdr) is
@@ -2983,8 +2998,10 @@ static int elf_validity_check(struct load_info *info)
 	 */
 	if (info->hdr->e_shoff >= info->len
 	    || (info->hdr->e_shnum * sizeof(Elf_Shdr) >
-		info->len - info->hdr->e_shoff))
-		return -ENOEXEC;
+		info->len - info->hdr->e_shoff)) {
+		pr_err("Invalid ELF section header overflow\n");
+		goto no_exec;
+	}
 
 	info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;
 
@@ -2992,13 +3009,19 @@ static int elf_validity_check(struct load_info *info)
 	 * Verify if the section name table index is valid.
 	 */
 	if (info->hdr->e_shstrndx == SHN_UNDEF
-	    || info->hdr->e_shstrndx >= info->hdr->e_shnum)
-		return -ENOEXEC;
+	    || info->hdr->e_shstrndx >= info->hdr->e_shnum) {
+		pr_err("Invalid ELF section name index: %d || e_shstrndx (%d) >= e_shnum (%d)\n",
+		       info->hdr->e_shstrndx, info->hdr->e_shstrndx,
+		       info->hdr->e_shnum);
+		goto no_exec;
+	}
 
 	strhdr = &info->sechdrs[info->hdr->e_shstrndx];
 	err = validate_section_offset(info, strhdr);
-	if (err < 0)
+	if (err < 0) {
+		pr_err("Invalid ELF section hdr(type %u)\n", strhdr->sh_type);
 		return err;
+	}
 
 	/*
 	 * The section name table must be NUL-terminated, as required
@@ -3006,8 +3029,10 @@ static int elf_validity_check(struct load_info *info)
 	 * strings in the section safe.
 	 */
 	info->secstrings = (void *)info->hdr + strhdr->sh_offset;
-	if (info->secstrings[strhdr->sh_size - 1] != '\0')
-		return -ENOEXEC;
+	if (info->secstrings[strhdr->sh_size - 1] != '\0') {
+		pr_err("ELF Spec violation: section name table isn't null terminated\n");
+		goto no_exec;
+	}
 
 	/*
 	 * The code assumes that section 0 has a length of zero and
@@ -3015,8 +3040,11 @@ static int elf_validity_check(struct load_info *info)
 	 */
 	if (info->sechdrs[0].sh_type != SHT_NULL
 	    || info->sechdrs[0].sh_size != 0
-	    || info->sechdrs[0].sh_addr != 0)
-		return -ENOEXEC;
+	    || info->sechdrs[0].sh_addr != 0) {
+		pr_err("ELF Spec violation: section 0 type(%d)!=SH_NULL or non-zero len or addr\n",
+		       info->sechdrs[0].sh_type);
+		goto no_exec;
+	}
 
 	for (i = 1; i < info->hdr->e_shnum; i++) {
 		shdr = &info->sechdrs[i];
@@ -3026,8 +3054,12 @@ static int elf_validity_check(struct load_info *info)
 			continue;
 		case SHT_SYMTAB:
 			if (shdr->sh_link == SHN_UNDEF
-			    || shdr->sh_link >= info->hdr->e_shnum)
-				return -ENOEXEC;
+			    || shdr->sh_link >= info->hdr->e_shnum) {
+				pr_err("Invalid ELF sh_link!=SHN_UNDEF(%d) or (sh_link(%d) >= hdr->e_shnum(%d)\n",
+				       shdr->sh_link, shdr->sh_link,
+				       info->hdr->e_shnum);
+				goto no_exec;
+			}
 			fallthrough;
 		default:
 			err = validate_section_offset(info, shdr);
@@ -3049,6 +3081,9 @@ static int elf_validity_check(struct load_info *info)
 	}
 
 	return 0;
+
+no_exec:
+	return -ENOEXEC;
 }
 
 #define COPY_CHUNK_SIZE (16*PAGE_SIZE)
@@ -3925,10 +3960,8 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	 * sections.
 	 */
 	err = elf_validity_check(info);
-	if (err) {
-		pr_err("Module has invalid ELF structures\n");
+	if (err)
 		goto free_copy;
-	}
 
 	/*
 	 * Everything checks out, so set up the section info
Signature · 1 line
2.35.1
author maintainer
#165 lore raw

PATCH 157/230 module: fix [e_shstrndx].sh_size=0 OOB access

In reply to Greg Kroah-Hartman

From: Alexey Dobriyan <[email protected]>

[ Upstream commit 391e982bfa632b8315235d8be9c0a81374c6a19c ]

It is trivial to craft a module to trigger OOB access in this line:

	if (info->secstrings[strhdr->sh_size - 1] != '\0') {
BUG: unable to handle page fault for address: ffffc90000aa0fff
PGD 100000067 P4D 100000067 PUD 100066067 PMD 10436f067 PTE 0
Oops: 0000 [#1] PREEMPT SMP PTI
CPU: 7 PID: 1215 Comm: insmod Not tainted 5.18.0-rc5-00007-g9bf578647087-dirty #10
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-4.fc34 04/01/2014
RIP: 0010:load_module+0x19b/0x2391
Fixes ec2a29593c83 ("module: harden ELF info handling")
[rebased patch onto modules-next]
---
 kernel/module.c | 4 ++++
 1 file changed, 4 insertions(+)
kernel/module.c +4 -0
index 256b3c80a771..ef79f4dbda87 100644
@@ -3029,6 +3029,10 @@ static int elf_validity_check(struct load_info *info)
 	 * strings in the section safe.
 	 */
 	info->secstrings = (void *)info->hdr + strhdr->sh_offset;
+	if (strhdr->sh_size == 0) {
+		pr_err("empty section name table\n");
+		goto no_exec;
+	}
 	if (info->secstrings[strhdr->sh_size - 1] != '\0') {
 		pr_err("ELF Spec violation: section name table isn't null terminated\n");
 		goto no_exec;
Signature · 1 line
2.35.1
author maintainer
#166 lore raw

PATCH 158/230 iommu/vt-d: Fix PCI bus rescan device hot add

In reply to Greg Kroah-Hartman

From: Yian Chen <[email protected]>

commit 316f92a705a4c2bf4712135180d56f3cca09243a upstream.

Notifier calling chain uses priority to determine the execution order of the notifiers or listeners registered to the chain. PCI bus device hot add utilizes the notification mechanism.

The current code sets low priority (INT_MIN) to Intel dmar_pci_bus_notifier and postpones DMAR decoding after adding new device into IOMMU. The result is that struct device pointer cannot be found in DRHD search for the new device's DMAR/IOMMU. Subsequently, the device is put under the "catch-all" IOMMU instead of the correct one. This could cause system hang when device TLB invalidation is sent to the wrong IOMMU. Invalidation timeout error and hard lockup have been observed and data inconsistency/crush may occur as well.

This patch fixes the issue by setting a positive priority(1) for dmar_pci_bus_notifier while the priority of IOMMU bus notifier uses the default value(0), therefore DMAR decoding will be in advance of DRHD search for a new device to find the correct IOMMU.

Following is a 2-step example that triggers the bug by simulating PCI device hot add behavior in Intel Sapphire Rapids server.

echo 1 > /sys/bus/pci/devices/0000:6a:01.0/remove
echo 1 > /sys/bus/pci/rescan

---
 drivers/iommu/intel/dmar.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iommu/intel/dmar.c +1 -1
@@ -385,7 +385,7 @@ static int dmar_pci_bus_notifier(struct
 
 static struct notifier_block dmar_pci_bus_nb = {
 	.notifier_call = dmar_pci_bus_notifier,
-	.priority = INT_MIN,
+	.priority = 1,
 };
 
 static struct dmar_drhd_unit *
author maintainer
#167 lore raw

PATCH 159/230 fbdev: fbmem: Fix logo center image dx issue

In reply to Greg Kroah-Hartman

From: Guiling Deng <[email protected]>

commit 955f04766d4e6eb94bf3baa539e096808c74ebfb upstream.

Image.dx gets wrong value because of missing '()'.

If xres == logo->width and n == 1, image.dx = -16.

Fixes 3d8b1933eb1c ("fbdev: fbmem: add config option to center the bootup logo")
---
 drivers/video/fbdev/core/fbmem.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/fbdev/core/fbmem.c +1 -1
@@ -514,7 +514,7 @@ static int fb_show_logo_line(struct fb_i
 
 		while (n && (n * (logo->width + 8) - 8 > xres))
 			--n;
-		image.dx = (xres - n * (logo->width + 8) - 8) / 2;
+		image.dx = (xres - (n * (logo->width + 8) - 8)) / 2;
 		image.dy = y ?: (yres - logo->height) / 2;
 	} else {
 		image.dx = 0;
author maintainer
#168 lore raw

PATCH 160/230 fbmem: Check virtual screen sizes in fb_set_var()

In reply to Greg Kroah-Hartman

From: Helge Deller <[email protected]>

commit 6c11df58fd1ac0aefcb3b227f72769272b939e56 upstream.

Verify that the fbdev or drm driver correctly adjusted the virtual screen sizes. On failure report the failing driver and reject the screen size change.

---
 drivers/video/fbdev/core/fbmem.c |   10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/video/fbdev/core/fbmem.c +10 -0
@@ -1020,6 +1020,16 @@ fb_set_var(struct fb_info *info, struct
 	if (ret)
 		return ret;
 
+	/* verify that virtual resolution >= physical resolution */
+	if (var->xres_virtual < var->xres ||
+	    var->yres_virtual < var->yres) {
+		pr_warn("WARNING: fbcon: Driver '%s' missed to adjust virtual screen size (%ux%u vs. %ux%u)\n",
+			info->fix.id,
+			var->xres_virtual, var->yres_virtual,
+			var->xres, var->yres);
+		return -EINVAL;
+	}
+
 	if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
 		return 0;
 
author maintainer
#169 lore raw

PATCH 161/230 fbcon: Disallow setting font bigger than screen size

In reply to Greg Kroah-Hartman

From: Helge Deller <[email protected]>

commit 65a01e601dbba8b7a51a2677811f70f783766682 upstream.

Prevent that users set a font size which is bigger than the physical screen. It's unlikely this may happen (because screens are usually much larger than the fonts and each font char is limited to 32x32 pixels), but it may happen on smaller screens/LCD displays.

---
 drivers/video/fbdev/core/fbcon.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/video/fbdev/core/fbcon.c +5 -0
@@ -2480,6 +2480,11 @@ static int fbcon_set_font(struct vc_data
 	if (charcount != 256 && charcount != 512)
 		return -EINVAL;
 
+	/* font bigger than screen resolution ? */
+	if (w > FBCON_SWAP(info->var.rotate, info->var.xres, info->var.yres) ||
+	    h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
+		return -EINVAL;
+
 	/* Make sure drawing engine can handle the font */
 	if (!(info->pixmap.blit_x & (1 << (font->width - 1))) ||
 	    !(info->pixmap.blit_y & (1 << (font->height - 1))))
author maintainer
#170 lore raw

PATCH 162/230 fbcon: Prevent that screen size is smaller than font size

In reply to Greg Kroah-Hartman

From: Helge Deller <[email protected]>

commit e64242caef18b4a5840b0e7a9bff37abd4f4f933 upstream.

We need to prevent that users configure a screen size which is smaller than the currently selected font size. Otherwise rendering chars on the screen will access memory outside the graphics memory region.

This patch adds a new function fbcon_modechange_possible() which implements this check and which later may be extended with other checks if necessary. The new function is called from the FBIOPUT_VSCREENINFO ioctl handler in fbmem.c, which will return -EINVAL if userspace asked for a too small screen size.

---
 drivers/video/fbdev/core/fbcon.c |   28 ++++++++++++++++++++++++++++
 drivers/video/fbdev/core/fbmem.c |    4 +++-
 include/linux/fbcon.h            |    4 ++++
 3 files changed, 35 insertions(+), 1 deletion(-)
drivers/video/fbdev/core/fbcon.c +28 -0
@@ -2747,6 +2747,34 @@ void fbcon_update_vcs(struct fb_info *in
 }
 EXPORT_SYMBOL(fbcon_update_vcs);
 
+/* let fbcon check if it supports a new screen resolution */
+int fbcon_modechange_possible(struct fb_info *info, struct fb_var_screeninfo *var)
+{
+	struct fbcon_ops *ops = info->fbcon_par;
+	struct vc_data *vc;
+	unsigned int i;
+
+	WARN_CONSOLE_UNLOCKED();
+
+	if (!ops)
+		return 0;
+
+	/* prevent setting a screen size which is smaller than font size */
+	for (i = first_fb_vc; i <= last_fb_vc; i++) {
+		vc = vc_cons[i].d;
+		if (!vc || vc->vc_mode != KD_TEXT ||
+			   registered_fb[con2fb_map[i]] != info)
+			continue;
+
+		if (vc->vc_font.width  > FBCON_SWAP(var->rotate, var->xres, var->yres) ||
+		    vc->vc_font.height > FBCON_SWAP(var->rotate, var->yres, var->xres))
+			return -EINVAL;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(fbcon_modechange_possible);
+
 int fbcon_mode_deleted(struct fb_info *info,
 		       struct fb_videomode *mode)
 {
drivers/video/fbdev/core/fbmem.c +3 -1
@@ -1120,7 +1120,9 @@ static long do_fb_ioctl(struct fb_info *
 			return -EFAULT;
 		console_lock();
 		lock_fb_info(info);
-		ret = fb_set_var(info, &var);
+		ret = fbcon_modechange_possible(info, &var);
+		if (!ret)
+			ret = fb_set_var(info, &var);
 		if (!ret)
 			fbcon_update_vcs(info, var.activate & FB_ACTIVATE_ALL);
 		unlock_fb_info(info);
include/linux/fbcon.h +4 -0
@@ -15,6 +15,8 @@ void fbcon_new_modelist(struct fb_info *
 void fbcon_get_requirement(struct fb_info *info,
 			   struct fb_blit_caps *caps);
 void fbcon_fb_blanked(struct fb_info *info, int blank);
+int  fbcon_modechange_possible(struct fb_info *info,
+			       struct fb_var_screeninfo *var);
 void fbcon_update_vcs(struct fb_info *info, bool all);
 void fbcon_remap_all(struct fb_info *info);
 int fbcon_set_con2fb_map_ioctl(void __user *argp);
@@ -33,6 +35,8 @@ static inline void fbcon_new_modelist(st
 static inline void fbcon_get_requirement(struct fb_info *info,
 					 struct fb_blit_caps *caps) {}
 static inline void fbcon_fb_blanked(struct fb_info *info, int blank) {}
+static inline int  fbcon_modechange_possible(struct fb_info *info,
+				struct fb_var_screeninfo *var) { return 0; }
 static inline void fbcon_update_vcs(struct fb_info *info, bool all) {}
 static inline void fbcon_remap_all(struct fb_info *info) {}
 static inline int fbcon_set_con2fb_map_ioctl(void __user *argp) { return 0; }
author maintainer
#171 lore raw

PATCH 163/230 PM: runtime: Redefine pm_runtime_release_supplier()

In reply to Greg Kroah-Hartman

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

commit 07358194badf73e267289b40b761f5dc56928eab upstream.

Instead of passing an extra bool argument to pm_runtime_release_supplier(), make its callers take care of triggering a runtime-suspend of the supplier device as needed.

No expected functional impact.

---
 drivers/base/core.c          |    3 ++-
 drivers/base/power/runtime.c |   20 +++++++++-----------
 include/linux/pm_runtime.h   |    5 ++---
 3 files changed, 13 insertions(+), 15 deletions(-)
drivers/base/core.c +2 -1
@@ -485,7 +485,8 @@ static void device_link_release_fn(struc
 	/* Ensure that all references to the link object have been dropped. */
 	device_link_synchronize_removal();
 
-	pm_runtime_release_supplier(link, true);
+	pm_runtime_release_supplier(link);
+	pm_request_idle(link->supplier);
 
 	put_device(link->consumer);
 	put_device(link->supplier);
drivers/base/power/runtime.c +9 -11
@@ -308,13 +308,10 @@ static int rpm_get_suppliers(struct devi
 /**
  * pm_runtime_release_supplier - Drop references to device link's supplier.
  * @link: Target device link.
- * @check_idle: Whether or not to check if the supplier device is idle.
  *
- * Drop all runtime PM references associated with @link to its supplier device
- * and if @check_idle is set, check if that device is idle (and so it can be
- * suspended).
+ * Drop all runtime PM references associated with @link to its supplier device.
  */
-void pm_runtime_release_supplier(struct device_link *link, bool check_idle)
+void pm_runtime_release_supplier(struct device_link *link)
 {
 	struct device *supplier = link->supplier;
 
@@ -327,9 +324,6 @@ void pm_runtime_release_supplier(struct
 	while (refcount_dec_not_one(&link->rpm_active) &&
 	       atomic_read(&supplier->power.usage_count) > 0)
 		pm_runtime_put_noidle(supplier);
-
-	if (check_idle)
-		pm_request_idle(supplier);
 }
 
 static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend)
@@ -337,8 +331,11 @@ static void __rpm_put_suppliers(struct d
 	struct device_link *link;
 
 	list_for_each_entry_rcu(link, &dev->links.suppliers, c_node,
-				device_links_read_lock_held())
-		pm_runtime_release_supplier(link, try_to_suspend);
+				device_links_read_lock_held()) {
+		pm_runtime_release_supplier(link);
+		if (try_to_suspend)
+			pm_request_idle(link->supplier);
+	}
 }
 
 static void rpm_put_suppliers(struct device *dev)
@@ -1791,7 +1788,8 @@ void pm_runtime_drop_link(struct device_
 		return;
 
 	pm_runtime_drop_link_count(link->consumer);
-	pm_runtime_release_supplier(link, true);
+	pm_runtime_release_supplier(link);
+	pm_request_idle(link->supplier);
 }
 
 static bool pm_runtime_need_not_resume(struct device *dev)
include/linux/pm_runtime.h +2 -3
@@ -58,7 +58,7 @@ extern void pm_runtime_get_suppliers(str
 extern void pm_runtime_put_suppliers(struct device *dev);
 extern void pm_runtime_new_link(struct device *dev);
 extern void pm_runtime_drop_link(struct device_link *link);
-extern void pm_runtime_release_supplier(struct device_link *link, bool check_idle);
+extern void pm_runtime_release_supplier(struct device_link *link);
 
 extern int devm_pm_runtime_enable(struct device *dev);
 
@@ -284,8 +284,7 @@ static inline void pm_runtime_get_suppli
 static inline void pm_runtime_put_suppliers(struct device *dev) {}
 static inline void pm_runtime_new_link(struct device *dev) {}
 static inline void pm_runtime_drop_link(struct device_link *link) {}
-static inline void pm_runtime_release_supplier(struct device_link *link,
-					       bool check_idle) {}
+static inline void pm_runtime_release_supplier(struct device_link *link) {}
 
 #endif /* !CONFIG_PM */
 
author maintainer
#172 lore raw

PATCH 164/230 memregion: Fix memregion_free() fallback definition

In reply to Greg Kroah-Hartman

From: Dan Williams <[email protected]>

commit f50974eee5c4a5de1e4f1a3d873099f170df25f8 upstream.

In the CONFIG_MEMREGION=n case, memregion_free() is meant to be a static inline. 0day reports:

In file included from drivers/cxl/core/port.c:4:
include/linux/memregion.h:19:6: warning: no previous prototype for function 'memregion_free' [-Wmissing-prototypes]

Mark memregion_free() static.

---
 include/linux/memregion.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/memregion.h +1 -1
@@ -16,7 +16,7 @@ static inline int memregion_alloc(gfp_t
 {
 	return -ENOMEM;
 }
-void memregion_free(int id)
+static inline void memregion_free(int id)
 {
 }
 #endif
author maintainer
#173 lore raw

PATCH 165/230 video: of_display_timing.h: include errno.h

In reply to Greg Kroah-Hartman

From: Hsin-Yi Wang <[email protected]>

commit 3663a2fb325b8782524f3edb0ae32d6faa615109 upstream.

If CONFIG_OF is not enabled, default of_get_display_timing() returns an errno, so include the header.

Fixes 422b67e0b31a ("videomode: provide dummy inline functions for !CONFIG_OF")
---
 include/video/of_display_timing.h |    2 ++
 1 file changed, 2 insertions(+)
include/video/of_display_timing.h +2 -0
@@ -8,6 +8,8 @@
 #ifndef __LINUX_OF_DISPLAY_TIMING_H
 #define __LINUX_OF_DISPLAY_TIMING_H
 
+#include <linux/errno.h>
+
 struct device_node;
 struct display_timing;
 struct display_timings;
author maintainer
#174 lore raw

PATCH 166/230 powerpc/powernv: delay rng platform device creation until later in boot

In reply to Greg Kroah-Hartman

From: Jason A. Donenfeld <[email protected]>

commit 887502826549caa7e4215fd9e628f48f14c0825a upstream.

The platform device for the rng must be created much later in boot. Otherwise it tries to connect to a parent that doesn't yet exist, resulting in this splat:

  [    0.000478] kobject: '(null)' ((____ptrval____)): is not initialized, yet kobject_get() is being called.
  [    0.002925] [c000000002a0fb30] [c00000000073b0bc] kobject_get+0x8c/0x100 (unreliable)
  [    0.003071] [c000000002a0fba0] [c00000000087e464] device_add+0xf4/0xb00
  [    0.003194] [c000000002a0fc80] [c000000000a7f6e4] of_device_add+0x64/0x80
  [    0.003321] [c000000002a0fcb0] [c000000000a800d0] of_platform_device_create_pdata+0xd0/0x1b0
  [    0.003476] [c000000002a0fd00] [c00000000201fa44] pnv_get_random_long_early+0x240/0x2e4
  [    0.003623] [c000000002a0fe20] [c000000002060c38] random_init+0xc0/0x214

This patch fixes the issue by doing the platform device creation inside of machine_subsys_initcall.

Fixes f3eac426657d ("powerpc/powernv: wire up rng during setup_arch")
[mpe: Change "of node" to "platform device" in change log]
---
 arch/powerpc/platforms/powernv/rng.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
arch/powerpc/platforms/powernv/rng.c +10 -6
@@ -176,12 +176,8 @@ static int __init pnv_get_random_long_ea
 		    NULL) != pnv_get_random_long_early)
 		return 0;
 
-	for_each_compatible_node(dn, NULL, "ibm,power-rng") {
-		if (rng_create(dn))
-			continue;
-		/* Create devices for hwrng driver */
-		of_platform_device_create(dn, NULL, NULL);
-	}
+	for_each_compatible_node(dn, NULL, "ibm,power-rng")
+		rng_create(dn);
 
 	if (!ppc_md.get_random_seed)
 		return 0;
@@ -205,10 +201,18 @@ void __init pnv_rng_init(void)
 
 static int __init pnv_rng_late_init(void)
 {
+	struct device_node *dn;
 	unsigned long v;
+
 	/* In case it wasn't called during init for some other reason. */
 	if (ppc_md.get_random_seed == pnv_get_random_long_early)
 		pnv_get_random_long_early(&v);
+
+	if (ppc_md.get_random_seed == powernv_get_random_long) {
+		for_each_compatible_node(dn, NULL, "ibm,power-rng")
+			of_platform_device_create(dn, NULL, NULL);
+	}
+
 	return 0;
 }
 machine_subsys_initcall(powernv, pnv_rng_late_init);
author maintainer
#175 lore raw

PATCH 167/230 net: dsa: qca8k: reset cpu port on MTU change

In reply to Greg Kroah-Hartman

From: Christian Marangi <[email protected]>

commit 386228c694bf1e7a7688e44412cb33500b0ac585 upstream.

It was discovered that the Documentation lacks of a fundamental detail on how to correctly change the MAX_FRAME_SIZE of the switch.

In fact if the MAX_FRAME_SIZE is changed while the cpu port is on, the switch panics and cease to send any packet. This cause the mgmt ethernet system to not receive any packet (the slow fallback still works) and makes the device not reachable. To recover from this a switch reset is required.

To correctly handle this, turn off the cpu ports before changing the MAX_FRAME_SIZE and turn on again after the value is applied.

Fixes f58d2598cf70 ("net: dsa: qca8k: implement the port MTU callbacks")
---
 drivers/net/dsa/qca8k.c |   23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)
drivers/net/dsa/qca8k.c +21 -2
@@ -1599,7 +1599,7 @@ static int
 qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
 {
 	struct qca8k_priv *priv = ds->priv;
-	int i, mtu = 0;
+	int ret, i, mtu = 0;
 
 	priv->port_mtu[port] = new_mtu;
 
@@ -1607,8 +1607,27 @@ qca8k_port_change_mtu(struct dsa_switch
 		if (priv->port_mtu[i] > mtu)
 			mtu = priv->port_mtu[i];
 
+	/* To change the MAX_FRAME_SIZE the cpu ports must be off or
+	 * the switch panics.
+	 * Turn off both cpu ports before applying the new value to prevent
+	 * this.
+	 */
+	if (priv->port_sts[0].enabled)
+		qca8k_port_set_status(priv, 0, 0);
+
+	if (priv->port_sts[6].enabled)
+		qca8k_port_set_status(priv, 6, 0);
+
 	/* Include L2 header / FCS length */
-	return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+	ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
+
+	if (priv->port_sts[0].enabled)
+		qca8k_port_set_status(priv, 0, 1);
+
+	if (priv->port_sts[6].enabled)
+		qca8k_port_set_status(priv, 6, 1);
+
+	return ret;
 }
 
 static int
author maintainer
#176 lore raw

PATCH 168/230 can: kvaser_usb: replace run-time checks with struct kvaser_usb_driver_info

In reply to Greg Kroah-Hartman

From: Jimmy Assarsson <[email protected]>

commit 49f274c72357d2d74cba70b172cf369768909707 upstream.

Unify and move compile-time known information into new struct kvaser_usb_driver_info, in favor of run-time checks.

All Kvaser USBcanII supports listen-only mode and error counter reporting.

---
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h      |   22 +
 drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c |  275 ++++++++++++-----------
 drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c |   24 +-
 3 files changed, 173 insertions(+), 148 deletions(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb.h +12 -10
@@ -35,9 +35,9 @@
 #define KVASER_USB_RX_BUFFER_SIZE		3072
 #define KVASER_USB_MAX_NET_DEVICES		5
 
-/* USB devices features */
-#define KVASER_USB_HAS_SILENT_MODE		BIT(0)
-#define KVASER_USB_HAS_TXRX_ERRORS		BIT(1)
+/* Kvaser USB device quirks */
+#define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
+#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP			0x01
@@ -65,12 +65,7 @@ struct kvaser_usb_dev_card_data_hydra {
 struct kvaser_usb_dev_card_data {
 	u32 ctrlmode_supported;
 	u32 capabilities;
-	union {
-		struct {
-			enum kvaser_usb_leaf_family family;
-		} leaf;
-		struct kvaser_usb_dev_card_data_hydra hydra;
-	};
+	struct kvaser_usb_dev_card_data_hydra hydra;
 };
 
 /* Context for an outstanding, not yet ACKed, transmission */
@@ -84,7 +79,7 @@ struct kvaser_usb {
 	struct usb_device *udev;
 	struct usb_interface *intf;
 	struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES];
-	const struct kvaser_usb_dev_ops *ops;
+	const struct kvaser_usb_driver_info *driver_info;
 	const struct kvaser_usb_dev_cfg *cfg;
 
 	struct usb_endpoint_descriptor *bulk_in, *bulk_out;
@@ -166,6 +161,12 @@ struct kvaser_usb_dev_ops {
 				  int *cmd_len, u16 transid);
 };
 
+struct kvaser_usb_driver_info {
+	u32 quirks;
+	enum kvaser_usb_leaf_family family;
+	const struct kvaser_usb_dev_ops *ops;
+};
+
 struct kvaser_usb_dev_cfg {
 	const struct can_clock clock;
 	const unsigned int timestamp_freq;
@@ -185,4 +186,5 @@ int kvaser_usb_send_cmd_async(struct kva
 			      int len);
 
 int kvaser_usb_can_rx_over_error(struct net_device *netdev);
+
 #endif /* KVASER_USB_H */
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +149 -126

447 lines not on this page · raw message

drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +12 -12
@@ -405,7 +405,7 @@ kvaser_usb_leaf_frame_to_cmd(const struc
 				      sizeof(struct kvaser_cmd_tx_can);
 		cmd->u.tx_can.channel = priv->channel;
 
-		switch (dev->card_data.leaf.family) {
+		switch (dev->driver_info->family) {
 		case KVASER_LEAF:
 			cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags;
 			break;
@@ -551,7 +551,7 @@ static int kvaser_usb_leaf_get_software_
 	if (err)
 		return err;
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo);
 		break;
@@ -598,7 +598,7 @@ static int kvaser_usb_leaf_get_card_info
 
 	dev->nchannels = cmd.u.cardinfo.nchannels;
 	if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES ||
-	    (dev->card_data.leaf.family == KVASER_USBCAN &&
+	    (dev->driver_info->family == KVASER_USBCAN &&
 	     dev->nchannels > MAX_USBCAN_NET_DEVICES))
 		return -EINVAL;
 
@@ -734,7 +734,7 @@ kvaser_usb_leaf_rx_error_update_can_stat
 	    new_state < CAN_STATE_BUS_OFF)
 		priv->can.can_stats.restarts++;
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		if (es->leaf.error_factor) {
 			priv->can.can_stats.bus_error++;
@@ -813,7 +813,7 @@ static void kvaser_usb_leaf_rx_error(con
 		}
 	}
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		if (es->leaf.error_factor) {
 			cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
@@ -1005,7 +1005,7 @@ static void kvaser_usb_leaf_rx_can_msg(c
 	stats = &priv->netdev->stats;
 
 	if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) &&
-	    (dev->card_data.leaf.family == KVASER_LEAF &&
+	    (dev->driver_info->family == KVASER_LEAF &&
 	     cmd->id == CMD_LEAF_LOG_MESSAGE)) {
 		kvaser_usb_leaf_leaf_rx_error(dev, cmd);
 		return;
@@ -1021,7 +1021,7 @@ static void kvaser_usb_leaf_rx_can_msg(c
 		return;
 	}
 
-	switch (dev->card_data.leaf.family) {
+	switch (dev->driver_info->family) {
 	case KVASER_LEAF:
 		rx_data = cmd->u.leaf.rx_can.data;
 		break;
@@ -1036,7 +1036,7 @@ static void kvaser_usb_leaf_rx_can_msg(c
 		return;
 	}
 
-	if (dev->card_data.leaf.family == KVASER_LEAF && cmd->id ==
+	if (dev->driver_info->family == KVASER_LEAF && cmd->id ==
 	    CMD_LEAF_LOG_MESSAGE) {
 		cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id);
 		if (cf->can_id & KVASER_EXTENDED_FRAME)
@@ -1133,14 +1133,14 @@ static void kvaser_usb_leaf_handle_comma
 		break;
 
 	case CMD_LEAF_LOG_MESSAGE:
-		if (dev->card_data.leaf.family != KVASER_LEAF)
+		if (dev->driver_info->family != KVASER_LEAF)
 			goto warn;
 		kvaser_usb_leaf_rx_can_msg(dev, cmd);
 		break;
 
 	case CMD_CHIP_STATE_EVENT:
 	case CMD_CAN_ERROR_EVENT:
-		if (dev->card_data.leaf.family == KVASER_LEAF)
+		if (dev->driver_info->family == KVASER_LEAF)
 			kvaser_usb_leaf_leaf_rx_error(dev, cmd);
 		else
 			kvaser_usb_leaf_usbcan_rx_error(dev, cmd);
@@ -1152,12 +1152,12 @@ static void kvaser_usb_leaf_handle_comma
 
 	/* Ignored commands */
 	case CMD_USBCAN_CLOCK_OVERFLOW_EVENT:
-		if (dev->card_data.leaf.family != KVASER_USBCAN)
+		if (dev->driver_info->family != KVASER_USBCAN)
 			goto warn;
 		break;
 
 	case CMD_FLUSH_QUEUE_REPLY:
-		if (dev->card_data.leaf.family != KVASER_LEAF)
+		if (dev->driver_info->family != KVASER_LEAF)
 			goto warn;
 		break;
 
author maintainer
#177 lore raw

PATCH 169/230 can: kvaser_usb: kvaser_usb_leaf: fix CAN clock frequency regression

In reply to Greg Kroah-Hartman

From: Jimmy Assarsson <[email protected]>

commit e6c80e601053ffdac5709f11ff3ec1e19ed05f7b upstream.

The firmware of M32C based Leaf devices expects bittiming parameters calculated for 16MHz clock. Since we use the actual clock frequency of the device, the device may end up with wrong bittiming parameters, depending on user requested parameters.

This regression affects M32C based Leaf devices with non-16MHz clock.

Fixes a8b513b824e4 ("can: kvaser_usb: get CAN clock frequency from device")
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h      |    1 
 drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c |   33 ++++++++++++++---------
 drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c |   25 +++++++++++------
 3 files changed, 38 insertions(+), 21 deletions(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb.h +1 -0
@@ -38,6 +38,7 @@
 /* Kvaser USB device quirks */
 #define KVASER_USB_QUIRK_HAS_SILENT_MODE	BIT(0)
 #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS	BIT(1)
+#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ	BIT(2)
 
 /* Device capabilities */
 #define KVASER_USB_CAP_BERR_CAP			0x01
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +21 -12
@@ -101,26 +101,33 @@ static const struct kvaser_usb_driver_in
 };
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = {
-	.quirks = 0,
+	.quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
 	.family = KVASER_LEAF,
 	.ops = &kvaser_usb_leaf_dev_ops,
 };
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = {
-	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS,
+	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
+		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
 	.family = KVASER_LEAF,
 	.ops = &kvaser_usb_leaf_dev_ops,
 };
 
 static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = {
 	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |
-		  KVASER_USB_QUIRK_HAS_SILENT_MODE,
+		  KVASER_USB_QUIRK_HAS_SILENT_MODE |
+		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,
 	.family = KVASER_LEAF,
 	.ops = &kvaser_usb_leaf_dev_ops,
 };
 
+static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {
+	.quirks = 0,
+	.ops = &kvaser_usb_leaf_dev_ops,
+};
+
 static const struct usb_device_id kvaser_usb_table[] = {
-	/* Leaf USB product IDs */
+	/* Leaf M32C USB product IDs */
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID),
 		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID),
@@ -161,22 +168,24 @@ static const struct usb_device_id kvaser
 		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID),
 		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },
+
+	/* Leaf i.MX28 USB product IDs */
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID),
-		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },
+		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },
 
 	/* USBCANII USB product IDs */
 	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID),
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +16 -9
@@ -525,16 +525,23 @@ static void kvaser_usb_leaf_get_software
 	dev->fw_version = le32_to_cpu(softinfo->fw_version);
 	dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx);
 
-	switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
-	case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
+	if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) {
+		/* Firmware expects bittiming parameters calculated for 16MHz
+		 * clock, regardless of the actual clock
+		 */
 		dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
-		break;
-	case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
-		dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
-		break;
-	case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
-		dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
-		break;
+	} else {
+		switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) {
+		case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK:
+			dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz;
+			break;
+		case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK:
+			dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz;
+			break;
+		case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK:
+			dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz;
+			break;
+		}
 	}
 }
 
author maintainer
#178 lore raw

PATCH 170/230 can: kvaser_usb: kvaser_usb_leaf: fix bittiming limits

In reply to Greg Kroah-Hartman

From: Jimmy Assarsson <[email protected]>

commit b3b6df2c56d80b8c6740433cff5f016668b8de70 upstream.

Use correct bittiming limits depending on device. For devices based on USBcanII, Leaf M32C or Leaf i.MX28.

Fixes 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices")
Fixes b4f20130af23 ("can: kvaser_usb: add support for Kvaser Leaf v2 and usb mini PCIe")
Fixes f5d4abea3ce0 ("can: kvaser_usb: Add support for the USBcan-II family")
[mkl: remove stray netlink.h include]
[mkl: keep struct can_bittiming_const kvaser_usb_flexc_bittiming_const in kvaser_usb_hydra.c]
---
 drivers/net/can/usb/kvaser_usb/kvaser_usb.h       |    2 
 drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c |    4 -
 drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c  |   76 ++++++++++++----------
 3 files changed, 47 insertions(+), 35 deletions(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb.h +2 -0
@@ -188,4 +188,6 @@ int kvaser_usb_send_cmd_async(struct kva
 
 int kvaser_usb_can_rx_over_error(struct net_device *netdev);
 
+extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const;
+
 #endif /* KVASER_USB_H */
drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +2 -2
@@ -373,7 +373,7 @@ static const struct can_bittiming_const
 	.brp_inc = 1,
 };
 
-static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = {
+const struct can_bittiming_const kvaser_usb_flexc_bittiming_const = {
 	.name = "kvaser_usb_flex",
 	.tseg1_min = 4,
 	.tseg1_max = 16,
@@ -2052,7 +2052,7 @@ static const struct kvaser_usb_dev_cfg k
 		.freq = 24000000,
 	},
 	.timestamp_freq = 1,
-	.bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c,
+	.bittiming_const = &kvaser_usb_flexc_bittiming_const,
 };
 
 static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = {
drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +43 -33

131 lines not on this page · raw message

author maintainer
#179 lore raw

PATCH 171/230 xfs: remove incorrect ASSERT in xfs_rename

In reply to Greg Kroah-Hartman

From: Eric Sandeen <[email protected]>

commit e445976537ad139162980bee015b7364e5b64fff upstream.

This ASSERT in xfs_rename is a) incorrect, because (RENAME_WHITEOUT|RENAME_NOREPLACE) is a valid combination, and
b) unnecessary, because actual invalid flag combinations are already handled at the vfs level in do_renameat2() before we get called. So, remove it.

---
 fs/xfs/xfs_inode.c |    1 -
 1 file changed, 1 deletion(-)
fs/xfs/xfs_inode.c +0 -1
@@ -3128,7 +3128,6 @@ xfs_rename(
 	 * appropriately.
 	 */
 	if (flags & RENAME_WHITEOUT) {
-		ASSERT(!(flags & (RENAME_NOREPLACE | RENAME_EXCHANGE)));
 		error = xfs_rename_alloc_whiteout(mnt_userns, target_dp, &wip);
 		if (error)
 			return error;
author maintainer
#180 lore raw

PATCH 172/230 Revert "serial: sc16is7xx: Clear RS485 bits in the shutdown"

In reply to Greg Kroah-Hartman

From: Hui Wang <[email protected]>

commit 41c606879f89623dd5269eaffea640b915e9e17c upstream.

This reverts commit 927728a34f11b5a27f4610bdb7068317d6fdc72a.

Once the uart_port->rs485->flag is set to SER_RS485_ENABLED, the port should always work in RS485 mode. If users want the port to leave RS485 mode, they need to call ioctl() to clear SER_RS485_ENABLED.

So here we shouldn't clear the RS485 bits in the shutdown().

Fixes 927728a34f11 ("serial: sc16is7xx: Clear RS485 bits in the shutdown")
---
 drivers/tty/serial/sc16is7xx.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/tty/serial/sc16is7xx.c +2 -4
@@ -1055,12 +1055,10 @@ static void sc16is7xx_shutdown(struct ua
 
 	/* Disable all interrupts */
 	sc16is7xx_port_write(port, SC16IS7XX_IER_REG, 0);
-	/* Disable TX/RX, clear auto RS485 and RTS invert */
+	/* Disable TX/RX */
 	sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG,
 			      SC16IS7XX_EFCR_RXDISABLE_BIT |
-			      SC16IS7XX_EFCR_TXDISABLE_BIT |
-			      SC16IS7XX_EFCR_AUTO_RS485_BIT |
-			      SC16IS7XX_EFCR_RTS_INVERT_BIT,
+			      SC16IS7XX_EFCR_TXDISABLE_BIT,
 			      SC16IS7XX_EFCR_RXDISABLE_BIT |
 			      SC16IS7XX_EFCR_TXDISABLE_BIT);
 
author maintainer
#181 lore raw

PATCH 173/230 btrfs: fix error pointer dereference in btrfs_ioctl_rm_dev_v2()

In reply to Greg Kroah-Hartman

From: Dan Carpenter <[email protected]>

commit d815b3f2f273537cb8afaf5ab11a46851f6c03e5 upstream.

If memdup_user() fails the error handing will crash when it tries to kfree() an error pointer. Just return directly because there is no cleanup required.

Fixes 1a15eb724aae ("btrfs: use btrfs_get_dev_args_from_path in dev removal ioctls")
---
 fs/btrfs/ioctl.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
fs/btrfs/ioctl.c +2 -4
@@ -3231,10 +3231,8 @@ static long btrfs_ioctl_rm_dev_v2(struct
 		return -EPERM;
 
 	vol_args = memdup_user(arg, sizeof(*vol_args));
-	if (IS_ERR(vol_args)) {
-		ret = PTR_ERR(vol_args);
-		goto out;
-	}
+	if (IS_ERR(vol_args))
+		return PTR_ERR(vol_args);
 
 	if (vol_args->flags & ~BTRFS_DEVICE_REMOVE_ARGS_MASK) {
 		ret = -EOPNOTSUPP;
author maintainer
#182 lore raw

PATCH 174/230 virtio-blk: modify the value type of num in virtio_queue_rq()

In reply to Greg Kroah-Hartman

From: Ye Guojin <[email protected]>

commit 0466a39bd0b6c462338f10d18076703d14a552de upstream.

This was found by coccicheck:
./drivers/block/virtio_blk.c, 334, 14-17, WARNING Unsigned expression compared with zero num < 0

---
 drivers/block/virtio_blk.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/block/virtio_blk.c +1 -1
@@ -308,7 +308,7 @@ static blk_status_t virtio_queue_rq(stru
 	struct request *req = bd->rq;
 	struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
 	unsigned long flags;
-	unsigned int num;
+	int num;
 	int qid = hctx->queue_num;
 	int err;
 	bool notify = false;
author maintainer
#183 lore raw

PATCH 175/230 btrfs: fix use of uninitialized variable at rm device ioctl

In reply to Greg Kroah-Hartman

From: Tom Rix <[email protected]>

commit 37b4599547e324589e011c20f74b021d6d25cb7f upstream.

Clang static analysis reports this problem ioctl.c:3333:8: warning: 3rd function call argument is an
uninitialized value
ret = exclop_start_or_cancel_reloc(fs_info,

cancel is only set in one branch of an if-check and is always used. So initialize to false.

Fixes 1a15eb724aae ("btrfs: use btrfs_get_dev_args_from_path in dev removal ioctls")
---
 fs/btrfs/ioctl.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/btrfs/ioctl.c +1 -1
@@ -3291,7 +3291,7 @@ static long btrfs_ioctl_rm_dev(struct fi
 	struct block_device *bdev = NULL;
 	fmode_t mode;
 	int ret;
-	bool cancel;
+	bool cancel = false;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
author maintainer
#184 lore raw

PATCH 176/230 tty: n_gsm: fix encoding of command/response bit

In reply to Greg Kroah-Hartman

From: [email protected] <[email protected]>

commit 57435c42400ec147a527b2313188b649e81e449e upstream.

n_gsm is based on the 3GPP 07.010 and its newer version is the 3GPP 27.010.
See https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1516
The changes from 07.010 to 27.010 are non-functional. Therefore, I refer to
the newer 27.010 here. Chapter 5.2.1.2 describes the encoding of the
C/R (command/response) bit. Table 1 shows that the actual encoding of the
C/R bit is inverted if the associated frame is sent by the responder.

The referenced commit fixed here further broke the internal meaning of this bit in the outgoing path by always setting the C/R bit regardless of the frame type.

This patch fixes both by setting the C/R bit always consistently for command (1) and response (0) frames and inverting it later for the responder where necessary. The meaning of this bit in the debug output is being preserved and shows the bit as if it was encoded by the initiator. This reflects only the frame type rather than the encoded combination of communication side and frame type.

Fixes cc0f42122a7e ("tty: n_gsm: Modify CR,PF bit when config requester")
---
 drivers/tty/n_gsm.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
drivers/tty/n_gsm.c +10 -6
@@ -471,7 +471,7 @@ static void gsm_hex_dump_bytes(const cha
  *	gsm_print_packet	-	display a frame for debug
  *	@hdr: header to print before decode
  *	@addr: address EA from the frame
- *	@cr: C/R bit from the frame
+ *	@cr: C/R bit seen as initiator
  *	@control: control including PF bit
  *	@data: following data bytes
  *	@dlen: length of data
@@ -571,7 +571,7 @@ static int gsm_stuff_frame(const u8 *inp
  *	gsm_send	-	send a control frame
  *	@gsm: our GSM mux
  *	@addr: address for control frame
- *	@cr: command/response bit
+ *	@cr: command/response bit seen as initiator
  *	@control:  control byte including PF bit
  *
  *	Format up and transmit a control frame. These do not go via the
@@ -586,11 +586,15 @@ static void gsm_send(struct gsm_mux *gsm
 	int len;
 	u8 cbuf[10];
 	u8 ibuf[3];
+	int ocr;
+
+	/* toggle C/R coding if not initiator */
+	ocr = cr ^ (gsm->initiator ? 0 : 1);
 
 	switch (gsm->encoding) {
 	case 0:
 		cbuf[0] = GSM0_SOF;
-		cbuf[1] = (addr << 2) | (cr << 1) | EA;
+		cbuf[1] = (addr << 2) | (ocr << 1) | EA;
 		cbuf[2] = control;
 		cbuf[3] = EA;	/* Length of data = 0 */
 		cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
@@ -600,7 +604,7 @@ static void gsm_send(struct gsm_mux *gsm
 	case 1:
 	case 2:
 		/* Control frame + packing (but not frame stuffing) in mode 1 */
-		ibuf[0] = (addr << 2) | (cr << 1) | EA;
+		ibuf[0] = (addr << 2) | (ocr << 1) | EA;
 		ibuf[1] = control;
 		ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
 		/* Stuffing may double the size worst case */
@@ -630,7 +634,7 @@ static void gsm_send(struct gsm_mux *gsm
 
 static inline void gsm_response(struct gsm_mux *gsm, int addr, int control)
 {
-	gsm_send(gsm, addr, 1, control);
+	gsm_send(gsm, addr, 0, control);
 }
 
 /**
@@ -1875,10 +1879,10 @@ static void gsm_queue(struct gsm_mux *gs
 		goto invalid;
 
 	cr = gsm->address & 1;		/* C/R bit */
+	cr ^= gsm->initiator ? 0 : 1;	/* Flip so 1 always means command */
 
 	gsm_print_packet("<--", address, cr, gsm->control, gsm->buf, gsm->len);
 
-	cr ^= 1 - gsm->initiator;	/* Flip so 1 always means command */
 	dlci = gsm->dlci[address];
 
 	switch (gsm->control) {
author maintainer
#185 lore raw

PATCH 177/230 ARM: meson: Fix refcount leak in meson_smp_prepare_cpus

In reply to Greg Kroah-Hartman

From: Miaoqian Lin <[email protected]>

[ Upstream commit 34d2cd3fccced12b958b8848e3eff0ee4296764c ]

of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak.

Fixes d850f3e5d296 ("ARM: meson: Add SMP bringup code for Meson8 and Meson8b")
---
 arch/arm/mach-meson/platsmp.c | 2 ++
 1 file changed, 2 insertions(+)
arch/arm/mach-meson/platsmp.c +2 -0
index 4b8ad728bb42..32ac60b89fdc 100644
@@ -71,6 +71,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible,
 	}
 
 	sram_base = of_iomap(node, 0);
+	of_node_put(node);
 	if (!sram_base) {
 		pr_err("Couldn't map SRAM registers\n");
 		return;
@@ -91,6 +92,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible,
 	}
 
 	scu_base = of_iomap(node, 0);
+	of_node_put(node);
 	if (!scu_base) {
 		pr_err("Couldn't map SCU registers\n");
 		return;
Signature · 1 line
2.35.1
author maintainer
#186 lore raw

PATCH 178/230 pinctrl: sunxi: a83t: Fix NAND function name for some pins

In reply to Greg Kroah-Hartman

From: Samuel Holland <[email protected]>

[ Upstream commit aaefa29270d9551b604165a08406543efa9d16f5 ]

The other NAND pins on Port C use the "nand0" function name. "nand0" also matches all of the other Allwinner SoCs.

Fixes 4730f33f0d82 ("pinctrl: sunxi: add allwinner A83T PIO controller support")
---
 drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +5 -5
index 4ada80317a3b..b5c1a8f363f3 100644
@@ -158,26 +158,26 @@ static const struct sunxi_desc_pin sun8i_a83t_pins[] = {
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ6 */
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ6 */
 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D6 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQ7 */
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQ7 */
 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* D7 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand"),		/* DQS */
+		  SUNXI_FUNCTION(0x2, "nand0"),		/* DQS */
 		  SUNXI_FUNCTION(0x3, "mmc2")),		/* RST */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand")),		/* CE2 */
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* CE2 */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
 		  SUNXI_FUNCTION(0x1, "gpio_out"),
-		  SUNXI_FUNCTION(0x2, "nand")),		/* CE3 */
+		  SUNXI_FUNCTION(0x2, "nand0")),	/* CE3 */
 	/* Hole */
 	SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2),
 		  SUNXI_FUNCTION(0x0, "gpio_in"),
Signature · 1 line
2.35.1
author maintainer
#187 lore raw

PATCH 179/230 ASoC: rt711: Add endianness flag in snd_soc_component_driver

In reply to Greg Kroah-Hartman

From: Charles Keepax <[email protected]>

[ Upstream commit 33f06beac3ade10834a82ad4105dcd91d4b00d61 ]

The endianness flag is used on the CODEC side to specify an ambivalence to endian, typically because it is lost over the hardware link. This device receives audio over a SoundWire DAI and as such should have endianness applied.

---
 sound/soc/codecs/rt711.c | 1 +
 1 file changed, 1 insertion(+)
sound/soc/codecs/rt711.c +1 -0
index a7c5608a0ef8..9cc7283a19c2 100644
@@ -943,6 +943,7 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
 	.num_dapm_routes = ARRAY_SIZE(rt711_audio_map),
 	.set_jack = rt711_set_jack_detect,
 	.remove = rt711_remove,
+	.endianness = 1,
 };
 
 static int rt711_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
Signature · 1 line
2.35.1
author maintainer
#188 lore raw

PATCH 180/230 ASoC: rt711-sdca: Add endianness flag in snd_soc_component_driver

In reply to Greg Kroah-Hartman

From: Charles Keepax <[email protected]>

[ Upstream commit 3e50a5001055d79c04ea1c79fe4b4ff937a3339c ]

The endianness flag is used on the CODEC side to specify an ambivalence to endian, typically because it is lost over the hardware link. This device receives audio over a SoundWire DAI and as such should have endianness applied.

---
 sound/soc/codecs/rt711-sdca.c | 1 +
 1 file changed, 1 insertion(+)
sound/soc/codecs/rt711-sdca.c +1 -0
index 2e992589f1e4..b168e9303ea9 100644
@@ -1208,6 +1208,7 @@ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = {
 	.num_dapm_routes = ARRAY_SIZE(rt711_sdca_audio_map),
 	.set_jack = rt711_sdca_set_jack_detect,
 	.remove = rt711_sdca_remove,
+	.endianness = 1,
 };
 
 static int rt711_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
Signature · 1 line
2.35.1
author maintainer
#189 lore raw

PATCH 181/230 ASoC: codecs: rt700/rt711/rt711-sdca: resume bus/codec in .set_jack_detect

In reply to Greg Kroah-Hartman

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

[ Upstream commit 40737057b48f1b4db67b0d766b95c87ba8fc5e03 ]

The .set_jack_detect() codec component callback is invoked during card registration, which happens when the machine driver is probed.

The issue is that this callback can race with the bus suspend/resume, and IO timeouts can happen. This can be reproduced very easily if the machine driver is 'blacklisted' and manually probed after the bus suspends. The bus and codec need to be re-initialized using pm_runtime helpers.

Previous contributions tried to make sure accesses to the bus during the .set_jack_detect() component callback only happen when the bus is active. This was done by changing the regcache status on a component remove. This is however a layering violation, the regcache status should only be modified on device probe, suspend and resume. The component probe/remove should not modify how the device regcache is handled. This solution also didn't handle all the possible race conditions, and the RT700 headset codec was not handled.

This patch tries to resume the codec device before handling the jack initializations. In case the codec has not yet been initialized, pm_runtime may not be enabled yet, so we don't squelch the -EACCES error code and only stop the jack information. When the codec reports as attached, the jack initialization will proceed as usual.

Fixes 7ad4d237e7c4a ('ASoC: rt711-sdca: Add RT711 SDCA vendor-specific driver')
Fixes 899b12542b089 ('ASoC: rt711: add snd_soc_component remove callback')
---
 sound/soc/codecs/rt700.c      | 16 +++++++++++++---
 sound/soc/codecs/rt711-sdca.c | 26 ++++++++++++++------------
 sound/soc/codecs/rt711.c      | 24 +++++++++++++-----------
 3 files changed, 40 insertions(+), 26 deletions(-)
sound/soc/codecs/rt700.c +13 -3
index 921382724f9c..614a40247679 100644
@@ -315,17 +315,27 @@ static int rt700_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack, void *data)
 {
 	struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component);
+	int ret;
 
 	rt700->hs_jack = hs_jack;
 
-	if (!rt700->hw_init) {
-		dev_dbg(&rt700->slave->dev,
-			"%s hw_init not ready yet\n", __func__);
+	ret = pm_runtime_resume_and_get(component->dev);
+	if (ret < 0) {
+		if (ret != -EACCES) {
+			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
+			return ret;
+		}
+
+		/* pm_runtime not enabled yet */
+		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
 		return 0;
 	}
 
 	rt700_jack_init(rt700);
 
+	pm_runtime_mark_last_busy(component->dev);
+	pm_runtime_put_autosuspend(component->dev);
+
 	return 0;
 }
 
sound/soc/codecs/rt711-sdca.c +14 -12
index b168e9303ea9..c15fb98eac86 100644
@@ -487,16 +487,27 @@ static int rt711_sdca_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack, void *data)
 {
 	struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
+	int ret;
 
 	rt711->hs_jack = hs_jack;
 
-	if (!rt711->hw_init) {
-		dev_dbg(&rt711->slave->dev,
-			"%s hw_init not ready yet\n", __func__);
+	ret = pm_runtime_resume_and_get(component->dev);
+	if (ret < 0) {
+		if (ret != -EACCES) {
+			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
+			return ret;
+		}
+
+		/* pm_runtime not enabled yet */
+		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
 		return 0;
 	}
 
 	rt711_sdca_jack_init(rt711);
+
+	pm_runtime_mark_last_busy(component->dev);
+	pm_runtime_put_autosuspend(component->dev);
+
 	return 0;
 }
 
@@ -1190,14 +1201,6 @@ static int rt711_sdca_probe(struct snd_soc_component *component)
 	return 0;
 }
 
-static void rt711_sdca_remove(struct snd_soc_component *component)
-{
-	struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
-
-	regcache_cache_only(rt711->regmap, true);
-	regcache_cache_only(rt711->mbq_regmap, true);
-}
-
 static const struct snd_soc_component_driver soc_sdca_dev_rt711 = {
 	.probe = rt711_sdca_probe,
 	.controls = rt711_sdca_snd_controls,
@@ -1207,7 +1210,6 @@ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = {
 	.dapm_routes = rt711_sdca_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(rt711_sdca_audio_map),
 	.set_jack = rt711_sdca_set_jack_detect,
-	.remove = rt711_sdca_remove,
 	.endianness = 1,
 };
 
sound/soc/codecs/rt711.c +13 -11
index 9cc7283a19c2..fafb0ba8349f 100644
@@ -450,17 +450,27 @@ static int rt711_set_jack_detect(struct snd_soc_component *component,
 	struct snd_soc_jack *hs_jack, void *data)
 {
 	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
+	int ret;
 
 	rt711->hs_jack = hs_jack;
 
-	if (!rt711->hw_init) {
-		dev_dbg(&rt711->slave->dev,
-			"%s hw_init not ready yet\n", __func__);
+	ret = pm_runtime_resume_and_get(component->dev);
+	if (ret < 0) {
+		if (ret != -EACCES) {
+			dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret);
+			return ret;
+		}
+
+		/* pm_runtime not enabled yet */
+		dev_dbg(component->dev,	"%s: skipping jack init for now\n", __func__);
 		return 0;
 	}
 
 	rt711_jack_init(rt711);
 
+	pm_runtime_mark_last_busy(component->dev);
+	pm_runtime_put_autosuspend(component->dev);
+
 	return 0;
 }
 
@@ -925,13 +935,6 @@ static int rt711_probe(struct snd_soc_component *component)
 	return 0;
 }
 
-static void rt711_remove(struct snd_soc_component *component)
-{
-	struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component);
-
-	regcache_cache_only(rt711->regmap, true);
-}
-
 static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
 	.probe = rt711_probe,
 	.set_bias_level = rt711_set_bias_level,
@@ -942,7 +945,6 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = {
 	.dapm_routes = rt711_audio_map,
 	.num_dapm_routes = ARRAY_SIZE(rt711_audio_map),
 	.set_jack = rt711_set_jack_detect,
-	.remove = rt711_remove,
 	.endianness = 1,
 };
 
Signature · 1 line
2.35.1
author maintainer
#190 lore raw

PATCH 182/230 arm64: dts: qcom: msm8994: Fix CPU6/7 reg values

In reply to Greg Kroah-Hartman

From: Konrad Dybcio <[email protected]>

[ Upstream commit 47bf59c4755930f616dd90c8c6a85f40a6d347ea ]

CPU6 and CPU7 were mistakengly pointing to CPU5 reg. Fix it.

Fixes 02d8091bbca0 ("arm64: dts: qcom: msm8994: Add a proper CPU map")
---
 arch/arm64/boot/dts/qcom/msm8994.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/msm8994.dtsi +2 -2
index 3c27671c8b5c..a8dc8163ee82 100644
@@ -93,7 +93,7 @@
 		CPU6: cpu@102 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a57";
-			reg = <0x0 0x101>;
+			reg = <0x0 0x102>;
 			enable-method = "psci";
 			next-level-cache = <&L2_1>;
 		};
@@ -101,7 +101,7 @@
 		CPU7: cpu@103 {
 			device_type = "cpu";
 			compatible = "arm,cortex-a57";
-			reg = <0x0 0x101>;
+			reg = <0x0 0x103>;
 			enable-method = "psci";
 			next-level-cache = <&L2_1>;
 		};
Signature · 1 line
2.35.1
author maintainer
#191 lore raw

PATCH 183/230 arm64: dts: qcom: sdm845: use dispcc AHB clock for mdss node

In reply to Greg Kroah-Hartman

From: Dmitry Baryshkov <[email protected]>

[ Upstream commit 3ba500dee327e0261e728edec8a4f2f563d2760c ]

It was noticed that on sdm845 after an MDSS suspend/resume cycle the driver can not read HW_REV registers properly (they will return 0 instead). Chaning the "iface" clock from <&gcc GCC_DISP_AHB_CLK> to <&dispcc DISP_CC_MDSS_AHB_CLK> fixes the issue.

Fixes 08c2a076d18f ("arm64: dts: qcom: sdm845: Add dpu to sdm845 dts file")
---
 arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/qcom/sdm845.dtsi +1 -1
index d20eacfc1017..ea7a272d267a 100644
@@ -4147,7 +4147,7 @@
 
 			power-domains = <&dispcc MDSS_GDSC>;
 
-			clocks = <&gcc GCC_DISP_AHB_CLK>,
+			clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>,
 				 <&dispcc DISP_CC_MDSS_MDP_CLK>;
 			clock-names = "iface", "core";
 
Signature · 1 line
2.35.1
author maintainer
#192 lore raw

PATCH 184/230 ARM: mxs_defconfig: Enable the framebuffer

In reply to Greg Kroah-Hartman

From: Fabio Estevam <[email protected]>

[ Upstream commit b10ef5f2ddb3a5a22ac0936c8d91a50ac5e55e77 ]

Currently, when booting Linux on a imx28-evk board there is no display activity.

Enable CONFIG_FB which is nowadays required for CONFIG_DRM_PANEL_LVDS, CONFIG_DRM_PANEL_SIMPLE, CONFIG_DRM_PANEL_SEIKO_43WVF1G, CONFIG_FB_MODE_HELPERS, CONFIG_BACKLIGHT_PWM, CONFIG_BACKLIGHT_GPIO, CONFIG_FRAMEBUFFER_CONSOLE, CONFIG_LOGO, CONFIG_FONTS, CONFIG_FONT_8x8 and CONFIG_FONT_8x16.

Based on commit c54467482ffd ("ARM: imx_v6_v7_defconfig: enable fb").

Fixes f611b1e7624c ("drm: Avoid circular dependencies for CONFIG_FB")
---
 arch/arm/configs/mxs_defconfig | 1 +
 1 file changed, 1 insertion(+)
arch/arm/configs/mxs_defconfig +1 -0
index ca32446b187f..f53086ddc48b 100644
@@ -93,6 +93,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
 CONFIG_DRM_MXSFB=y
+CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
Signature · 1 line
2.35.1
author maintainer
#193 lore raw

PATCH 185/230 arm64: dts: imx8mp-evk: correct mmc pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 01785f1f156511c4f285786b4192245d4f476bf1 ]

According to RM bit layout, BIT3 and BIT0 are reserved.

  8  7   6   5   4   3  2 1  0
 PE HYS PUE ODE FSEL X  DSE  X

Not set reserved bit.

Fixes 9e847693c6f3 ("arm64: dts: freescale: Add i.MX8MP EVK board support")
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-evk.dts +4 -4
index 7b99fad6e4d6..3c4369d6468c 100644
@@ -377,7 +377,7 @@
 
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x41
+			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
 		>;
 	};
 
@@ -402,7 +402,7 @@
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d0
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d0
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d0
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 
@@ -414,7 +414,7 @@
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d4
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d4
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d4
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
 		>;
 	};
 
@@ -426,7 +426,7 @@
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d6
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d6
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d6
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#194 lore raw

PATCH 186/230 arm64: dts: imx8mp-evk: correct the uart2 pinctl value

In reply to Greg Kroah-Hartman

From: Sherry Sun <[email protected]>

[ Upstream commit 2d4fb72b681205eed4553d8802632bd3270be3ba ]

According to the IOMUXC_SW_PAD_CTL_PAD_UART2_RXD/TXD register define in imx8mp RM, bit0 and bit3 are reserved, and the uart2 rx/tx pin should enable the pull up, so need to set bit8 to 1. The original pinctl value 0x49 is incorrect and needs to be changed to 0x140, same as uart1 and uart3.

Fixes 9e847693c6f3 ("arm64: dts: freescale: Add i.MX8MP EVK board support")
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-evk.dts +2 -2
index 3c4369d6468c..3f424a8937f1 100644
@@ -383,8 +383,8 @@
 
 	pinctrl_uart2: uart2grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX	0x49
-			MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX	0x49
+			MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX	0x140
+			MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX	0x140
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#195 lore raw

PATCH 187/230 arm64: dts: imx8mp-evk: correct gpio-led pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit b838582ab8d5fb11b2c0275056a9f34e1d94fece ]

0x19 is not a valid setting. According to RM bit layout, BIT3 and BIT0 are reserved.

  8  7   6   5   4   3  2 1  0
 PE HYS PUE ODE FSEL X  DSE  X

Correct setting with PE PUE set, DSE set to 0.

Fixes 50d336b12f34 ("arm64: dts: imx8mp-evk: Add GPIO LED support")
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mp-evk.dts +1 -1
index 3f424a8937f1..be3b01b5e159 100644
@@ -351,7 +351,7 @@
 
 	pinctrl_gpio_led: gpioledgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16	0x19
+			MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16	0x140
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#196 lore raw

PATCH 188/230 arm64: dts: imx8mp-evk: correct vbus pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit e2c00820a99c55c9bb40642d5818a904a1e0d664 ]

0x19 is not a valid setting. According to RM bit layout, BIT3 and BIT0 are reserved.

  8  7   6   5   4   3  2 1  0
 PE HYS PUE ODE FSEL X  DSE  X

Not set reserved bit.

Fixes 43da4f92a611 ("arm64: dts: imx8mp-evk: enable usb1 as host mode")
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/boot/dts/freescale/imx8mp-evk.dts +1 -1
index be3b01b5e159..c794e8662da8 100644
@@ -390,7 +390,7 @@
 
 	pinctrl_usb1_vbus: usb1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR	0x19
+			MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR	0x10
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#197 lore raw

PATCH 189/230 arm64: dts: imx8mp-evk: correct eqos pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit e6e1bc0ec9e8ad212fa46d8878a6e17cd31fdf7b ]

According to RM bit layout, BIT3 and BIT0 are reserved.

 8  7   6   5   4   3  2 1  0
PE HYS PUE ODE FSEL X  DSE  X

Although function is not broken, we should not set reserved bit.

Fixes dc6d5dc89bad ("arm64: dts: imx8mp-evk: enable EQOS ethernet")
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 30 ++++++++++----------
 1 file changed, 15 insertions(+), 15 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-evk.dts +15 -15
index c794e8662da8..33664c217673 100644
@@ -285,21 +285,21 @@
 &iomuxc {
 	pinctrl_eqos: eqosgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC				0x3
-			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO				0x3
-			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0			0x91
-			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1			0x91
-			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2			0x91
-			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3			0x91
-			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x91
-			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL			0x91
-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0			0x1f
-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1			0x1f
-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2			0x1f
-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3			0x1f
-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL			0x1f
-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x1f
-			MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22				0x19
+			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC				0x2
+			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO				0x2
+			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0			0x90
+			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1			0x90
+			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2			0x90
+			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3			0x90
+			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
+			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL			0x90
+			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0			0x16
+			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1			0x16
+			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2			0x16
+			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3			0x16
+			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL			0x16
+			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
+			MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22				0x10
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#198 lore raw

PATCH 190/230 arm64: dts: imx8mp-evk: correct I2C1 pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 05a7f43478e890513d571f36660bfedc1482a588 ]

According to RM bit layout, BIT3 and BIT0 are reserved.

 8  7   6   5   4   3  2 1  0
PE HYS PUE ODE FSEL X  DSE  X

Although function is not broken, we should not set reserved bit.

Fixes 5497bc2a2bff ("arm64: dts: imx8mp-evk: Add PMIC device")
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-evk.dts +2 -2
index 33664c217673..de6f3297fea4 100644
@@ -357,8 +357,8 @@
 
 	pinctrl_i2c1: i2c1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL		0x400001c3
-			MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA		0x400001c3
+			MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL		0x400001c2
+			MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA		0x400001c2
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#199 lore raw

PATCH 191/230 arm64: dts: imx8mp-evk: correct I2C3 pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 0836de513ebaae5f03014641eac996290d67493d ]

According to RM bit layout, BIT3 and BIT0 are reserved.

 8  7   6   5   4   3  2 1  0
PE HYS PUE ODE FSEL X  DSE  X

Although function is not broken, we should not set reserved bit.

Fixes 5e4a67ff7f69 ("arm64: dts: imx8mp-evk: Add i2c3 support")
---
 arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-evk.dts +2 -2
index de6f3297fea4..5c9fb39dd99e 100644
@@ -364,8 +364,8 @@
 
 	pinctrl_i2c3: i2c3grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL		0x400001c3
-			MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA		0x400001c3
+			MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL		0x400001c2
+			MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA		0x400001c2
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#200 lore raw

PATCH 192/230 arm64: dts: imx8mp-phyboard-pollux-rdk: correct uart pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit e266c155bd88e95f9b86379d6b0add6ac6e5452e ]

BIT3 and BIT0 are reserved bits, should not touch.

Fixes 846f752866bd ("arm64: dts: imx8mp-phyboard-pollux-rdk: Change debug UART")
---
 arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts +2 -2
index 984a6b9ded8d..e34076954897 100644
@@ -156,8 +156,8 @@
 
 	pinctrl_uart1: uart1grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x49
-			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x49
+			MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX	0x40
+			MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX	0x40
 		>;
 	};
 
Signature · 1 line
2.35.1
author maintainer
#201 lore raw

PATCH 193/230 arm64: dts: imx8mp-phyboard-pollux-rdk: correct eqos pad settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit bae4de618efe1c41d34aa2e6cef8b08e46256667 ]

BIT3 and BIT0 are reserved bits, should not touch.

Fixes 6f96852619d5 ("arm64: dts: freescale: Add support EQOS MAC on phyBOARD-Pollux-i.MX8MP")
---
 .../freescale/imx8mp-phyboard-pollux-rdk.dts  | 28 +++++++++----------
 1 file changed, 14 insertions(+), 14 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts +14 -14
index e34076954897..cefd3d36f93f 100644
@@ -116,20 +116,20 @@
 &iomuxc {
 	pinctrl_eqos: eqosgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC			0x3
-			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO			0x3
-			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0		0x91
-			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1		0x91
-			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x91
-			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x91
-			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x91
-			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x91
-			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x1f
-			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x1f
-			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x1f
-			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x1f
-			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x1f
-			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x1f
+			MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC			0x2
+			MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO			0x2
+			MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0		0x90
+			MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1		0x90
+			MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2		0x90
+			MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3		0x90
+			MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK	0x90
+			MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL		0x90
+			MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0		0x16
+			MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1		0x16
+			MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2		0x16
+			MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3		0x16
+			MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL		0x16
+			MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK	0x16
 			MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20			0x10
 		>;
 	};
Signature · 1 line
2.35.1
author maintainer
#202 lore raw

PATCH 194/230 arm64: dts: imx8mp-phyboard-pollux-rdk: correct i2c2 & mmc settings

In reply to Greg Kroah-Hartman

From: Peng Fan <[email protected]>

[ Upstream commit 242d8ee9111171a6e68249aaff62643c513be6ec ]

BIT3 and BIT0 are reserved bits, should not touch.

Fixes 88f7f6bcca37 ("arm64: dts: freescale: Add support for phyBOARD-Pollux-i.MX8MP")
---
 .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)
arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts +8 -8
index cefd3d36f93f..6aa720bafe28 100644
@@ -136,21 +136,21 @@
 
 	pinctrl_i2c2: i2c2grp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL		0x400001c3
-			MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA		0x400001c3
+			MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL		0x400001c2
+			MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA		0x400001c2
 		>;
 	};
 
 	pinctrl_i2c2_gpio: i2c2gpiogrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16	0x1e3
-			MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17	0x1e3
+			MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16	0x1e2
+			MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17	0x1e2
 		>;
 	};
 
 	pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp {
 		fsl,pins = <
-			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x41
+			MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19	0x40
 		>;
 	};
 
@@ -175,7 +175,7 @@
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d0
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d0
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d0
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 
@@ -187,7 +187,7 @@
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d4
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d4
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d4
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 
@@ -199,7 +199,7 @@
 			MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1	0x1d6
 			MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2	0x1d6
 			MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3	0x1d6
-			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc1
+			MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT	0xc0
 		>;
 	};
 };
Signature · 1 line
2.35.1
author maintainer
#203 lore raw

PATCH 195/230 pinctrl: sunxi: sunxi_pconf_set: use correct offset

In reply to Greg Kroah-Hartman

From: Andrei Lalaev <[email protected]>

[ Upstream commit cd4c1e65a32afd003b08ad4aafe1e4d3e4e8e61b ]

Some Allwinner SoCs have 2 pinctrls (PIO and R_PIO). Previous implementation used absolute pin numbering and it was incorrect for R_PIO pinctrl.
It's necessary to take into account the base pin number.

---
 drivers/pinctrl/sunxi/pinctrl-sunxi.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/pinctrl/sunxi/pinctrl-sunxi.c +2 -0
index ce3f9ea41511..1431ab21aca6 100644
@@ -544,6 +544,8 @@ static int sunxi_pconf_set(struct pinctrl_dev *pctldev, unsigned pin,
 	struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev);
 	int i;
 
+	pin -= pctl->desc->pin_base;
+
 	for (i = 0; i < num_configs; i++) {
 		enum pin_config_param param;
 		unsigned long flags;
Signature · 1 line
2.35.1
author maintainer
#204 lore raw

PATCH 196/230 arm64: dts: qcom: msm8992-*: Fix vdd_lvs1_2-supply typo

In reply to Greg Kroah-Hartman

From: Stephan Gerhold <[email protected]>

[ Upstream commit 5fb779558f1c97e2bf2794cb59553e569c38e2f9 ]

"make dtbs_check" complains about the missing "-supply" suffix for vdd_lvs1_2 which is clearly a typo, originally introduced in the msm8994-smd-rpm.dtsi file and apparently later copied to msm8992-xiaomi-libra.dts:

msm8992-lg-bullhead-rev-10/101.dtb: pm8994-regulators: 'vdd_lvs1_2' does not match any of the regexes:
'.*-supply$', '^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$', 'pinctrl-[0-9]+'

Quoted 1 line

From schema: regulator/qcom,smd-rpm-regulator.yaml

msm8992-xiaomi-libra.dtb: pm8994-regulators: 'vdd_lvs1_2'
does not match any of the regexes:
'.*-supply$', '^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$', 'pinctrl-[0-9]+'

Quoted 1 line

From schema: regulator/qcom,smd-rpm-regulator.yaml

Cc Konrad Dybcio <[email protected]>
Fixes f3b2c99e73be ("arm64: dts: Enable onboard SDHCI on msm8992")
Fixes 0f5cdb31e850 ("arm64: dts: qcom: Add Xiaomi Libra (Mi 4C) device tree")
---
 arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts | 2 +-
 arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/qcom/msm8992-bullhead-rev-101.dts +1 -1
index 1ccca83292ac..c7d191dc6d4b 100644
@@ -74,7 +74,7 @@
 		vdd_l17_29-supply = <&vph_pwr>;
 		vdd_l20_21-supply = <&vph_pwr>;
 		vdd_l25-supply = <&pm8994_s5>;
-		vdd_lvs1_2 = <&pm8994_s4>;
+		vdd_lvs1_2-supply = <&pm8994_s4>;
 
 		/* S1, S2, S6 and S12 are managed by RPMPD */
 
arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts +1 -1
index 357d55496e75..a3d6340a0c55 100644
@@ -142,7 +142,7 @@
 		vdd_l17_29-supply = <&vph_pwr>;
 		vdd_l20_21-supply = <&vph_pwr>;
 		vdd_l25-supply = <&pm8994_s5>;
-		vdd_lvs1_2 = <&pm8994_s4>;
+		vdd_lvs1_2-supply = <&pm8994_s4>;
 
 		/* S1, S2, S6 and S12 are managed by RPMPD */
 
Signature · 1 line
2.35.1
author maintainer
#205 lore raw

PATCH 197/230 ARM: at91: pm: use proper compatible for sama5d2s rtc

In reply to Greg Kroah-Hartman

From: Claudiu Beznea <[email protected]>

[ Upstream commit ddc980da8043779119acaca106c6d9b445c9b65b ]

Use proper compatible strings for SAMA5D2's RTC IPs. This is necessary for configuring wakeup sources for ULP1 PM mode.

Fixes d7484f5c6b3b ("ARM: at91: pm: configure wakeup sources for ULP1 mode")
---
 arch/arm/mach-at91/pm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-at91/pm.c +1 -1
index 8711d6824c1f..cde99c9d0b2e 100644
@@ -146,7 +146,7 @@ static const struct wakeup_source_info ws_info[] = {
 
 static const struct of_device_id sama5d2_ws_ids[] = {
 	{ .compatible = "atmel,sama5d2-gem",		.data = &ws_info[0] },
-	{ .compatible = "atmel,at91rm9200-rtc",		.data = &ws_info[1] },
+	{ .compatible = "atmel,sama5d2-rtc",		.data = &ws_info[1] },
 	{ .compatible = "atmel,sama5d3-udc",		.data = &ws_info[2] },
 	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
Signature · 1 line
2.35.1
author maintainer
#206 lore raw

PATCH 198/230 ARM: at91: pm: use proper compatibles for sam9x60s rtc and rtt

In reply to Greg Kroah-Hartman

From: Claudiu Beznea <[email protected]>

[ Upstream commit 641522665dbb25ce117c78746df1aad8b58c80e5 ]

Use proper compatible strings for SAM9X60's RTC and RTT IPs. These are necessary for configuring wakeup sources for ULP1 PM mode.

Fixes eaedc0d379da ("ARM: at91: pm: add ULP1 support for SAM9X60")
---
 arch/arm/mach-at91/pm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mach-at91/pm.c +2 -2
index cde99c9d0b2e..cbad3609b783 100644
@@ -157,12 +157,12 @@ static const struct of_device_id sama5d2_ws_ids[] = {
 };
 
 static const struct of_device_id sam9x60_ws_ids[] = {
-	{ .compatible = "atmel,at91sam9x5-rtc",		.data = &ws_info[1] },
+	{ .compatible = "microchip,sam9x60-rtc",	.data = &ws_info[1] },
 	{ .compatible = "atmel,at91rm9200-ohci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
 	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
-	{ .compatible = "atmel,at91sam9260-rtt",	.data = &ws_info[4] },
+	{ .compatible = "microchip,sam9x60-rtt",	.data = &ws_info[4] },
 	{ .compatible = "cdns,sam9x60-macb",		.data = &ws_info[5] },
 	{ /* sentinel */ }
 };
Signature · 1 line
2.35.1
author maintainer
#207 lore raw

PATCH 199/230 ARM: at91: pm: use proper compatibles for sama7g5s rtc and rtt

In reply to Greg Kroah-Hartman

From: Claudiu Beznea <[email protected]>

[ Upstream commit 1c40169b35ad58906814d53a517ac92db3d20d5f ]

Use proper compatible strings for SAMA7G5's RTC and RTT IPs. These are necessary for configuring wakeup sources for ULP1 PM mode.

Fixes 6501330f9f5e ("ARM: at91: pm: add pm support for SAMA7G5")
---
 arch/arm/mach-at91/pm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/mach-at91/pm.c +2 -2
index cbad3609b783..ed1050404ef0 100644
@@ -168,13 +168,13 @@ static const struct of_device_id sam9x60_ws_ids[] = {
 };
 
 static const struct of_device_id sama7g5_ws_ids[] = {
-	{ .compatible = "atmel,at91sam9x5-rtc",		.data = &ws_info[1] },
+	{ .compatible = "microchip,sama7g5-rtc",	.data = &ws_info[1] },
 	{ .compatible = "microchip,sama7g5-ohci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ohci",			.data = &ws_info[2] },
 	{ .compatible = "atmel,at91sam9g45-ehci",	.data = &ws_info[2] },
 	{ .compatible = "usb-ehci",			.data = &ws_info[2] },
 	{ .compatible = "microchip,sama7g5-sdhci",	.data = &ws_info[3] },
-	{ .compatible = "atmel,at91sam9260-rtt",	.data = &ws_info[4] },
+	{ .compatible = "microchip,sama7g5-rtt",	.data = &ws_info[4] },
 	{ /* sentinel */ }
 };
 
Signature · 1 line
2.35.1
author maintainer
#208 lore raw

PATCH 200/230 ARM: dts: at91: sam9x60ek: fix eeprom compatible and size

In reply to Greg Kroah-Hartman

From: Eugen Hristev <[email protected]>

[ Upstream commit f2cbbc3f926316ccf8ef9363d8a60c1110afc1c7 ]

The board has a microchip 24aa025e48 eeprom, which is a 2 Kbits memory, so it's compatible with at24c02 not at24c32.
Also the size property is wrong, it's not 128 bytes, but 256 bytes. Thus removing and leaving it to the default (256).

Fixes 1e5f532c27371 ("ARM: dts: at91: sam9x60: add device tree for soc and board")
---
 arch/arm/boot/dts/at91-sam9x60ek.dts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/arm/boot/dts/at91-sam9x60ek.dts +1 -2
index b1068cca4228..fd8dc1183b3e 100644
@@ -233,10 +233,9 @@
 		status = "okay";
 
 		eeprom@53 {
-			compatible = "atmel,24c32";
+			compatible = "atmel,24c02";
 			reg = <0x53>;
 			pagesize = <16>;
-			size = <128>;
 			status = "okay";
 		};
 	};
Signature · 1 line
2.35.1
author maintainer
#209 lore raw

PATCH 201/230 ARM: dts: at91: sama5d2_icp: fix eeprom compatibles

In reply to Greg Kroah-Hartman

From: Eugen Hristev <[email protected]>

[ Upstream commit 416ce193d73a734ded6d09fe141017b38af1c567 ]

The eeprom memories on the board are microchip 24aa025e48, which are 2 Kbits and are compatible with at24c02 not at24c32.

Fixes 68a95ef72cefe ("ARM: dts: at91: sama5d2-icp: add SAMA5D2-ICP")
---
 arch/arm/boot/dts/at91-sama5d2_icp.dts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
arch/arm/boot/dts/at91-sama5d2_icp.dts +3 -3
index e06b58724ca8..fd1a288f686b 100644
@@ -323,21 +323,21 @@
 	status = "okay";
 
 	eeprom@50 {
-		compatible = "atmel,24c32";
+		compatible = "atmel,24c02";
 		reg = <0x50>;
 		pagesize = <16>;
 		status = "okay";
 	};
 
 	eeprom@52 {
-		compatible = "atmel,24c32";
+		compatible = "atmel,24c02";
 		reg = <0x52>;
 		pagesize = <16>;
 		status = "disabled";
 	};
 
 	eeprom@53 {
-		compatible = "atmel,24c32";
+		compatible = "atmel,24c02";
 		reg = <0x53>;
 		pagesize = <16>;
 		status = "disabled";
Signature · 1 line
2.35.1
author maintainer
#210 lore raw

PATCH 202/230 ARM: at91: fix soc detection for SAM9X60 SiPs

In reply to Greg Kroah-Hartman

From: Mihai Sain <[email protected]>

[ Upstream commit 35074df65a8d8c5328a83e2eea948f7bbc8e6e08 ]

Fix SoC detection for SAM9X60 SiPs:
SAM9X60D5M
SAM9X60D1G
SAM9X60D6K

Fixes af3a10513cd6 ("drivers: soc: atmel: add per soc id and version match masks")
---
 drivers/soc/atmel/soc.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/soc/atmel/soc.c +6 -6
index a490ad7e090f..9e3d37011447 100644
@@ -91,14 +91,14 @@ static const struct at91_soc socs[] __initconst = {
 	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
 		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
 		 "sam9x60", "sam9x60"),
-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D5M_EXID_MATCH,
-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
+	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X60_D5M_EXID_MATCH,
 		 "sam9x60 64MiB DDR2 SiP", "sam9x60"),
-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D1G_EXID_MATCH,
-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
+	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X60_D1G_EXID_MATCH,
 		 "sam9x60 128MiB DDR2 SiP", "sam9x60"),
-	AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D6K_EXID_MATCH,
-		 AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH,
+	AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK,
+		 AT91_CIDR_VERSION_MASK, SAM9X60_D6K_EXID_MATCH,
 		 "sam9x60 8MiB SDRAM SiP", "sam9x60"),
 #endif
 #ifdef CONFIG_SOC_SAMA5
Signature · 1 line
2.35.1
author maintainer
#211 lore raw

PATCH 203/230 xsk: Clear page contiguity bit when unmapping pool

In reply to Greg Kroah-Hartman

From: Ivan Malov <[email protected]>

[ Upstream commit 512d1999b8e94a5d43fba3afc73e774849674742 ]

When a XSK pool gets mapped, xp_check_dma_contiguity() adds bit 0x1 to pages' DMA addresses that go in ascending order and at 4K stride.

The problem is that the bit does not get cleared before doing unmap. As a result, a lot of warnings from iommu_dma_unmap_page() are seen in dmesg, which indicates that lookups by iommu_iova_to_phys() fail.

---
 net/xdp/xsk_buff_pool.c | 1 +
 1 file changed, 1 insertion(+)
net/xdp/xsk_buff_pool.c +1 -0
index fc7fbfc1e586..ccedbbd27692 100644
@@ -326,6 +326,7 @@ static void __xp_dma_unmap(struct xsk_dma_map *dma_map, unsigned long attrs)
 	for (i = 0; i < dma_map->dma_pages_cnt; i++) {
 		dma = &dma_map->dma_pages[i];
 		if (*dma) {
+			*dma &= ~XSK_NEXT_PG_CONTIG_MASK;
 			dma_unmap_page_attrs(dma_map->dev, *dma, PAGE_SIZE,
 					     DMA_BIDIRECTIONAL, attrs);
 			*dma = 0;
Signature · 1 line
2.35.1
author maintainer
#212 lore raw

PATCH 204/230 i2c: piix4: Fix a memory leak in the EFCH MMIO support

In reply to Greg Kroah-Hartman

From: Jean Delvare <[email protected]>

[ Upstream commit 8ad59b397f86a4d8014966fdc0552095a0c4fb2b ]

The recently added support for EFCH MMIO regions introduced a memory leak in that code path. The leak is caused by the fact that release_resource() merely removes the resource from the tree but does not free its memory. We need to call release_mem_region() instead, which does free the memory. As a nice side effect, this brings back some symmetry between the legacy and MMIO paths.

Fixes 7c148722d074 ("i2c: piix4: Add EFCH MMIO support to region request and release")
---
 drivers/i2c/busses/i2c-piix4.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)
drivers/i2c/busses/i2c-piix4.c +7 -9
index ac8e7d60672a..39cb1b7bb865 100644
@@ -161,7 +161,6 @@ static const char *piix4_aux_port_name_sb800 = " port 1";
 
 struct sb800_mmio_cfg {
 	void __iomem *addr;
-	struct resource *res;
 	bool use_mmio;
 };
 
@@ -179,13 +178,11 @@ static int piix4_sb800_region_request(struct device *dev,
 				      struct sb800_mmio_cfg *mmio_cfg)
 {
 	if (mmio_cfg->use_mmio) {
-		struct resource *res;
 		void __iomem *addr;
 
-		res = request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR,
-					       SB800_PIIX4_FCH_PM_SIZE,
-					       "sb800_piix4_smb");
-		if (!res) {
+		if (!request_mem_region_muxed(SB800_PIIX4_FCH_PM_ADDR,
+					      SB800_PIIX4_FCH_PM_SIZE,
+					      "sb800_piix4_smb")) {
 			dev_err(dev,
 				"SMBus base address memory region 0x%x already in use.\n",
 				SB800_PIIX4_FCH_PM_ADDR);
@@ -195,12 +192,12 @@ static int piix4_sb800_region_request(struct device *dev,
 		addr = ioremap(SB800_PIIX4_FCH_PM_ADDR,
 			       SB800_PIIX4_FCH_PM_SIZE);
 		if (!addr) {
-			release_resource(res);
+			release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
+					   SB800_PIIX4_FCH_PM_SIZE);
 			dev_err(dev, "SMBus base address mapping failed.\n");
 			return -ENOMEM;
 		}
 
-		mmio_cfg->res = res;
 		mmio_cfg->addr = addr;
 
 		return 0;
@@ -222,7 +219,8 @@ static void piix4_sb800_region_release(struct device *dev,
 {
 	if (mmio_cfg->use_mmio) {
 		iounmap(mmio_cfg->addr);
-		release_resource(mmio_cfg->res);
+		release_mem_region(SB800_PIIX4_FCH_PM_ADDR,
+				   SB800_PIIX4_FCH_PM_SIZE);
 		return;
 	}
 
Signature · 1 line
2.35.1
author maintainer
#213 lore raw

PATCH 205/230 i40e: Fix dropped jumbo frames statistics

In reply to Greg Kroah-Hartman

From: Lukasz Cieplicki <[email protected]>

[ Upstream commit 1adb1563e7b7ec659379a18e607e8bc3522d8a78 ]

Dropped packets caused by too large frames were not included in dropped RX packets statistics.
Issue was caused by not reading the GL_RXERR1 register. That register stores count of packet which was have been dropped due to too large size.

Fix it by reading GL_RXERR1 register for each interface.

Repro steps:
Send a packet larger than the set MTU to SUT
Observe rx statists: ethtool -S <interface> | grep rx | grep -v ": 0"

---
 drivers/net/ethernet/intel/i40e/i40e.h        | 16 ++++
 drivers/net/ethernet/intel/i40e/i40e_main.c   | 73 +++++++++++++++++++
 .../net/ethernet/intel/i40e/i40e_register.h   | 13 ++++
 drivers/net/ethernet/intel/i40e/i40e_type.h   |  1 +
 4 files changed, 103 insertions(+)
drivers/net/ethernet/intel/i40e/i40e.h +16 -0
index 56a3a6d1dbe4..210f09118ede 100644
@@ -37,6 +37,7 @@
 #include <net/tc_act/tc_mirred.h>
 #include <net/udp_tunnel.h>
 #include <net/xdp_sock.h>
+#include <linux/bitfield.h>
 #include "i40e_type.h"
 #include "i40e_prototype.h"
 #include <linux/net/intel/i40e_client.h>
@@ -1087,6 +1088,21 @@ static inline void i40e_write_fd_input_set(struct i40e_pf *pf,
 			  (u32)(val & 0xFFFFFFFFULL));
 }
 
+/**
+ * i40e_get_pf_count - get PCI PF count.
+ * @hw: pointer to a hw.
+ *
+ * Reports the function number of the highest PCI physical
+ * function plus 1 as it is loaded from the NVM.
+ *
+ * Return: PCI PF count.
+ **/
+static inline u32 i40e_get_pf_count(struct i40e_hw *hw)
+{
+	return FIELD_GET(I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK,
+			 rd32(hw, I40E_GLGEN_PCIFCNCNT));
+}
+
 /* needed by i40e_ethtool.c */
 int i40e_up(struct i40e_vsi *vsi);
 void i40e_down(struct i40e_vsi *vsi);
drivers/net/ethernet/intel/i40e/i40e_main.c +73 -0

91 lines not on this page · raw message

drivers/net/ethernet/intel/i40e/i40e_register.h +13 -0
index 1908eed4fa5e..7339003aa17c 100644
@@ -211,6 +211,11 @@
 #define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0
 #define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16
 #define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT                0x001C0AB4 /* Reset: PCIR */
+#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0
+#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK  I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT)
+#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16
+#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK  I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT)
 #define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */
 #define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0
 #define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT)
@@ -643,6 +648,14 @@
 #define I40E_VFQF_HKEY1_MAX_INDEX 12
 #define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */
 #define I40E_VFQF_HLUT1_MAX_INDEX 15
+#define I40E_GL_RXERR1H(_i)             (0x00318004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR1H_MAX_INDEX       143
+#define I40E_GL_RXERR1H_RXERR1H_SHIFT   0
+#define I40E_GL_RXERR1H_RXERR1H_MASK    I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1H_RXERR1H_SHIFT)
+#define I40E_GL_RXERR1L(_i)             (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */
+#define I40E_GL_RXERR1L_MAX_INDEX       143
+#define I40E_GL_RXERR1L_RXERR1L_SHIFT   0
+#define I40E_GL_RXERR1L_RXERR1L_MASK    I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1L_RXERR1L_SHIFT)
 #define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
 #define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
 #define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */
drivers/net/ethernet/intel/i40e/i40e_type.h +1 -0
index 36a4ca1ffb1a..7b3f30beb757 100644
@@ -1172,6 +1172,7 @@ struct i40e_eth_stats {
 	u64 tx_broadcast;		/* bptc */
 	u64 tx_discards;		/* tdpc */
 	u64 tx_errors;			/* tepc */
+	u64 rx_discards_other;          /* rxerr1 */
 };
 
 /* Statistics collected per VEB per TC */
Signature · 1 line
2.35.1
author maintainer
#214 lore raw

PATCH 206/230 i40e: Fix VFs MAC Address change on VM

In reply to Greg Kroah-Hartman

From: Norbert Zulinski <[email protected]>

[ Upstream commit fed0d9f13266a22ce1fc9a97521ef9cdc6271a23 ]

Clear VF MAC from parent PF and remove VF filter from VSI when both conditions are true:
-VIRTCHNL_VF_OFFLOAD_USO is not used
-VM MAC was not set from PF level

It affects older version of IAVF and it allow them to change MAC Address on VM, newer IAVF won't change their behaviour.

Previously it wasn't possible to change VF's MAC Address on VM because there is flag on IAVF driver that won't allow to change MAC Address if this address is given from PF driver.

Fixes 155f0ac2c96b ("iavf: allow permanent MAC address to change")
---
 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 4 ++++
 1 file changed, 4 insertions(+)
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +4 -0
index 6c1e668f4ebf..d78ac5e7f658 100644
@@ -2147,6 +2147,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg)
 		/* VFs only use TC 0 */
 		vfres->vsi_res[0].qset_handle
 					  = le16_to_cpu(vsi->info.qs_handle[0]);
+		if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) {
+			i40e_del_mac_filter(vsi, vf->default_lan_addr.addr);
+			eth_zero_addr(vf->default_lan_addr.addr);
+		}
 		ether_addr_copy(vfres->vsi_res[0].default_mac_addr,
 				vf->default_lan_addr.addr);
 	}
Signature · 1 line
2.35.1
author maintainer
#215 lore raw

PATCH 207/230 ARM: dts: stm32: use usbphyc ck_usbo_48m as USBH OHCI clock on stm32mp151

In reply to Greg Kroah-Hartman

From: Amelie Delaunay <[email protected]>

[ Upstream commit db7be2cb87ae65e2d033a9f61f7fb94bce505177 ]

Referring to the note under USBH reset and clocks chapter of RM0436, "In order to access USBH_OHCI registers it is necessary to activate the USB clocks by enabling the PLL controlled by USBPHYC" (ck_usbo_48m).

The point is, when USBPHYC PLL is not enabled, OHCI register access freezes the resume from STANDBY. It is the case when dual USBH is enabled, instead of OTG + single USBH.
When OTG is probed, as ck_usbo_48m is USBO clock parent, then USBPHYC PLL is enabled and OHCI register access is OK.

This patch adds ck_usbo_48m (provided by USBPHYC PLL) as clock of USBH OHCI, thus USBPHYC PLL will be enabled and OHCI register access will be OK.

---
 arch/arm/boot/dts/stm32mp151.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/stm32mp151.dtsi +1 -1
index 6992a4b0ba79..f693a7d24247 100644
@@ -1452,7 +1452,7 @@
 		usbh_ohci: usb@5800c000 {
 			compatible = "generic-ohci";
 			reg = <0x5800c000 0x1000>;
-			clocks = <&rcc USBH>;
+			clocks = <&rcc USBH>, <&usbphyc>;
 			resets = <&rcc USBH_R>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
Signature · 1 line
2.35.1
author maintainer
#216 lore raw

PATCH 208/230 ARM: dts: stm32: add missing usbh clock and fix clk order on stm32mp15

In reply to Greg Kroah-Hartman

From: Fabrice Gasnier <[email protected]>

[ Upstream commit 1d0c1aadf1fd9f3de95d1532b3651e8634546e71 ]

The USBH composed of EHCI and OHCI controllers needs the PHY clock to be initialized first, before enabling (gating) them. The reverse is also required when going to suspend.
So, add USBPHY clock as 1st entry in both controllers, so the USBPHY PLL gets enabled 1st upon controller init. Upon suspend/resume, this also makes the clock to be disabled/re-enabled in the correct order.
This fixes some IRQ storm conditions seen when going to low-power, due to PHY PLL being disabled before all clocks are cleanly gated.

Fixes 949a0c0dec85 ("ARM: dts: stm32: add USB Host (USBH) support to stm32mp157c")
Fixes db7be2cb87ae ("ARM: dts: stm32: use usbphyc ck_usbo_48m as USBH OHCI clock on stm32mp151")
---
 arch/arm/boot/dts/stm32mp151.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/boot/dts/stm32mp151.dtsi +2 -2
index f693a7d24247..a9b65b3bfda5 100644
@@ -1452,7 +1452,7 @@
 		usbh_ohci: usb@5800c000 {
 			compatible = "generic-ohci";
 			reg = <0x5800c000 0x1000>;
-			clocks = <&rcc USBH>, <&usbphyc>;
+			clocks = <&usbphyc>, <&rcc USBH>;
 			resets = <&rcc USBH_R>;
 			interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
 			status = "disabled";
@@ -1461,7 +1461,7 @@
 		usbh_ehci: usb@5800d000 {
 			compatible = "generic-ehci";
 			reg = <0x5800d000 0x1000>;
-			clocks = <&rcc USBH>;
+			clocks = <&usbphyc>, <&rcc USBH>;
 			resets = <&rcc USBH_R>;
 			interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
 			companion = <&usbh_ohci>;
Signature · 1 line
2.35.1
author maintainer
#217 lore raw

PATCH 209/230 ibmvnic: Properly dispose of all skbs during a failover.

In reply to Greg Kroah-Hartman

From: Rick Lindsley <[email protected]>

[ Upstream commit 1b18f09d31cfa7148df15a7d5c5e0e86f105f7d1 ]

During a reset, there may have been transmits in flight that are no longer valid and cannot be fulfilled. Resetting and clearing the queues is insufficient; each skb also needs to be explicitly freed so that upper levels are not left waiting for confirmation of a transmit that will never happen. If this happens frequently enough, the apparent backlog will cause TCP to begin "congestion control" unnecessarily, culminating in permanently decreased throughput.

Fixes d7c0ef36bde03 ("ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change")
---
 drivers/net/ethernet/ibm/ibmvnic.c | 9 +++++++++
 1 file changed, 9 insertions(+)
drivers/net/ethernet/ibm/ibmvnic.c +9 -0
index 28344c3dfea1..4a070724a8fb 100644
@@ -5585,6 +5585,15 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
 			release_sub_crqs(adapter, 0);
 			rc = init_sub_crqs(adapter);
 		} else {
+			/* no need to reinitialize completely, but we do
+			 * need to clean up transmits that were in flight
+			 * when we processed the reset.  Failure to do so
+			 * will confound the upper layer, usually TCP, by
+			 * creating the illusion of transmits that are
+			 * awaiting completion.
+			 */
+			clean_tx_pools(adapter);
+
 			rc = reset_sub_crq_queues(adapter);
 		}
 	} else {
Signature · 1 line
2.35.1
author maintainer
#218 lore raw

PATCH 210/230 selftests: forwarding: fix flood_unicast_test when h2 supports IFF_UNICAST_FLT

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit b8e629b05f5d23f9649c901bef09fab8b0c2e4b9 ]

As mentioned in the blamed commit, flood_unicast_test() works by checking the match count on a tc filter placed on the receiving interface.

But the second host interface (host2_if) has no interest in receiving a packet with MAC DA de:ad:be:ef:13:37, so its RX filter drops it even before the ingress tc filter gets to be executed. So we will incorrectly get the message "Packet was not flooded when should", when in fact, the packet was flooded as expected but dropped due to an unrelated reason, at some other layer on the receiving side.

Force h2 to accept this packet by temporarily placing it in promiscuous mode. Alternatively we could either deliver to its MAC address or use tcpdump_start, but this has the fewest complications.

This fixes the "flooding" test from bridge_vlan_aware.sh and bridge_vlan_unaware.sh, which calls flood_test from the lib.

Fixes 236dd50bf67a ("selftests: forwarding: Add a test for flooded traffic")
---
 tools/testing/selftests/net/forwarding/lib.sh | 2 ++
 1 file changed, 2 insertions(+)
tools/testing/selftests/net/forwarding/lib.sh +2 -0
index 92087d423bcf..8a9c55fe841a 100644
@@ -1215,6 +1215,7 @@ flood_test_do()
 
 	# Add an ACL on `host2_if` which will tell us whether the packet
 	# was flooded to it or not.
+	ip link set $host2_if promisc on
 	tc qdisc add dev $host2_if ingress
 	tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \
 		flower dst_mac $mac action drop
@@ -1232,6 +1233,7 @@ flood_test_do()
 
 	tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower
 	tc qdisc del dev $host2_if ingress
+	ip link set $host2_if promisc off
 
 	return $err
 }
Signature · 1 line
2.35.1
author maintainer
#219 lore raw

PATCH 211/230 selftests: forwarding: fix learning_test when h1 supports IFF_UNICAST_FLT

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit 1a635d3e1c80626237fdae47a5545b6655d8d81c ]

The first host interface has by default no interest in receiving packets MAC DA de:ad:be:ef:13:37, so it might drop them before they hit the tc filter and this might confuse the selftest.

Enable promiscuous mode such that the filter properly counts received packets.

Fixes d4deb01467ec ("selftests: forwarding: Add a test for FDB learning")
---
 tools/testing/selftests/net/forwarding/lib.sh | 2 ++
 1 file changed, 2 insertions(+)
tools/testing/selftests/net/forwarding/lib.sh +2 -0
index 8a9c55fe841a..0db6ea8d7e05 100644
@@ -1149,6 +1149,7 @@ learning_test()
 	# FDB entry was installed.
 	bridge link set dev $br_port1 flood off
 
+	ip link set $host1_if promisc on
 	tc qdisc add dev $host1_if ingress
 	tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \
 		flower dst_mac $mac action drop
@@ -1198,6 +1199,7 @@ learning_test()
 
 	tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower
 	tc qdisc del dev $host1_if ingress
+	ip link set $host1_if promisc off
 
 	bridge link set dev $br_port1 flood on
 
Signature · 1 line
2.35.1
author maintainer
#220 lore raw

PATCH 212/230 selftests: forwarding: fix error message in learning_test

In reply to Greg Kroah-Hartman

From: Vladimir Oltean <[email protected]>

[ Upstream commit 83844aacab2015da1dba1df0cc61fc4b4c4e8076 ]

When packets are not received, they aren't received on $host1_if, so the message talking about the second host not receiving them is incorrect. Fix it.

Fixes d4deb01467ec ("selftests: forwarding: Add a test for FDB learning")
---
 tools/testing/selftests/net/forwarding/lib.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/testing/selftests/net/forwarding/lib.sh +1 -1
index 0db6ea8d7e05..c9507df9c05b 100644
@@ -1160,7 +1160,7 @@ learning_test()
 	tc -j -s filter show dev $host1_if ingress \
 		| jq -e ".[] | select(.options.handle == 101) \
 		| select(.options.actions[0].stats.packets == 1)" &> /dev/null
-	check_fail $? "Packet reached second host when should not"
+	check_fail $? "Packet reached first host when should not"
 
 	$MZ $host1_if -c 1 -p 64 -a $mac -t ip -q
 	sleep 1
Signature · 1 line
2.35.1
author maintainer
#221 lore raw

PATCH 213/230 r8169: fix accessing unset transport header

In reply to Greg Kroah-Hartman

From: Heiner Kallweit <[email protected]>

[ Upstream commit faa4e04e5e140a6d02260289a8fba8fd8d7a3003 ]

66e4c8d95008 ("net: warn if transport header was not set") added a check that triggers a warning in r8169, see [0].

The commit referenced in the Fixes tag refers to the change from which the patch applies cleanly, there's nothing wrong with this commit. It seems the actual issue (not bug, because the warning is harmless here) was introduced with bdfa4ed68187 ("r8169: use Giant Send").

[0] https://bugzilla.kernel.org/show_bug.cgi?id=216157

---
 drivers/net/ethernet/realtek/r8169_main.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/net/ethernet/realtek/r8169_main.c +4 -6
index 2918947dd57c..2af4c76bcf02 100644
@@ -4177,7 +4177,6 @@ static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts)
 static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 				struct sk_buff *skb, u32 *opts)
 {
-	u32 transport_offset = (u32)skb_transport_offset(skb);
 	struct skb_shared_info *shinfo = skb_shinfo(skb);
 	u32 mss = shinfo->gso_size;
 
@@ -4194,7 +4193,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 			WARN_ON_ONCE(1);
 		}
 
-		opts[0] |= transport_offset << GTTCPHO_SHIFT;
+		opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT;
 		opts[1] |= mss << TD1_MSS_SHIFT;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 ip_protocol;
@@ -4222,7 +4221,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp,
 		else
 			WARN_ON_ONCE(1);
 
-		opts[1] |= transport_offset << TCPHO_SHIFT;
+		opts[1] |= skb_transport_offset(skb) << TCPHO_SHIFT;
 	} else {
 		unsigned int padto = rtl_quirk_packet_padto(tp, skb);
 
@@ -4389,14 +4388,13 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
 						struct net_device *dev,
 						netdev_features_t features)
 {
-	int transport_offset = skb_transport_offset(skb);
 	struct rtl8169_private *tp = netdev_priv(dev);
 
 	if (skb_is_gso(skb)) {
 		if (tp->mac_version == RTL_GIGA_MAC_VER_34)
 			features = rtl8168evl_fix_tso(skb, features);
 
-		if (transport_offset > GTTCPHO_MAX &&
+		if (skb_transport_offset(skb) > GTTCPHO_MAX &&
 		    rtl_chip_supports_csum_v2(tp))
 			features &= ~NETIF_F_ALL_TSO;
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -4407,7 +4405,7 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb,
 		if (rtl_quirk_packet_padto(tp, skb))
 			features &= ~NETIF_F_CSUM_MASK;
 
-		if (transport_offset > TCPHO_MAX &&
+		if (skb_transport_offset(skb) > TCPHO_MAX &&
 		    rtl_chip_supports_csum_v2(tp))
 			features &= ~NETIF_F_CSUM_MASK;
 	}
Signature · 1 line
2.35.1
author maintainer
#222 lore raw

PATCH 214/230 i2c: cadence: Unregister the clk notifier in error path

In reply to Greg Kroah-Hartman

From: Satish Nagireddy <[email protected]>

[ Upstream commit 3501f0c663063513ad604fb1b3f06af637d3396d ]

This patch ensures that the clock notifier is unregistered when driver probe is returning error.

Fixes df8eb5691c48 ("i2c: Add driver for Cadence I2C controller")
---
 drivers/i2c/busses/i2c-cadence.c | 1 +
 1 file changed, 1 insertion(+)
drivers/i2c/busses/i2c-cadence.c +1 -0
index b4c1ad19cdae..3d6f8ee355bf 100644
@@ -1338,6 +1338,7 @@ static int cdns_i2c_probe(struct platform_device *pdev)
 	return 0;
 
 err_clk_dis:
+	clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
 	clk_disable_unprepare(id->clk);
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_set_suspended(&pdev->dev);
Signature · 1 line
2.35.1
author maintainer
#223 lore raw

PATCH 215/230 dmaengine: imx-sdma: Allow imx8m for imx7 FW revs

In reply to Greg Kroah-Hartman

From: Peter Robinson <[email protected]>

commit a7cd3cf0b2e5aaacfe5e02c472bd28e98e640be7 upstream.

The revision of the imx-sdma IP that is in the i.MX8M series is the same is that as that in the i.MX7 series but the imx7d MODULE_FIRMWARE directive is wrapped in a condiditional which means it's not defined when built for aarch64 SOC_IMX8M platforms and hence you get the following errors when the driver loads on imx8m devices:

imx-sdma 302c0000.dma-controller: Direct firmware load for imx/sdma/sdma-imx7d.bin failed with error -2 imx-sdma 302c0000.dma-controller: external firmware not found, using ROM firmware

Add the SOC_IMX8M into the check so the firmware can load on i.MX8.

Fixes 1474d48bd639 ("arm64: dts: imx8mq: Add SDMA nodes")
Fixes 941acd566b18 ("dmaengine: imx-sdma: Only check ratio on parts that support 1:1")
---
 drivers/dma/imx-sdma.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/imx-sdma.c +1 -1
@@ -2264,7 +2264,7 @@ MODULE_DESCRIPTION("i.MX SDMA driver");
 #if IS_ENABLED(CONFIG_SOC_IMX6Q)
 MODULE_FIRMWARE("imx/sdma/sdma-imx6q.bin");
 #endif
-#if IS_ENABLED(CONFIG_SOC_IMX7D)
+#if IS_ENABLED(CONFIG_SOC_IMX7D) || IS_ENABLED(CONFIG_SOC_IMX8M)
 MODULE_FIRMWARE("imx/sdma/sdma-imx7d.bin");
 #endif
 MODULE_LICENSE("GPL");
author maintainer
#224 lore raw

PATCH 216/230 misc: rtsx_usb: fix use of dma mapped buffer for usb bulk transfer

In reply to Greg Kroah-Hartman

From: Shuah Khan <[email protected]>

commit eb7f8e28420372787933eec079735c35034bda7d upstream.

rtsx_usb driver allocates coherent dma buffer for urb transfers. This buffer is passed to usb_bulk_msg() and usb core tries to map already mapped buffer running into a dma mapping error.

xhci_hcd 0000:01:00.0: rejecting DMA map of vmalloc memory

WARNING: CPU: 1 PID: 279 at include/linux/dma-mapping.h:326 usb_ hcd_map_urb_for_dma+0x7d6/0x820

...

xhci_map_urb_for_dma+0x291/0x4e0
usb_hcd_submit_urb+0x199/0x12b0
...
usb_submit_urb+0x3b8/0x9e0
usb_start_wait_urb+0xe3/0x2d0
usb_bulk_msg+0x115/0x240
rtsx_usb_transfer_data+0x185/0x1a8 [rtsx_usb]
rtsx_usb_send_cmd+0xbb/0x123 [rtsx_usb]
rtsx_usb_write_register+0x12c/0x143 [rtsx_usb]
rtsx_usb_probe+0x226/0x4b2 [rtsx_usb]

Fix it to use kmalloc() to get DMA-able memory region instead.

---
 drivers/misc/cardreader/rtsx_usb.c |   13 +++++++------
 include/linux/rtsx_usb.h           |    1 -
 2 files changed, 7 insertions(+), 7 deletions(-)
drivers/misc/cardreader/rtsx_usb.c +7 -6
@@ -631,8 +631,7 @@ static int rtsx_usb_probe(struct usb_int
 
 	ucr->pusb_dev = usb_dev;
 
-	ucr->iobuf = usb_alloc_coherent(ucr->pusb_dev, IOBUF_SIZE,
-			GFP_KERNEL, &ucr->iobuf_dma);
+	ucr->iobuf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
 	if (!ucr->iobuf)
 		return -ENOMEM;
 
@@ -668,8 +667,9 @@ static int rtsx_usb_probe(struct usb_int
 
 out_init_fail:
 	usb_set_intfdata(ucr->pusb_intf, NULL);
-	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
-			ucr->iobuf_dma);
+	kfree(ucr->iobuf);
+	ucr->iobuf = NULL;
+	ucr->cmd_buf = ucr->rsp_buf = NULL;
 	return ret;
 }
 
@@ -682,8 +682,9 @@ static void rtsx_usb_disconnect(struct u
 	mfd_remove_devices(&intf->dev);
 
 	usb_set_intfdata(ucr->pusb_intf, NULL);
-	usb_free_coherent(ucr->pusb_dev, IOBUF_SIZE, ucr->iobuf,
-			ucr->iobuf_dma);
+	kfree(ucr->iobuf);
+	ucr->iobuf = NULL;
+	ucr->cmd_buf = ucr->rsp_buf = NULL;
 }
 
 #ifdef CONFIG_PM
include/linux/rtsx_usb.h +0 -1
@@ -55,7 +55,6 @@ struct rtsx_ucr {
 	struct usb_interface	*pusb_intf;
 	struct usb_sg_request	current_sg;
 	unsigned char		*iobuf;
-	dma_addr_t		iobuf_dma;
 
 	struct timer_list	sg_timer;
 	struct mutex		dev_mutex;
author maintainer
#225 lore raw

PATCH 217/230 misc: rtsx_usb: use separate command and response buffers

In reply to Greg Kroah-Hartman

From: Shuah Khan <[email protected]>

commit 3776c78559853fd151be7c41e369fd076fb679d5 upstream.

rtsx_usb uses same buffer for command and response. There could be a potential conflict using the same buffer for both especially if retries and timeouts are involved.

Use separate command and response buffers to avoid conflicts.

---
 drivers/misc/cardreader/rtsx_usb.c |   26 +++++++++++++++++---------
 include/linux/rtsx_usb.h           |    1 -
 2 files changed, 17 insertions(+), 10 deletions(-)
drivers/misc/cardreader/rtsx_usb.c +17 -9
@@ -631,15 +631,18 @@ static int rtsx_usb_probe(struct usb_int
 
 	ucr->pusb_dev = usb_dev;
 
-	ucr->iobuf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
-	if (!ucr->iobuf)
+	ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
+	if (!ucr->cmd_buf)
 		return -ENOMEM;
 
+	ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
+	if (!ucr->rsp_buf)
+		goto out_free_cmd_buf;
+
 	usb_set_intfdata(intf, ucr);
 
 	ucr->vendor_id = id->idVendor;
 	ucr->product_id = id->idProduct;
-	ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf;
 
 	mutex_init(&ucr->dev_mutex);
 
@@ -667,9 +670,11 @@ static int rtsx_usb_probe(struct usb_int
 
 out_init_fail:
 	usb_set_intfdata(ucr->pusb_intf, NULL);
-	kfree(ucr->iobuf);
-	ucr->iobuf = NULL;
-	ucr->cmd_buf = ucr->rsp_buf = NULL;
+	kfree(ucr->rsp_buf);
+	ucr->rsp_buf = NULL;
+out_free_cmd_buf:
+	kfree(ucr->cmd_buf);
+	ucr->cmd_buf = NULL;
 	return ret;
 }
 
@@ -682,9 +687,12 @@ static void rtsx_usb_disconnect(struct u
 	mfd_remove_devices(&intf->dev);
 
 	usb_set_intfdata(ucr->pusb_intf, NULL);
-	kfree(ucr->iobuf);
-	ucr->iobuf = NULL;
-	ucr->cmd_buf = ucr->rsp_buf = NULL;
+
+	kfree(ucr->cmd_buf);
+	ucr->cmd_buf = NULL;
+
+	kfree(ucr->rsp_buf);
+	ucr->rsp_buf = NULL;
 }
 
 #ifdef CONFIG_PM
include/linux/rtsx_usb.h +0 -1
@@ -54,7 +54,6 @@ struct rtsx_ucr {
 	struct usb_device	*pusb_dev;
 	struct usb_interface	*pusb_intf;
 	struct usb_sg_request	current_sg;
-	unsigned char		*iobuf;
 
 	struct timer_list	sg_timer;
 	struct mutex		dev_mutex;
author maintainer
#226 lore raw

PATCH 218/230 misc: rtsx_usb: set return value in rsp_buf alloc err path

In reply to Greg Kroah-Hartman

From: Shuah Khan <[email protected]>

commit 2cd37c2e72449a7add6da1183d20a6247d6db111 upstream.

Set return value in rsp_buf alloc error path before going to error handling.

drivers/misc/cardreader/rtsx_usb.c:639:6: warning: variable 'ret' is used uninitialized whenever 'if' condition is true [-Wsometimes-uninitialized]

           if (!ucr->rsp_buf)
               ^~~~~~~~~~~~~
   drivers/misc/cardreader/rtsx_usb.c:678:9: note: uninitialized use occurs here
           return ret;
                  ^~~
   drivers/misc/cardreader/rtsx_usb.c:639:2: note: remove the 'if' if its condition is always false
           if (!ucr->rsp_buf)
           ^~~~~~~~~~~~~~~~~~
   drivers/misc/cardreader/rtsx_usb.c:622:9: note: initialize the variable 'ret' to silence this warning
           int ret;
                  ^
                   = 0
Fixes 3776c7855985 ("misc: rtsx_usb: use separate command and response buffers")
Cc stable <[email protected]>
---
 drivers/misc/cardreader/rtsx_usb.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/misc/cardreader/rtsx_usb.c +3 -1
@@ -636,8 +636,10 @@ static int rtsx_usb_probe(struct usb_int
 		return -ENOMEM;
 
 	ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL);
-	if (!ucr->rsp_buf)
+	if (!ucr->rsp_buf) {
+		ret = -ENOMEM;
 		goto out_free_cmd_buf;
+	}
 
 	usb_set_intfdata(intf, ucr);
 
author maintainer
#227 lore raw

PATCH 219/230 Revert "mm/memory-failure.c: fix race with changing page compound again"

In reply to Greg Kroah-Hartman

From: Naoya Horiguchi <[email protected]>

commit 2ba2b008a8bf5fd268a43d03ba79e0ad464d6836 upstream.

Reverts commit 888af2701db7 ("mm/memory-failure.c: fix race with changing page compound again") because now we fetch the page refcount under hugetlb_lock in try_memory_failure_hugetlb() so that the race check is no longer necessary.

---
 include/linux/mm.h      |    1 -
 include/ras/ras_event.h |    1 -
 mm/memory-failure.c     |   11 -----------
 3 files changed, 13 deletions(-)
include/linux/mm.h +0 -1
@@ -3175,7 +3175,6 @@ enum mf_action_page_type {
 	MF_MSG_BUDDY_2ND,
 	MF_MSG_DAX,
 	MF_MSG_UNSPLIT_THP,
-	MF_MSG_DIFFERENT_PAGE_SIZE,
 	MF_MSG_UNKNOWN,
 };
 
include/ras/ras_event.h +0 -1
@@ -376,7 +376,6 @@ TRACE_EVENT(aer_event,
 	EM ( MF_MSG_BUDDY_2ND, "free buddy page (2nd try)" )		\
 	EM ( MF_MSG_DAX, "dax page" )					\
 	EM ( MF_MSG_UNSPLIT_THP, "unsplit thp" )			\
-	EM ( MF_MSG_DIFFERENT_PAGE_SIZE, "different page size" )	\
 	EMe ( MF_MSG_UNKNOWN, "unknown page" )
 
 /*
mm/memory-failure.c +0 -11
@@ -741,7 +741,6 @@ static const char * const action_page_ty
 	[MF_MSG_BUDDY_2ND]		= "free buddy page (2nd try)",
 	[MF_MSG_DAX]			= "dax page",
 	[MF_MSG_UNSPLIT_THP]		= "unsplit thp",
-	[MF_MSG_DIFFERENT_PAGE_SIZE]	= "different page size",
 	[MF_MSG_UNKNOWN]		= "unknown page",
 };
 
@@ -1526,16 +1525,6 @@ retry:
 		return res == MF_RECOVERED ? 0 : -EBUSY;
 	}
 
-	/*
-	 * The page could have changed compound pages due to race window.
-	 * If this happens just bail out.
-	 */
-	if (!PageHuge(p) || compound_head(p) != head) {
-		action_result(pfn, MF_MSG_DIFFERENT_PAGE_SIZE, MF_IGNORED);
-		res = -EBUSY;
-		goto out;
-	}
-
 	page_flags = head->flags;
 
 	/*
author maintainer
#228 lore raw

PATCH 220/230 Revert "serial: 8250_mtk: Make sure to select the right FEATURE_SEL"

In reply to Greg Kroah-Hartman

From: AngeloGioacchino Del Regno <[email protected]>

commit f0136f65285bcfb7e8f90d1013723076a35acd51 upstream.

It was found that some MediaTek SoCs are incompatible with this change. Also, this register was mistakenly understood as it was related to the 16550A register layout selection but, at least on some IPs, if not all, it's related to something else unknown.

This reverts commit 6f81fdded0d024c7d4084d434764f30bca1cd6b1.

Fixes 6f81fdded0d0 ("serial: 8250_mtk: Make sure to select the right FEATURE_SEL")
---
 drivers/tty/serial/8250/8250_mtk.c |    7 -------
 1 file changed, 7 deletions(-)
drivers/tty/serial/8250/8250_mtk.c +0 -7
@@ -57,9 +57,6 @@
 #define MTK_UART_XON1		40	/* I/O: Xon character 1 */
 #define MTK_UART_XOFF1		42	/* I/O: Xoff character 1 */
 
-#define MTK_UART_FEATURE_SEL	39	/* Feature Selection register */
-#define MTK_UART_FEAT_NEWRMAP	BIT(0)	/* Use new register map */
-
 #ifdef CONFIG_SERIAL_8250_DMA
 enum dma_rx_status {
 	DMA_RX_START = 0,
@@ -575,10 +572,6 @@ static int mtk8250_probe(struct platform
 		uart.dma = data->dma;
 #endif
 
-	/* Set AP UART new register map */
-	writel(MTK_UART_FEAT_NEWRMAP, uart.port.membase +
-	       (MTK_UART_FEATURE_SEL << uart.port.regshift));
-
 	/* Disable Rate Fix function */
 	writel(0x0, uart.port.membase +
 			(MTK_UART_RATE_FIX << uart.port.regshift));
author maintainer
#229 lore raw

PATCH 221/230 dt-bindings: dma: allwinner,sun50i-a64-dma: Fix min/max typo

In reply to Greg Kroah-Hartman

From: Samuel Holland <[email protected]>

commit 607a48c78e6b427b0b684d24e61c19e846ad65d6 upstream.

The conditional block for variants with a second clock should have set minItems, not maxItems, which was already 2. Since clock-names requires two items, this typo should not have caused any problems.

Fixes edd14218bd66 ("dt-bindings: dmaengine: Convert Allwinner A31 and A64 DMA to a schema")
---
 Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml +1 -1
@@ -64,7 +64,7 @@ if:
 then:
   properties:
     clocks:
-      maxItems: 2
+      minItems: 2
 
   required:
     - clock-names
author maintainer
#230 lore raw

PATCH 222/230 ida: dont use BUG_ON() for debugging

In reply to Greg Kroah-Hartman

From: Linus Torvalds <[email protected]>

commit fc82bbf4dede758007763867d0282353c06d1121 upstream.

This is another old BUG_ON() that just shouldn't exist (see also commit
a382f8fee42c: "signal handling: don't use BUG_ON() for debugging").

In fact, as Matthew Wilcox points out, this condition shouldn't really even result in a warning, since a negative id allocation result is just a normal allocation failure:

"I wonder if we should even warn here -- sure, the caller is trying to
free something that wasn't allocated, but we don't warn for kfree(NULL)"

and goes on to point out how that current error check is only causing people to unnecessarily do their own index range checking before freeing it.

This was noted by Itay Iellin, because the bluetooth HCI socket cookie code does *not* do that range checking, and ends up just freeing the error case too, triggering the BUG_ON().

The HCI code requires CAP_NET_RAW, and seems to just result in an ugly splat, but there really is no reason to BUG_ON() here, and we have generally striven for allocation models where it's always ok to just do

    free(alloc());

even if the allocation were to fail for some random reason (usually obviously that "random" reason being some resource limit).

Fixes 88eca0207cf1 ("ida: simplified functions for id allocation")
---
 lib/idr.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
lib/idr.c +2 -1
@@ -491,7 +491,8 @@ void ida_free(struct ida *ida, unsigned
 	struct ida_bitmap *bitmap;
 	unsigned long flags;
 
-	BUG_ON((int)id < 0);
+	if ((int)id < 0)
+		return;
 
 	xas_lock_irqsave(&xas, flags);
 	bitmap = xas_load(&xas);
author maintainer
#231 lore raw

PATCH 223/230 dmaengine: pl330: Fix lockdep warning about non-static key

In reply to Greg Kroah-Hartman

From: Dmitry Osipenko <[email protected]>

commit b64b3b2f1d81f83519582e1feee87d77f51f5f17 upstream.

The DEFINE_SPINLOCK() macro shouldn't be used for dynamically allocated spinlocks. The lockdep warns about this and disables locking validator. Fix the warning by making lock static.

INFO: trying to register non-static key.
The code is fine but needs lockdep annotation, or maybe you didn't initialize this object before use? turning off the locking correctness validator.

 Hardware name: Radxa ROCK Pi 4C (DT)
 Call trace:
  dump_backtrace.part.0+0xcc/0xe0
  show_stack+0x18/0x6c
  dump_stack_lvl+0x8c/0xb8
  dump_stack+0x18/0x34
  register_lock_class+0x4a8/0x4cc
  __lock_acquire+0x78/0x20cc
  lock_acquire.part.0+0xe0/0x230
  lock_acquire+0x68/0x84
  _raw_spin_lock_irqsave+0x84/0xc4
  add_desc+0x44/0xc0
  pl330_get_desc+0x15c/0x1d0
  pl330_prep_dma_cyclic+0x100/0x270
  snd_dmaengine_pcm_trigger+0xec/0x1c0
  dmaengine_pcm_trigger+0x18/0x24
  ...
Fixes e588710311ee ("dmaengine: pl330: fix descriptor allocation fail")
---
 drivers/dma/pl330.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/dma/pl330.c +1 -1
@@ -2589,7 +2589,7 @@ static struct dma_pl330_desc *pl330_get_
 
 	/* If the DMAC pool is empty, alloc new */
 	if (!desc) {
-		DEFINE_SPINLOCK(lock);
+		static DEFINE_SPINLOCK(lock);
 		LIST_HEAD(pool);
 
 		if (!add_desc(&pool, &lock, GFP_ATOMIC, 1))
author maintainer
#232 lore raw

PATCH 224/230 dmaengine: lgm: Fix an error handling path in intel_ldma_probe()

In reply to Greg Kroah-Hartman

From: Christophe JAILLET <[email protected]>

commit 1dbe67b9faea0bc340cce894018076679c16cb71 upstream.

ldma_clk_disable() calls both:

	clk_disable_unprepare(d->core_clk);
	reset_control_assert(d->rst);

So, should devm_reset_control_get_optional() fail, core_clk should not be prepare_enable'd before it, otherwise it will never be disable_unprepare'd.

Reorder the code to handle the error handling path as expected.

---
 drivers/dma/lgm/lgm-dma.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/dma/lgm/lgm-dma.c +2 -1
@@ -1593,11 +1593,12 @@ static int intel_ldma_probe(struct platf
 	d->core_clk = devm_clk_get_optional(dev, NULL);
 	if (IS_ERR(d->core_clk))
 		return PTR_ERR(d->core_clk);
-	clk_prepare_enable(d->core_clk);
 
 	d->rst = devm_reset_control_get_optional(dev, NULL);
 	if (IS_ERR(d->rst))
 		return PTR_ERR(d->rst);
+
+	clk_prepare_enable(d->core_clk);
 	reset_control_deassert(d->rst);
 
 	ret = devm_add_action_or_reset(dev, ldma_clk_disable, d);
author maintainer
#233 lore raw

PATCH 225/230 dmaengine: at_xdma: handle errors of at_xdmac_alloc_desc() correctly

In reply to Greg Kroah-Hartman

From: Michael Walle <[email protected]>

commit 3770d92bd5237d686e49da7b2fb86f53ee6ed259 upstream.

It seems that it is valid to have less than the requested number of descriptors. But what is not valid and leads to subsequent errors is to have zero descriptors. In that case, abort the probing.

Fixes e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel eXtended DMA Controller driver")
---
 drivers/dma/at_xdmac.c |    5 +++++
 1 file changed, 5 insertions(+)
drivers/dma/at_xdmac.c +5 -0
@@ -1898,6 +1898,11 @@ static int at_xdmac_alloc_chan_resources
 	for (i = 0; i < init_nr_desc_per_channel; i++) {
 		desc = at_xdmac_alloc_desc(chan, GFP_KERNEL);
 		if (!desc) {
+			if (i == 0) {
+				dev_warn(chan2dev(chan),
+					 "can't allocate any descriptors\n");
+				return -EIO;
+			}
 			dev_warn(chan2dev(chan),
 				"only %d descriptors have been allocated\n", i);
 			break;
author maintainer
#234 lore raw

PATCH 226/230 dmaengine: ti: Fix refcount leak in ti_dra7_xbar_route_allocate

In reply to Greg Kroah-Hartman

From: Miaoqian Lin <[email protected]>

commit c132fe78ad7b4ce8b5d49a501a15c29d08eeb23a upstream.

of_parse_phandle() returns a node pointer with refcount incremented, we should use of_node_put() on it when not needed anymore.

Add missing of_node_put() in to fix this.

Fixes ec9bfa1e1a79 ("dmaengine: ti-dma-crossbar: dra7: Use bitops instead of idr")
---
 drivers/dma/ti/dma-crossbar.c |    1 +
 1 file changed, 1 insertion(+)
drivers/dma/ti/dma-crossbar.c +1 -0
@@ -268,6 +268,7 @@ static void *ti_dra7_xbar_route_allocate
 		mutex_unlock(&xbar->mutex);
 		dev_err(&pdev->dev, "Run out of free DMA requests\n");
 		kfree(map);
+		of_node_put(dma_spec->np);
 		return ERR_PTR(-ENOMEM);
 	}
 	set_bit(map->xbar_out, xbar->dma_inuse);
author maintainer
#235 lore raw

PATCH 227/230 dmaengine: qcom: bam_dma: fix runtime PM underflow

In reply to Greg Kroah-Hartman

From: Caleb Connolly <[email protected]>

commit 0ac9c3dd0d6fe293cd5044cfad10bec27d171e4e upstream.

Commit dbad41e7bb5f ("dmaengine: qcom: bam_dma: check if the runtime pm enabled") caused unbalanced pm_runtime_get/put() calls when the bam is controlled remotely. This commit reverts it and just enables pm_runtime in all cases, the clk_* functions already just nop when the clock is NULL.

Also clean up a bit by removing unnecessary bamclk null checks.

Fixes dbad41e7bb5f ("dmaengine: qcom: bam_dma: check if the runtime pm enabled")
---
 drivers/dma/qcom/bam_dma.c |   39 +++++++++++----------------------------
 1 file changed, 11 insertions(+), 28 deletions(-)
drivers/dma/qcom/bam_dma.c +11 -28
@@ -515,14 +515,6 @@ static int bam_alloc_chan(struct dma_cha
 	return 0;
 }
 
-static int bam_pm_runtime_get_sync(struct device *dev)
-{
-	if (pm_runtime_enabled(dev))
-		return pm_runtime_get_sync(dev);
-
-	return 0;
-}
-
 /**
  * bam_free_chan - Frees dma resources associated with specific channel
  * @chan: specified channel
@@ -538,7 +530,7 @@ static void bam_free_chan(struct dma_cha
 	unsigned long flags;
 	int ret;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return;
 
@@ -734,7 +726,7 @@ static int bam_pause(struct dma_chan *ch
 	unsigned long flag;
 	int ret;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return ret;
 
@@ -760,7 +752,7 @@ static int bam_resume(struct dma_chan *c
 	unsigned long flag;
 	int ret;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return ret;
 
@@ -869,7 +861,7 @@ static irqreturn_t bam_dma_irq(int irq,
 	if (srcs & P_IRQ)
 		tasklet_schedule(&bdev->task);
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return IRQ_NONE;
 
@@ -987,7 +979,7 @@ static void bam_start_dma(struct bam_cha
 	if (!vd)
 		return;
 
-	ret = bam_pm_runtime_get_sync(bdev->dev);
+	ret = pm_runtime_get_sync(bdev->dev);
 	if (ret < 0)
 		return;
 
@@ -1350,11 +1342,6 @@ static int bam_dma_probe(struct platform
 	if (ret)
 		goto err_unregister_dma;
 
-	if (!bdev->bamclk) {
-		pm_runtime_disable(&pdev->dev);
-		return 0;
-	}
-
 	pm_runtime_irq_safe(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, BAM_DMA_AUTOSUSPEND_DELAY);
 	pm_runtime_use_autosuspend(&pdev->dev);
@@ -1438,10 +1425,8 @@ static int __maybe_unused bam_dma_suspen
 {
 	struct bam_device *bdev = dev_get_drvdata(dev);
 
-	if (bdev->bamclk) {
-		pm_runtime_force_suspend(dev);
-		clk_unprepare(bdev->bamclk);
-	}
+	pm_runtime_force_suspend(dev);
+	clk_unprepare(bdev->bamclk);
 
 	return 0;
 }
@@ -1451,13 +1436,11 @@ static int __maybe_unused bam_dma_resume
 	struct bam_device *bdev = dev_get_drvdata(dev);
 	int ret;
 
-	if (bdev->bamclk) {
-		ret = clk_prepare(bdev->bamclk);
-		if (ret)
-			return ret;
+	ret = clk_prepare(bdev->bamclk);
+	if (ret)
+		return ret;
 
-		pm_runtime_force_resume(dev);
-	}
+	pm_runtime_force_resume(dev);
 
 	return 0;
 }
author maintainer
#236 lore raw

PATCH 228/230 dmaengine: ti: Add missing put_device in ti_dra7_xbar_route_allocate

In reply to Greg Kroah-Hartman

From: Miaoqian Lin <[email protected]>

commit 615a4bfc426e11dba05c2cf343f9ac752fb381d2 upstream.

of_find_device_by_node() takes reference, we should use put_device() to release it when not need anymore.

Fixes a074ae38f859 ("dmaengine: Add driver for TI DMA crossbar on DRA7x")
---
 drivers/dma/ti/dma-crossbar.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/dma/ti/dma-crossbar.c +4 -0
@@ -245,6 +245,7 @@ static void *ti_dra7_xbar_route_allocate
 	if (dma_spec->args[0] >= xbar->xbar_requests) {
 		dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
 			dma_spec->args[0]);
+		put_device(&pdev->dev);
 		return ERR_PTR(-EINVAL);
 	}
 
@@ -252,12 +253,14 @@ static void *ti_dra7_xbar_route_allocate
 	dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
 	if (!dma_spec->np) {
 		dev_err(&pdev->dev, "Can't get DMA master\n");
+		put_device(&pdev->dev);
 		return ERR_PTR(-EINVAL);
 	}
 
 	map = kzalloc(sizeof(*map), GFP_KERNEL);
 	if (!map) {
 		of_node_put(dma_spec->np);
+		put_device(&pdev->dev);
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -269,6 +272,7 @@ static void *ti_dra7_xbar_route_allocate
 		dev_err(&pdev->dev, "Run out of free DMA requests\n");
 		kfree(map);
 		of_node_put(dma_spec->np);
+		put_device(&pdev->dev);
 		return ERR_PTR(-ENOMEM);
 	}
 	set_bit(map->xbar_out, xbar->dma_inuse);
author maintainer
#237 lore raw

PATCH 229/230 dmaengine: idxd: force wq context cleanup on device disable path

In reply to Greg Kroah-Hartman

From: Dave Jiang <[email protected]>

commit 44c4237cf3436bda2b185ff728123651ad133f69 upstream.

Testing shown that when a wq mode is setup to be dedicated and then torn down and reconfigured to shared, the wq configured end up being dedicated anyays. The root cause is when idxd_device_wqs_clear_state() gets called during idxd_driver removal, idxd_wq_disable_cleanup() does not get called vs when the wq driver is removed first. The check of wq state being "enabled" causes the cleanup to be bypassed. However, idxd_driver->remove() releases all wq drivers. So the wqs goes to "disabled" state and will never be "enabled". By that point, the driver has no idea if the wq was previously configured or clean. So force call idxd_wq_disable_cleanup() on all wqs always to make sure everything gets cleaned up.

Fixes 0dcfe41e9a4c ("dmanegine: idxd: cleanup all device related bits after disabling device")
---
 drivers/dma/idxd/device.c |    5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/dma/idxd/device.c +1 -4
@@ -720,10 +720,7 @@ static void idxd_device_wqs_clear_state(
 	for (i = 0; i < idxd->max_wqs; i++) {
 		struct idxd_wq *wq = idxd->wqs[i];
 
-		if (wq->state == IDXD_WQ_ENABLED) {
-			idxd_wq_disable_cleanup(wq);
-			wq->state = IDXD_WQ_DISABLED;
-		}
+		idxd_wq_disable_cleanup(wq);
 		idxd_wq_device_reset_cleanup(wq);
 	}
 }
author maintainer
#238 lore raw

PATCH 230/230 selftests/net: fix section name when using xdp_dummy.o

In reply to Greg Kroah-Hartman

From: Hangbin Liu <[email protected]>

commit d28b25a62a47a8c8aa19bd543863aab6717e68c9 upstream.

Since commit 8fffa0e3451a ("selftests/bpf: Normalize XDP section names in selftests") the xdp_dummy.o's section name has changed to xdp. But some tests are still using "section xdp_dummy", which make the tests failed. Fix them by updating to the new section name.

Fixes 8fffa0e3451a ("selftests/bpf: Normalize XDP section names in selftests")
---
 tools/testing/selftests/net/udpgro.sh       |    2 +-
 tools/testing/selftests/net/udpgro_bench.sh |    2 +-
 tools/testing/selftests/net/udpgro_fwd.sh   |    2 +-
 tools/testing/selftests/net/veth.sh         |    6 +++---
 4 files changed, 6 insertions(+), 6 deletions(-)
tools/testing/selftests/net/udpgro.sh +1 -1
@@ -34,7 +34,7 @@ cfg_veth() {
 	ip -netns "${PEER_NS}" addr add dev veth1 192.168.1.1/24
 	ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad
 	ip -netns "${PEER_NS}" link set dev veth1 up
-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
+	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
 }
 
 run_one() {
tools/testing/selftests/net/udpgro_bench.sh +1 -1
@@ -34,7 +34,7 @@ run_one() {
 	ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad
 	ip -netns "${PEER_NS}" link set dev veth1 up
 
-	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy
+	ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp
 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r &
 	ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r &
 
tools/testing/selftests/net/udpgro_fwd.sh +1 -1
@@ -46,7 +46,7 @@ create_ns() {
 		ip -n $BASE$ns addr add dev veth$ns $BM_NET_V4$ns/24
 		ip -n $BASE$ns addr add dev veth$ns $BM_NET_V6$ns/64 nodad
 	done
-	ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null
+	ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null
 }
 
 create_vxlan_endpoint() {
tools/testing/selftests/net/veth.sh +3 -3
@@ -289,14 +289,14 @@ if [ $CPUS -gt 1 ]; then
 	ip netns exec $NS_SRC ethtool -L veth$SRC rx 1 tx 2 2>/dev/null
 	printf "%-60s" "bad setting: XDP with RX nr less than TX"
 	ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
-		section xdp_dummy 2>/dev/null &&\
+		section xdp 2>/dev/null &&\
 		echo "fail - set operation successful ?!?" || echo " ok "
 
 	# the following tests will run with multiple channels active
 	ip netns exec $NS_SRC ethtool -L veth$SRC rx 2
 	ip netns exec $NS_DST ethtool -L veth$DST rx 2
 	ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \
-		section xdp_dummy 2>/dev/null
+		section xdp 2>/dev/null
 	printf "%-60s" "bad setting: reducing RX nr below peer TX with XDP set"
 	ip netns exec $NS_DST ethtool -L veth$DST rx 1 2>/dev/null &&\
 		echo "fail - set operation successful ?!?" || echo " ok "
@@ -311,7 +311,7 @@ if [ $CPUS -gt 2 ]; then
 	chk_channels "setting invalid channels nr" $DST 2 2
 fi
 
-ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null
+ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null
 chk_gro_flag "with xdp attached - gro flag" $DST on
 chk_gro_flag "        - peer gro flag" $SRC off
 chk_tso_flag "        - tso flag" $SRC off
maintainer
#239 lore raw
In reply to Greg Kroah-Hartman

Hi Greg,

Quoted 20 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 5.15.54 release. There are 230 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, 13 Jul 2022 09:05: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/v5.x/stable-review/patch-5.15.54-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-5.15.y
and the diffstat can be found below.

thanks,

greg k-h

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

...

Quoted 2 lines

Mark Rutland <[email protected]>
irqchip/gic-v3: Ensure pseudo-NMIs have an ISB between ack and handling

The above change is missing a semi-colon and so is causing the following build error ...

drivers/irqchip/irq-gic-v3.c: In function 'gic_handle_nmi':
drivers/irqchip/irq-gic-v3.c:666:2: error: expected ';' before 'err'
err = handle_domain_nmi(gic_data.domain, irqnr, regs); ^~~

Quoted 2 lines

Hou Tao <[email protected]>
bpf, arm64: Use emit_addr_mov_i64() for BPF_PSEUDO_FUNC

And the above commit is generating the following build error ...

arch/arm64/net/bpf_jit_comp.c: In function 'build_insn':
arch/arm64/net/bpf_jit_comp.c:791:7: error: implicit declaration of function 'bpf_pseudo_func' [-Werror=implicit-function-declaration]
if (bpf_pseudo_func(insn))

       ^~~~~~~~~~~~~~~

These are seen with ARM64 builds.

Cheers
Jon

Signature · 1 line
nvpublic
#240 lore raw
Quoted 44 lines · Jon Hunter

Hi Greg,

Quoted 20 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 5.15.54 release. There are 230 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, 13 Jul 2022 09:05: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/v5.x/stable-review/patch-5.15.54-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-5.15.y
and the diffstat can be found below.

thanks,

greg k-h

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

...

Quoted 2 lines

Mark Rutland <[email protected]>
irqchip/gic-v3: Ensure pseudo-NMIs have an ISB between ack and handling

The above change is missing a semi-colon and so is causing the following build error ...

drivers/irqchip/irq-gic-v3.c: In function 'gic_handle_nmi':
drivers/irqchip/irq-gic-v3.c:666:2: error: expected ';' before 'err'

   err = handle_domain_nmi(gic_data.domain, irqnr, regs);
   ^~~
Quoted 2 lines

Hou Tao <[email protected]>
bpf, arm64: Use emit_addr_mov_i64() for BPF_PSEUDO_FUNC

And the above commit is generating the following build error ...

Quoted 7 lines

arch/arm64/net/bpf_jit_comp.c: In function 'build_insn':
arch/arm64/net/bpf_jit_comp.c:791:7: error: implicit declaration of function 'bpf_pseudo_func' [-Werror=implicit-function-declaration]

    if (bpf_pseudo_func(insn))
        ^~~~~~~~~~~~~~~

These are seen with ARM64 builds.

I have also noticed these failures on arm64 and arm.

- Naresh

Quoted 6 lines

Cheers
Jon

--
nvpublic

author maintainer
#241 lore raw
In reply to Jon Hunter
Quoted 30 lines · Jon Hunter

Hi Greg,

Quoted 20 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 5.15.54 release. There are 230 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, 13 Jul 2022 09:05: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/v5.x/stable-review/patch-5.15.54-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-5.15.y
and the diffstat can be found below.

thanks,

greg k-h

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

...

Quoted 2 lines

Mark Rutland <[email protected]>
irqchip/gic-v3: Ensure pseudo-NMIs have an ISB between ack and handling

Quoted 7 lines

The above change is missing a semi-colon and so is causing the following build error ...

drivers/irqchip/irq-gic-v3.c: In function 'gic_handle_nmi':
drivers/irqchip/irq-gic-v3.c:666:2: error: expected ';' before 'err'
err = handle_domain_nmi(gic_data.domain, irqnr, regs); ^~~

Ah, the original also didn't have the ; I'll go find the fix commit for this...

Quoted 11 lines
Quoted 3 lines

Hou Tao <[email protected]>
bpf, arm64: Use emit_addr_mov_i64() for BPF_PSEUDO_FUNC

And the above commit is generating the following build error ...

arch/arm64/net/bpf_jit_comp.c: In function 'build_insn':
arch/arm64/net/bpf_jit_comp.c:791:7: error: implicit declaration of function 'bpf_pseudo_func' [-Werror=implicit-function-declaration]
if (bpf_pseudo_func(insn))

       ^~~~~~~~~~~~~~~

Thanks, will figure this one out and do a -rc2 release.

greg k-h

Tested-by on the v1 series
#242 lore raw
In reply to Greg Kroah-Hartman
Quoted 5 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 5.15.54 release. There are 230 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.

Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0).

On powerpc build (ps3_defconfig, GCC 12.1.0), I found errors on gettimeofday vdso:

VDSOSYM include/generated/vdso32-offsets.h

  LDS     arch/powerpc/kernel/vdso64/vdso64.lds
  AS      arch/powerpc/kernel/vdso64/sigtramp.o
  AS      arch/powerpc/kernel/vdso64/gettimeofday.o
  AS      arch/powerpc/kernel/vdso64/datapage.o

arch/powerpc/kernel/vdso64/gettimeofday.S: Assembler messages:
arch/powerpc/kernel/vdso64/gettimeofday.S:25: Error: unrecognized opcode: cvdso_call' arch/powerpc/kernel/vdso64/gettimeofday.S:36: Error: unrecognized opcode: cvdso_call' arch/powerpc/kernel/vdso64/gettimeofday.S:47: Error: unrecognized opcode: cvdso_call' arch/powerpc/kernel/vdso64/gettimeofday.S:57: Error: unrecognized opcode: cvdso_call_time' make[1]: *** [scripts/Makefile.build:390: arch/powerpc/kernel/vdso64/gettimeofday.o] Error 1

Thanks.

Signature · 1 line
An old man doll... just what I always wanted! - Clara
#243 lore raw
Quoted 24 lines · Bagas Sanjaya
Quoted 5 lines · Greg Kroah-Hartman

This is the start of the stable review cycle for the 5.15.54 release. There are 230 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.

Successfully cross-compiled for arm64 (bcm2711_defconfig, GCC 10.2.0).

On powerpc build (ps3_defconfig, GCC 12.1.0), I found errors on gettimeofday vdso:

VDSOSYM include/generated/vdso32-offsets.h

  LDS     arch/powerpc/kernel/vdso64/vdso64.lds
  AS      arch/powerpc/kernel/vdso64/sigtramp.o
  AS      arch/powerpc/kernel/vdso64/gettimeofday.o
  AS      arch/powerpc/kernel/vdso64/datapage.o

arch/powerpc/kernel/vdso64/gettimeofday.S: Assembler messages:
arch/powerpc/kernel/vdso64/gettimeofday.S:25: Error: unrecognized opcode: cvdso_call' arch/powerpc/kernel/vdso64/gettimeofday.S:36: Error: unrecognized opcode: cvdso_call' arch/powerpc/kernel/vdso64/gettimeofday.S:47: Error: unrecognized opcode: cvdso_call' arch/powerpc/kernel/vdso64/gettimeofday.S:57: Error: unrecognized opcode: cvdso_call_time' make[1]: *** [scripts/Makefile.build:390: arch/powerpc/kernel/vdso64/gettimeofday.o] Error 1

Quoted 5 lines

Thanks.

Oops, wrong -rc replied. I tested for -rc2 instead.

I will test -rc3 soon.

Signature · 1 line
An old man doll... just what I always wanted! - Clara