This is the start of the stable review cycle for the 4.14.212 release.
There are 31 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 Sat, 12 Dec 2020 14:25:47 +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/v4.x/stable-review/patch-4.14.212-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-4.14.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <[email protected]>
Linux 4.14.212-rc1
Masami Hiramatsu <[email protected]>
x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes
Luo Meng <[email protected]>
Input: i8042 - fix error return code in i8042_setup_aux()
Zhihao Cheng <[email protected]>
i2c: qup: Fix error return code in qup_i2c_bam_schedule_desc()
Bob Peterson <[email protected]>
gfs2: check for empty rgrp tree in gfs2_ri_update
Steven Rostedt (VMware) <[email protected]>
tracing: Fix userstacktrace option for instances
Peter Ujfalusi <[email protected]>
spi: bcm2835: Release the DMA channel if probe fails after dma_init
Lukas Wunner <[email protected]>
spi: bcm2835: Fix use-after-free on unbind
Lukas Wunner <[email protected]>
spi: bcm-qspi: Fix use-after-free on unbind
Lukas Wunner <[email protected]>
spi: Introduce device-managed SPI controller allocation
Suravee Suthikulpanit <[email protected]>
iommu/amd: Set DTE[IntTabLen] to represent 512 IRTEs
Samuel Thibault <[email protected]>
speakup: Reject setting the speakup line discipline outside of speakup
Christian Eggers <[email protected]>
i2c: imx: Check for I2SR_IAL after every byte
Christian Eggers <[email protected]>
i2c: imx: Fix reset of I2SR_IAL flag
Qian Cai <[email protected]>
mm/swapfile: do not sleep with a spin lock held
Paulo Alcantara <[email protected]>
cifs: fix potential use-after-free in cifs_echo_request()
Naveen N. Rao <[email protected]>
ftrace: Fix updating FTRACE_FL_TRAMP
Takashi Iwai <[email protected]>
ALSA: hda/generic: Add option to enforce preferred_dacs pairs
Kailang Yang <[email protected]>
ALSA: hda/realtek - Add new codec supported for ALC897
Jann Horn <[email protected]>
tty: Fix ->session locking
Jann Horn <[email protected]>
tty: Fix ->pgrp locking in tiocspgrp()
Bjørn Mork <[email protected]>
USB: serial: option: fix Quectel BG96 matching
Giacinto Cifelli <[email protected]>
USB: serial: option: add support for Thales Cinterion EXS82
Vincent Palatin <[email protected]>
USB: serial: option: add Fibocom NL668 variants
Johan Hovold <[email protected]>
USB: serial: ch341: sort device-id entries
Jan-Niklas Burfeind <[email protected]>
USB: serial: ch341: add new Product ID for CH341A
Johan Hovold <[email protected]>
USB: serial: kl5kusb105: fix memleak on open
Vamsi Krishna Samavedam <[email protected]>
usb: gadget: f_fs: Use local copy of descriptors for userspace copy
Eric Dumazet <[email protected]>
geneve: pull IP header before ECN decapsulation
Toke Høiland-Jørgensen <[email protected]>
vlan: consolidate VLAN parsing code and limit max parsing depth
Hans de Goede <[email protected]>
pinctrl: baytrail: Fix pin being driven low for a while on gpiod_get(..., GPIOD_OUT_HIGH)
Hans de Goede <[email protected]>
pinctrl: baytrail: Replace WARN with dev_info_once when setting direct-irq pin to output
-------------
Diffstat:
Makefile | 4 +-
arch/x86/include/asm/insn.h | 15 +++++++
arch/x86/kernel/uprobes.c | 10 +++--
drivers/i2c/busses/i2c-imx.c | 30 +++++++++++---
drivers/i2c/busses/i2c-qup.c | 3 +-
drivers/input/serio/i8042.c | 3 +-
drivers/iommu/amd_iommu_types.h | 2 +-
drivers/net/geneve.c | 20 +++++++--
drivers/pinctrl/intel/pinctrl-baytrail.c | 67 ++++++++++++++++++++++++-------
drivers/spi/spi-bcm-qspi.c | 34 ++++++----------
drivers/spi/spi-bcm2835.c | 22 +++++-----
drivers/spi/spi.c | 58 +++++++++++++++++++++++++-
drivers/staging/speakup/spk_ttyio.c | 38 +++++++++++-------
drivers/tty/tty_io.c | 7 +++-
drivers/tty/tty_jobctrl.c | 44 ++++++++++++++------
drivers/usb/gadget/function/f_fs.c | 6 ++-
drivers/usb/serial/ch341.c | 5 ++-
drivers/usb/serial/kl5kusb105.c | 10 ++---
drivers/usb/serial/option.c | 10 +++--
fs/cifs/connect.c | 2 +
fs/gfs2/rgrp.c | 4 ++
include/linux/if_vlan.h | 29 +++++++++----
include/linux/spi/spi.h | 19 +++++++++
include/linux/tty.h | 4 ++
include/net/inet_ecn.h | 1 +
kernel/trace/ftrace.c | 22 +++++++++-
kernel/trace/trace.c | 7 ++--
kernel/trace/trace.h | 6 ++-
mm/swapfile.c | 4 +-
sound/pci/hda/hda_generic.c | 12 ++++--
sound/pci/hda/hda_generic.h | 1 +
sound/pci/hda/patch_realtek.c | 2 +
tools/objtool/arch/x86/include/asm/insn.h | 15 +++++++
33 files changed, 387 insertions(+), 129 deletions(-)
From: Johan Hovold <[email protected]>
commit 3f203f057edfcf6bd02c6b942799262bfcf31f73 upstream.
Fix memory leak of control-message transfer buffer on successful open().
Fixes: 6774d5f53271 ("USB: serial: kl5kusb105: fix open error path")
Cc: [email protected]
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/usb/serial/kl5kusb105.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -281,12 +281,12 @@ static int klsi_105_open(struct tty_str
priv->cfg.unknown2 = cfg->unknown2;
spin_unlock_irqrestore(&priv->lock, flags);
+ kfree(cfg);
+
/* READ_ON and urb submission */
rc = usb_serial_generic_open(tty, port);
- if (rc) {
- retval = rc;
- goto err_free_cfg;
- }
+ if (rc)
+ return rc;
rc = usb_control_msg(port->serial->dev,
usb_sndctrlpipe(port->serial->dev, 0),
@@ -329,8 +329,6 @@ err_disable_read:
KLSI_TIMEOUT);
err_generic_close:
usb_serial_generic_close(port);
-err_free_cfg:
- kfree(cfg);
return retval;
}
From: Toke Høiland-Jørgensen <[email protected]>
[ Upstream commit 469aceddfa3ed16e17ee30533fae45e90f62efd8 ]
Toshiaki pointed out that we now have two very similar functions to extract
the L3 protocol number in the presence of VLAN tags. And Daniel pointed out
that the unbounded parsing loop makes it possible for maliciously crafted
packets to loop through potentially hundreds of tags.
Fix both of these issues by consolidating the two parsing functions and
limiting the VLAN tag parsing to a max depth of 8 tags. As part of this,
switch over __vlan_get_protocol() to use skb_header_pointer() instead of
pskb_may_pull(), to avoid the possible side effects of the latter and keep
the skb pointer 'const' through all the parsing functions.
v2:
- Use limit of 8 tags instead of 32 (matching XMIT_RECURSION_LIMIT)
Reported-by: Toshiaki Makita <[email protected]>
Reported-by: Daniel Borkmann <[email protected]>
Fixes: d7bf2ebebc2b ("sched: consistently handle layer3 header accesses in the presence of VLANs")
Signed-off-by: Toke Høiland-Jørgensen <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
include/linux/if_vlan.h | 29 ++++++++++++++++++++++-------
include/net/inet_ecn.h | 1 +
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 87b8c20d5b27c..af4f2a7f8e9a0 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -30,6 +30,8 @@
#define VLAN_ETH_DATA_LEN 1500 /* Max. octets in payload */
#define VLAN_ETH_FRAME_LEN 1518 /* Max. octets in frame sans FCS */
+#define VLAN_MAX_DEPTH 8 /* Max. number of nested VLAN tags parsed */
+
/*
* struct vlan_hdr - vlan header
* @h_vlan_TCI: priority and VLAN ID
@@ -534,10 +536,10 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
* Returns the EtherType of the packet, regardless of whether it is
* vlan encapsulated (normal or hardware accelerated) or not.
*/
-static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
+static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type,
int *depth)
{
- unsigned int vlan_depth = skb->mac_len;
+ unsigned int vlan_depth = skb->mac_len, parse_depth = VLAN_MAX_DEPTH;
/* if type is 802.1Q/AD then the header should already be
* present at mac_len - VLAN_HLEN (if mac_len > 0), or at
@@ -552,13 +554,12 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
vlan_depth = ETH_HLEN;
}
do {
- struct vlan_hdr *vh;
+ struct vlan_hdr vhdr, *vh;
- if (unlikely(!pskb_may_pull(skb,
- vlan_depth + VLAN_HLEN)))
+ vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr);
+ if (unlikely(!vh || !--parse_depth))
return 0;
- vh = (struct vlan_hdr *)(skb->data + vlan_depth);
type = vh->h_vlan_encapsulated_proto;
vlan_depth += VLAN_HLEN;
} while (eth_type_vlan(type));
@@ -577,11 +578,25 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
* Returns the EtherType of the packet, regardless of whether it is
* vlan encapsulated (normal or hardware accelerated) or not.
*/
-static inline __be16 vlan_get_protocol(struct sk_buff *skb)
+static inline __be16 vlan_get_protocol(const struct sk_buff *skb)
{
return __vlan_get_protocol(skb, skb->protocol, NULL);
}
+/* A getter for the SKB protocol field which will handle VLAN tags consistently
+ * whether VLAN acceleration is enabled or not.
+ */
+static inline __be16 skb_protocol(const struct sk_buff *skb, bool skip_vlan)
+{
+ if (!skip_vlan)
+ /* VLAN acceleration strips the VLAN header from the skb and
+ * moves it to skb->vlan_proto
+ */
+ return skb_vlan_tag_present(skb) ? skb->vlan_proto : skb->protocol;
+
+ return vlan_get_protocol(skb);
+}
+
static inline void vlan_set_encap_proto(struct sk_buff *skb,
struct vlan_hdr *vhdr)
{
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index d30e4c869438c..09ed8a48b4548 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -4,6 +4,7 @@
#include <linux/ip.h>
#include <linux/skbuff.h>
+#include <linux/if_vlan.h>
#include <net/inet_sock.h>
#include <net/dsfield.h>
--
2.27.0
From: Hans de Goede <[email protected]>
commit 156abe2961601d60a8c2a60c6dc8dd6ce7adcdaf upstream
The pins on the Bay Trail SoC have separate input-buffer and output-buffer
enable bits and a read of the level bit of the value register will always
return the value from the input-buffer.
The BIOS of a device may configure a pin in output-only mode, only enabling
the output buffer, and write 1 to the level bit to drive the pin high.
This 1 written to the level bit will be stored inside the data-latch of the
output buffer.
But a subsequent read of the value register will return 0 for the level bit
because the input-buffer is disabled. This causes a read-modify-write as
done by byt_gpio_set_direction() to write 0 to the level bit, driving the
pin low!
Before this commit byt_gpio_direction_output() relied on
pinctrl_gpio_direction_output() to set the direction, followed by a call
to byt_gpio_set() to apply the selected value. This causes the pin to
go low between the pinctrl_gpio_direction_output() and byt_gpio_set()
calls.
Change byt_gpio_direction_output() to directly make the register
modifications itself instead. Replacing the 2 subsequent writes to the
value register with a single write.
Note that the pinctrl code does not keep track internally of the direction,
so not going through pinctrl_gpio_direction_output() is not an issue.
This issue was noticed on a Trekstor SurfTab Twin 10.1. When the panel is
already on at boot (no external monitor connected), then the i915 driver
does a gpiod_get(..., GPIOD_OUT_HIGH) for the panel-enable GPIO. The
temporarily going low of that GPIO was causing the panel to reset itself
after which it would not show an image until it was turned off and back on
again (until a full modeset was done on it). This commit fixes this.
This commit also updates the byt_gpio_direction_input() to use direct
register accesses instead of going through pinctrl_gpio_direction_input(),
to keep it consistent with byt_gpio_direction_output().
Note for backporting, this commit depends on:
commit e2b74419e5cc ("pinctrl: baytrail: Replace WARN with dev_info_once
when setting direct-irq pin to output")
Cc: [email protected]
Fixes: 86e3ef812fe3 ("pinctrl: baytrail: Update gpio chip operations")
Signed-off-by: Hans de Goede <[email protected]>
Acked-by: Mika Westerberg <[email protected]>
Signed-off-by: Andy Shevchenko <[email protected]>
[sudip: use byt_gpio and vg->pdev->dev for dev_info()]
Signed-off-by: Sudip Mukherjee <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/pinctrl/intel/pinctrl-baytrail.c | 67 +++++++++++++++++++-----
1 file changed, 53 insertions(+), 14 deletions(-)
diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
index d86c4c51769e4..62eac76be9f66 100644
--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
+++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
@@ -1017,6 +1017,21 @@ static void byt_gpio_disable_free(struct pinctrl_dev *pctl_dev,
pm_runtime_put(&vg->pdev->dev);
}
+static void byt_gpio_direct_irq_check(struct byt_gpio *vg,
+ unsigned int offset)
+{
+ void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
+
+ /*
+ * Before making any direction modifications, do a check if gpio is set
+ * for direct IRQ. On Bay Trail, setting GPIO to output does not make
+ * sense, so let's at least inform the caller before they shoot
+ * themselves in the foot.
+ */
+ if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
+ dev_info_once(&vg->pdev->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
+}
+
static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
struct pinctrl_gpio_range *range,
unsigned int offset,
@@ -1024,7 +1039,6 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
{
struct byt_gpio *vg = pinctrl_dev_get_drvdata(pctl_dev);
void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
- void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG);
unsigned long flags;
u32 value;
@@ -1034,14 +1048,8 @@ static int byt_gpio_set_direction(struct pinctrl_dev *pctl_dev,
value &= ~BYT_DIR_MASK;
if (input)
value |= BYT_OUTPUT_EN;
- else if (readl(conf_reg) & BYT_DIRECT_IRQ_EN)
- /*
- * Before making any direction modifications, do a check if gpio
- * is set for direct IRQ. On baytrail, setting GPIO to output
- * does not make sense, so let's at least inform the caller before
- * they shoot themselves in the foot.
- */
- dev_info_once(vg->dev, "Potential Error: Setting GPIO with direct_irq_en to output");
+ else
+ byt_gpio_direct_irq_check(vg, offset);
writel(value, val_reg);
@@ -1382,19 +1390,50 @@ static int byt_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
static int byt_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
{
- return pinctrl_gpio_direction_input(chip->base + offset);
+ struct byt_gpio *vg = gpiochip_get_data(chip);
+ void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+ unsigned long flags;
+ u32 reg;
+
+ raw_spin_lock_irqsave(&byt_lock, flags);
+
+ reg = readl(val_reg);
+ reg &= ~BYT_DIR_MASK;
+ reg |= BYT_OUTPUT_EN;
+ writel(reg, val_reg);
+
+ raw_spin_unlock_irqrestore(&byt_lock, flags);
+ return 0;
}
+/*
+ * Note despite the temptation this MUST NOT be converted into a call to
+ * pinctrl_gpio_direction_output() + byt_gpio_set() that does not work this
+ * MUST be done as a single BYT_VAL_REG register write.
+ * See the commit message of the commit adding this comment for details.
+ */
static int byt_gpio_direction_output(struct gpio_chip *chip,
unsigned int offset, int value)
{
- int ret = pinctrl_gpio_direction_output(chip->base + offset);
+ struct byt_gpio *vg = gpiochip_get_data(chip);
+ void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG);
+ unsigned long flags;
+ u32 reg;
- if (ret)
- return ret;
+ raw_spin_lock_irqsave(&byt_lock, flags);
- byt_gpio_set(chip, offset, value);
+ byt_gpio_direct_irq_check(vg, offset);
+ reg = readl(val_reg);
+ reg &= ~BYT_DIR_MASK;
+ if (value)
+ reg |= BYT_LEVEL;
+ else
+ reg &= ~BYT_LEVEL;
+
+ writel(reg, val_reg);
+
+ raw_spin_unlock_irqrestore(&byt_lock, flags);
return 0;
}
--
2.27.0
From: Zhihao Cheng <[email protected]>
commit e9acf0298c664f825e6f1158f2a97341bf9e03ca upstream.
Fix to return the error code from qup_i2c_change_state()
instaed of 0 in qup_i2c_bam_schedule_desc().
Fixes: fbf9921f8b35d9b2 ("i2c: qup: Fix error handling")
Reported-by: Hulk Robot <[email protected]>
Signed-off-by: Zhihao Cheng <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
Signed-off-by: Wolfram Sang <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/i2c/busses/i2c-qup.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -846,7 +846,8 @@ static int qup_i2c_bam_do_xfer(struct qu
if (ret || qup->bus_err || qup->qup_err) {
reinit_completion(&qup->xfer);
- if (qup_i2c_change_state(qup, QUP_RUN_STATE)) {
+ ret = qup_i2c_change_state(qup, QUP_RUN_STATE);
+ if (ret) {
dev_err(qup->dev, "change to run state timed out");
goto desc_err;
}
From: Jann Horn <[email protected]>
commit 54ffccbf053b5b6ca4f6e45094b942fab92a25fc upstream.
tiocspgrp() takes two tty_struct pointers: One to the tty that userspace
passed to ioctl() (`tty`) and one to the TTY being changed (`real_tty`).
These pointers are different when ioctl() is called with a master fd.
To properly lock real_tty->pgrp, we must take real_tty->ctrl_lock.
This bug makes it possible for racing ioctl(TIOCSPGRP, ...) calls on
both sides of a PTY pair to corrupt the refcount of `struct pid`,
leading to use-after-free errors.
Fixes: 47f86834bbd4 ("redo locking of tty->pgrp")
CC: [email protected]
Signed-off-by: Jann Horn <[email protected]>
Reviewed-by: Jiri Slaby <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/tty/tty_jobctrl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/tty/tty_jobctrl.c
+++ b/drivers/tty/tty_jobctrl.c
@@ -493,10 +493,10 @@ static int tiocspgrp(struct tty_struct *
if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock;
retval = 0;
- spin_lock_irq(&tty->ctrl_lock);
+ spin_lock_irq(&real_tty->ctrl_lock);
put_pid(real_tty->pgrp);
real_tty->pgrp = get_pid(pgrp);
- spin_unlock_irq(&tty->ctrl_lock);
+ spin_unlock_irq(&real_tty->ctrl_lock);
out_unlock:
rcu_read_unlock();
return retval;
From: Johan Hovold <[email protected]>
commit bf193bfc12dbc3754fc8a6e0e1e3702f1af2f772 upstream.
Keep the device-id entries sorted to make it easier to add new ones in
the right spot.
Reviewed-by: Greg Kroah-Hartman <[email protected]>
Cc: [email protected]
Signed-off-by: Johan Hovold <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/usb/serial/ch341.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -83,11 +83,11 @@
#define CH341_LCR_CS5 0x00
static const struct usb_device_id id_table[] = {
- { USB_DEVICE(0x4348, 0x5523) },
- { USB_DEVICE(0x1a86, 0x7522) },
- { USB_DEVICE(0x1a86, 0x7523) },
{ USB_DEVICE(0x1a86, 0x5512) },
{ USB_DEVICE(0x1a86, 0x5523) },
+ { USB_DEVICE(0x1a86, 0x7522) },
+ { USB_DEVICE(0x1a86, 0x7523) },
+ { USB_DEVICE(0x4348, 0x5523) },
{ },
};
MODULE_DEVICE_TABLE(usb, id_table);
From: Paulo Alcantara <[email protected]>
commit 212253367dc7b49ed3fc194ce71b0992eacaecf2 upstream.
This patch fixes a potential use-after-free bug in
cifs_echo_request().
For instance,
thread 1
--------
cifs_demultiplex_thread()
clean_demultiplex_info()
kfree(server)
thread 2 (workqueue)
--------
apic_timer_interrupt()
smp_apic_timer_interrupt()
irq_exit()
__do_softirq()
run_timer_softirq()
call_timer_fn()
cifs_echo_request() <- use-after-free in server ptr
Signed-off-by: Paulo Alcantara (SUSE) <[email protected]>
CC: Stable <[email protected]>
Reviewed-by: Ronnie Sahlberg <[email protected]>
Signed-off-by: Steve French <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/cifs/connect.c | 2 ++
1 file changed, 2 insertions(+)
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -756,6 +756,8 @@ static void clean_demultiplex_info(struc
list_del_init(&server->tcp_ses_list);
spin_unlock(&cifs_tcp_ses_lock);
+ cancel_delayed_work_sync(&server->echo);
+
spin_lock(&GlobalMid_Lock);
server->tcpStatus = CifsExiting;
spin_unlock(&GlobalMid_Lock);
From: Luo Meng <[email protected]>
commit 855b69857830f8d918d715014f05e59a3f7491a0 upstream.
Fix to return a negative error code from the error handling case
instead of 0 in function i8042_setup_aux(), as done elsewhere in this
function.
Fixes: f81134163fc7 ("Input: i8042 - use platform_driver_probe")
Reported-by: Hulk Robot <[email protected]>
Signed-off-by: Luo Meng <[email protected]>
Reviewed-by: Hans de Goede <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Dmitry Torokhov <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/input/serio/i8042.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1458,7 +1458,8 @@ static int __init i8042_setup_aux(void)
if (error)
goto err_free_ports;
- if (aux_enable())
+ error = aux_enable();
+ if (error)
goto err_free_irq;
i8042_aux_irq_registered = true;
From: Qian Cai <[email protected]>
commit b11a76b37a5aa7b07c3e3eeeaae20b25475bddd3 upstream.
We can't call kvfree() with a spin lock held, so defer it. Fixes a
might_sleep() runtime warning.
Fixes: 873d7bcfd066 ("mm/swapfile.c: use kvzalloc for swap_info_struct allocation")
Signed-off-by: Qian Cai <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Reviewed-by: Andrew Morton <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
mm/swapfile.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2828,6 +2828,7 @@ late_initcall(max_swapfiles_check);
static struct swap_info_struct *alloc_swap_info(void)
{
struct swap_info_struct *p;
+ struct swap_info_struct *defer = NULL;
unsigned int type;
int i;
int size = sizeof(*p) + nr_node_ids * sizeof(struct plist_node);
@@ -2857,7 +2858,7 @@ static struct swap_info_struct *alloc_sw
smp_wmb();
nr_swapfiles++;
} else {
- kvfree(p);
+ defer = p;
p = swap_info[type];
/*
* Do not memset this entry: a racing procfs swap_next()
@@ -2870,6 +2871,7 @@ static struct swap_info_struct *alloc_sw
plist_node_init(&p->avail_lists[i], 0);
p->flags = SWP_USED;
spin_unlock(&swap_lock);
+ kvfree(defer);
spin_lock_init(&p->lock);
spin_lock_init(&p->cont_lock);
On Thu, Dec 10, 2020 at 03:26:37PM +0100, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.14.212 release.
> There are 31 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 Sat, 12 Dec 2020 14:25:47 +0000.
> Anything received after that time might be too late.
>
Build results:
total: 168 pass: 168 fail: 0
Qemu test results:
total: 404 pass: 404 fail: 0
Tested-by: Guenter Roeck <[email protected]>
Guenter
From: Samuel Thibault <[email protected]>
commit f0992098cadb4c9c6a00703b66cafe604e178fea upstream.
Speakup exposing a line discipline allows userland to try to use it,
while it is deemed to be useless, and thus uselessly exposes potential
bugs. One of them is simply that in such a case if the line sends data,
spk_ttyio_receive_buf2 is called and crashes since spk_ttyio_synth
is NULL.
This change restricts the use of the speakup line discipline to
speakup drivers, thus avoiding such kind of issues altogether.
Cc: [email protected]
Reported-by: Shisong Qin <[email protected]>
Signed-off-by: Samuel Thibault <[email protected]>
Tested-by: Shisong Qin <[email protected]>
Link: https://lore.kernel.org/r/20201129193523.hm3f6n5xrn6fiyyc@function
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/staging/speakup/spk_ttyio.c | 38 +++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
--- a/drivers/staging/speakup/spk_ttyio.c
+++ b/drivers/staging/speakup/spk_ttyio.c
@@ -46,28 +46,20 @@ static int spk_ttyio_ldisc_open(struct t
{
struct spk_ldisc_data *ldisc_data;
+ if (tty != speakup_tty)
+ /* Somebody tried to use this line discipline outside speakup */
+ return -ENODEV;
+
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
- mutex_lock(&speakup_tty_mutex);
- if (speakup_tty) {
- mutex_unlock(&speakup_tty_mutex);
- return -EBUSY;
- }
- speakup_tty = tty;
-
ldisc_data = kmalloc(sizeof(struct spk_ldisc_data), GFP_KERNEL);
- if (!ldisc_data) {
- speakup_tty = NULL;
- mutex_unlock(&speakup_tty_mutex);
- pr_err("speakup: Failed to allocate ldisc_data.\n");
+ if (!ldisc_data)
return -ENOMEM;
- }
sema_init(&ldisc_data->sem, 0);
ldisc_data->buf_free = true;
- speakup_tty->disc_data = ldisc_data;
- mutex_unlock(&speakup_tty_mutex);
+ tty->disc_data = ldisc_data;
return 0;
}
@@ -184,9 +176,25 @@ static int spk_ttyio_initialise_ldisc(st
tty_unlock(tty);
+ mutex_lock(&speakup_tty_mutex);
+ speakup_tty = tty;
ret = tty_set_ldisc(tty, N_SPEAKUP);
if (ret)
- pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
+ speakup_tty = NULL;
+ mutex_unlock(&speakup_tty_mutex);
+
+ if (!ret)
+ /* Success */
+ return 0;
+
+ pr_err("speakup: Failed to set N_SPEAKUP on tty\n");
+
+ tty_lock(tty);
+ if (tty->ops->close)
+ tty->ops->close(tty, NULL);
+ tty_unlock(tty);
+
+ tty_kclose(tty);
return ret;
}
On Thu, 10 Dec 2020 at 20:01, Greg Kroah-Hartman
<[email protected]> wrote:
>
> This is the start of the stable review cycle for the 4.14.212 release.
> There are 31 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 Sat, 12 Dec 2020 14:25:47 +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/v4.x/stable-review/patch-4.14.212-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-4.14.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
Results from Linaro’s test farm.
No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing <[email protected]>
Summary
------------------------------------------------------------------------
kernel: 4.14.212-rc1
git repo: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git
git branch: linux-4.14.y
git commit: ad2d75a4fc6e81e11297320a54abb176b5de8dca
git describe: v4.14.211-31-gad2d75a4fc6e
Test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-4.14.y/build/v4.14.211-31-gad2d75a4fc6e
No regressions (compared to build v4.14.211)
No fixes (compared to build v4.14.211)
Ran 36132 total tests in the following environments and test suites.
Environments
--------------
- arm
- arm64
- dragonboard-410c - arm64
- hi6220-hikey - arm64
- i386
- juno-r2 - arm64
- mips
- qemu-arm64-kasan
- qemu-x86_64-kasan
- qemu_arm
- qemu_arm64
- qemu_arm64-compat
- qemu_i386
- qemu_x86_64
- qemu_x86_64-compat
- sparc
- x15 - arm
- x86_64
- x86-kasan
Test Suites
-----------
* build
* linux-log-parser
* install-android-platform-tools-r2600
* ltp-cap_bounds-tests
* ltp-containers-tests
* ltp-cpuhotplug-tests
* ltp-crypto-tests
* ltp-fcntl-locktests-tests
* ltp-filecaps-tests
* ltp-fs_bind-tests
* ltp-fs_perms_simple-tests
* ltp-fsx-tests
* ltp-hugetlb-tests
* ltp-mm-tests
* ltp-nptl-tests
* ltp-pty-tests
* ltp-securebits-tests
* perf
* ltp-commands-tests
* ltp-controllers-tests
* ltp-cve-tests
* ltp-dio-tests
* ltp-io-tests
* ltp-ipc-tests
* ltp-math-tests
* ltp-sched-tests
* ltp-syscalls-tests
* ltp-tracing-tests
* network-basic-tests
* libhugetlbfs
* ltp-fs-tests
* ltp-open-posix-tests
* v4l2-compliance
* rcutorture
* fwts
* kvm-unit-tests
--
Linaro LKFT
https://lkft.linaro.org
From: Masami Hiramatsu <[email protected]>
commit 4e9a5ae8df5b3365183150f6df49e49dece80d8c upstream
Since insn.prefixes.nbytes can be bigger than the size of
insn.prefixes.bytes[] when a prefix is repeated, the proper check must
be
insn.prefixes.bytes[i] != 0 and i < 4
instead of using insn.prefixes.nbytes.
Introduce a for_each_insn_prefix() macro for this purpose. Debugged by
Kees Cook <[email protected]>.
[ bp: Massage commit message, sync with the respective header in tools/
and drop "we". ]
Fixes: 2b1444983508 ("uprobes, mm, x86: Add the ability to install and remove uprobes breakpoints")
Reported-by: [email protected]
Signed-off-by: Masami Hiramatsu <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Reviewed-by: Srikar Dronamraju <[email protected]>
Cc: [email protected]
Link: https://lkml.kernel.org/r/160697103739.3146288.7437620795200799020.stgit@devnote2
[sudip: adjust context, use old insn.h]
Signed-off-by: Sudip Mukherjee <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/x86/include/asm/insn.h | 15 +++++++++++++++
arch/x86/kernel/uprobes.c | 10 ++++++----
tools/objtool/arch/x86/include/asm/insn.h | 15 +++++++++++++++
3 files changed, 36 insertions(+), 4 deletions(-)
--- a/arch/x86/include/asm/insn.h
+++ b/arch/x86/include/asm/insn.h
@@ -208,6 +208,21 @@ static inline int insn_offset_immediate(
return insn_offset_displacement(insn) + insn->displacement.nbytes;
}
+/**
+ * for_each_insn_prefix() -- Iterate prefixes in the instruction
+ * @insn: Pointer to struct insn.
+ * @idx: Index storage.
+ * @prefix: Prefix byte.
+ *
+ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix
+ * and the index is stored in @idx (note that this @idx is just for a cursor,
+ * do not change it.)
+ * Since prefixes.nbytes can be bigger than 4 if some prefixes
+ * are repeated, it cannot be used for looping over the prefixes.
+ */
+#define for_each_insn_prefix(insn, idx, prefix) \
+ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++)
+
#define POP_SS_OPCODE 0x1f
#define MOV_SREG_OPCODE 0x8e
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -268,10 +268,11 @@ static volatile u32 good_2byte_insns[256
static bool is_prefix_bad(struct insn *insn)
{
+ insn_byte_t p;
int i;
- for (i = 0; i < insn->prefixes.nbytes; i++) {
- switch (insn->prefixes.bytes[i]) {
+ for_each_insn_prefix(insn, i, p) {
+ switch (p) {
case 0x26: /* INAT_PFX_ES */
case 0x2E: /* INAT_PFX_CS */
case 0x36: /* INAT_PFX_DS */
@@ -711,6 +712,7 @@ static const struct uprobe_xol_ops branc
static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
{
u8 opc1 = OPCODE1(insn);
+ insn_byte_t p;
int i;
switch (opc1) {
@@ -741,8 +743,8 @@ static int branch_setup_xol_ops(struct a
* Intel and AMD behavior differ in 64-bit mode: Intel ignores 66 prefix.
* No one uses these insns, reject any branch insns with such prefix.
*/
- for (i = 0; i < insn->prefixes.nbytes; i++) {
- if (insn->prefixes.bytes[i] == 0x66)
+ for_each_insn_prefix(insn, i, p) {
+ if (p == 0x66)
return -ENOTSUPP;
}
--- a/tools/objtool/arch/x86/include/asm/insn.h
+++ b/tools/objtool/arch/x86/include/asm/insn.h
@@ -208,6 +208,21 @@ static inline int insn_offset_immediate(
return insn_offset_displacement(insn) + insn->displacement.nbytes;
}
+/**
+ * for_each_insn_prefix() -- Iterate prefixes in the instruction
+ * @insn: Pointer to struct insn.
+ * @idx: Index storage.
+ * @prefix: Prefix byte.
+ *
+ * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix
+ * and the index is stored in @idx (note that this @idx is just for a cursor,
+ * do not change it.)
+ * Since prefixes.nbytes can be bigger than 4 if some prefixes
+ * are repeated, it cannot be used for looping over the prefixes.
+ */
+#define for_each_insn_prefix(insn, idx, prefix) \
+ for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++)
+
#define POP_SS_OPCODE 0x1f
#define MOV_SREG_OPCODE 0x8e
From: Bob Peterson <[email protected]>
commit 778721510e84209f78e31e2ccb296ae36d623f5e upstream.
If gfs2 tries to mount a (corrupt) file system that has no resource
groups it still tries to set preferences on the first one, which causes
a kernel null pointer dereference. This patch adds a check to function
gfs2_ri_update so this condition is detected and reported back as an
error.
Reported-by: [email protected]
Signed-off-by: Bob Peterson <[email protected]>
Signed-off-by: Andreas Gruenbacher <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/gfs2/rgrp.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -990,6 +990,10 @@ static int gfs2_ri_update(struct gfs2_in
if (error < 0)
return error;
+ if (RB_EMPTY_ROOT(&sdp->sd_rindex_tree)) {
+ fs_err(sdp, "no resource groups found in the file system.\n");
+ return -ENOENT;
+ }
set_rgrp_preferences(sdp);
sdp->sd_rindex_uptodate = 1;
From: Kailang Yang <[email protected]>
commit e5782a5d5054bf1e03cb7fbd87035037c2a22698 upstream.
Enable new codec supported for ALC897.
Signed-off-by: Kailang Yang <[email protected]>
Cc: <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/pci/hda/patch_realtek.c | 2 ++
1 file changed, 2 insertions(+)
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -392,6 +392,7 @@ static void alc_fill_eapd_coef(struct hd
alc_update_coef_idx(codec, 0x7, 1<<5, 0);
break;
case 0x10ec0892:
+ case 0x10ec0897:
alc_update_coef_idx(codec, 0x7, 1<<5, 0);
break;
case 0x10ec0899:
@@ -8443,6 +8444,7 @@ static const struct hda_device_id snd_hd
HDA_CODEC_ENTRY(0x10ec0888, "ALC888", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0889, "ALC889", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0892, "ALC892", patch_alc662),
+ HDA_CODEC_ENTRY(0x10ec0897, "ALC897", patch_alc662),
HDA_CODEC_ENTRY(0x10ec0899, "ALC898", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0900, "ALC1150", patch_alc882),
HDA_CODEC_ENTRY(0x10ec0b00, "ALCS1200A", patch_alc882),
From: Lukas Wunner <[email protected]>
[ Upstream commit e1483ac030fb4c57734289742f1c1d38dca61e22 ]
bcm2835_spi_remove() accesses the driver's private data after calling
spi_unregister_controller() even though that function releases the last
reference on the spi_controller and thereby frees the private data.
Fix by switching over to the new devm_spi_alloc_master() helper which
keeps the private data accessible until the driver has unbound.
Fixes: f8043872e796 ("spi: add driver for BCM2835")
Reported-by: Sascha Hauer <[email protected]>
Reported-by: Florian Fainelli <[email protected]>
Signed-off-by: Lukas Wunner <[email protected]>
Cc: <[email protected]> # v3.10+: 5e844cc37a5c: spi: Introduce device-managed SPI controller allocation
Cc: <[email protected]> # v3.10+
Cc: Vladimir Oltean <[email protected]>
Tested-by: Florian Fainelli <[email protected]>
Acked-by: Florian Fainelli <[email protected]>
Link: https://lore.kernel.org/r/ad66e0a0ad96feb848814842ecf5b6a4539ef35c.1605121038.git.lukas@wunner.de
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/spi/spi-bcm2835.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -737,7 +737,7 @@ static int bcm2835_spi_probe(struct plat
struct resource *res;
int err;
- master = spi_alloc_master(&pdev->dev, sizeof(*bs));
+ master = devm_spi_alloc_master(&pdev->dev, sizeof(*bs));
if (!master) {
dev_err(&pdev->dev, "spi_alloc_master() failed\n");
return -ENOMEM;
@@ -759,23 +759,20 @@ static int bcm2835_spi_probe(struct plat
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bs->regs = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(bs->regs)) {
- err = PTR_ERR(bs->regs);
- goto out_master_put;
- }
+ if (IS_ERR(bs->regs))
+ return PTR_ERR(bs->regs);
bs->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(bs->clk)) {
err = PTR_ERR(bs->clk);
dev_err(&pdev->dev, "could not get clk: %d\n", err);
- goto out_master_put;
+ return err;
}
bs->irq = platform_get_irq(pdev, 0);
if (bs->irq <= 0) {
dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq);
- err = bs->irq ? bs->irq : -ENODEV;
- goto out_master_put;
+ return bs->irq ? bs->irq : -ENODEV;
}
clk_prepare_enable(bs->clk);
@@ -803,8 +800,6 @@ static int bcm2835_spi_probe(struct plat
out_clk_disable:
clk_disable_unprepare(bs->clk);
-out_master_put:
- spi_master_put(master);
return err;
}
From: Lukas Wunner <[email protected]>
[ Upstream commit 5e844cc37a5cbaa460e68f9a989d321d63088a89 ]
SPI driver probing currently comprises two steps, whereas removal
comprises only one step:
spi_alloc_master()
spi_register_controller()
spi_unregister_controller()
That's because spi_unregister_controller() calls device_unregister()
instead of device_del(), thereby releasing the reference on the
spi_controller which was obtained by spi_alloc_master().
An SPI driver's private data is contained in the same memory allocation
as the spi_controller struct. Thus, once spi_unregister_controller()
has been called, the private data is inaccessible. But some drivers
need to access it after spi_unregister_controller() to perform further
teardown steps.
Introduce devm_spi_alloc_master() and devm_spi_alloc_slave(), which
release a reference on the spi_controller struct only after the driver
has unbound, thereby keeping the memory allocation accessible. Change
spi_unregister_controller() to not release a reference if the
spi_controller was allocated by one of these new devm functions.
The present commit is small enough to be backportable to stable.
It allows fixing drivers which use the private data in their ->remove()
hook after it's been freed. It also allows fixing drivers which neglect
to release a reference on the spi_controller in the probe error path.
Long-term, most SPI drivers shall be moved over to the devm functions
introduced herein. The few that can't shall be changed in a treewide
commit to explicitly release the last reference on the controller.
That commit shall amend spi_unregister_controller() to no longer release
a reference, thereby completing the migration.
As a result, the behaviour will be less surprising and more consistent
with subsystems such as IIO, which also includes the private data in the
allocation of the generic iio_dev struct, but calls device_del() in
iio_device_unregister().
Signed-off-by: Lukas Wunner <[email protected]>
Link: https://lore.kernel.org/r/272bae2ef08abd21388c98e23729886663d19192.1605121038.git.lukas@wunner.de
Signed-off-by: Mark Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/spi/spi.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++-
include/linux/spi/spi.h | 19 +++++++++++++++
2 files changed, 76 insertions(+), 1 deletion(-)
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -2043,6 +2043,49 @@ struct spi_controller *__spi_alloc_contr
}
EXPORT_SYMBOL_GPL(__spi_alloc_controller);
+static void devm_spi_release_controller(struct device *dev, void *ctlr)
+{
+ spi_controller_put(*(struct spi_controller **)ctlr);
+}
+
+/**
+ * __devm_spi_alloc_controller - resource-managed __spi_alloc_controller()
+ * @dev: physical device of SPI controller
+ * @size: how much zeroed driver-private data to allocate
+ * @slave: whether to allocate an SPI master (false) or SPI slave (true)
+ * Context: can sleep
+ *
+ * Allocate an SPI controller and automatically release a reference on it
+ * when @dev is unbound from its driver. Drivers are thus relieved from
+ * having to call spi_controller_put().
+ *
+ * The arguments to this function are identical to __spi_alloc_controller().
+ *
+ * Return: the SPI controller structure on success, else NULL.
+ */
+struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
+ unsigned int size,
+ bool slave)
+{
+ struct spi_controller **ptr, *ctlr;
+
+ ptr = devres_alloc(devm_spi_release_controller, sizeof(*ptr),
+ GFP_KERNEL);
+ if (!ptr)
+ return NULL;
+
+ ctlr = __spi_alloc_controller(dev, size, slave);
+ if (ctlr) {
+ *ptr = ctlr;
+ devres_add(dev, ptr);
+ } else {
+ devres_free(ptr);
+ }
+
+ return ctlr;
+}
+EXPORT_SYMBOL_GPL(__devm_spi_alloc_controller);
+
#ifdef CONFIG_OF
static int of_spi_register_master(struct spi_controller *ctlr)
{
@@ -2261,6 +2304,11 @@ int devm_spi_register_controller(struct
}
EXPORT_SYMBOL_GPL(devm_spi_register_controller);
+static int devm_spi_match_controller(struct device *dev, void *res, void *ctlr)
+{
+ return *(struct spi_controller **)res == ctlr;
+}
+
static int __unregister(struct device *dev, void *null)
{
spi_unregister_device(to_spi_device(dev));
@@ -2300,7 +2348,15 @@ void spi_unregister_controller(struct sp
list_del(&ctlr->list);
mutex_unlock(&board_lock);
- device_unregister(&ctlr->dev);
+ device_del(&ctlr->dev);
+
+ /* Release the last reference on the controller if its driver
+ * has not yet been converted to devm_spi_alloc_master/slave().
+ */
+ if (!devres_find(ctlr->dev.parent, devm_spi_release_controller,
+ devm_spi_match_controller, ctlr))
+ put_device(&ctlr->dev);
+
/* free bus id */
mutex_lock(&board_lock);
if (found == ctlr)
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -638,6 +638,25 @@ static inline struct spi_controller *spi
return __spi_alloc_controller(host, size, true);
}
+struct spi_controller *__devm_spi_alloc_controller(struct device *dev,
+ unsigned int size,
+ bool slave);
+
+static inline struct spi_controller *devm_spi_alloc_master(struct device *dev,
+ unsigned int size)
+{
+ return __devm_spi_alloc_controller(dev, size, false);
+}
+
+static inline struct spi_controller *devm_spi_alloc_slave(struct device *dev,
+ unsigned int size)
+{
+ if (!IS_ENABLED(CONFIG_SPI_SLAVE))
+ return NULL;
+
+ return __devm_spi_alloc_controller(dev, size, true);
+}
+
extern int spi_register_controller(struct spi_controller *ctlr);
extern int devm_spi_register_controller(struct device *dev,
struct spi_controller *ctlr);