* [PATCH AUTOSEL 5.10 2/5] usb: pci-quirks: group AMD specific quirk code together
2023-11-07 23:24 [PATCH AUTOSEL 5.10 1/5] tty: vcc: Add check for kstrdup() in vcc_probe() Sasha Levin
@ 2023-11-07 23:24 ` Sasha Levin
2023-11-07 23:24 ` [PATCH AUTOSEL 5.10 3/5] usb: pci-quirks: handle HAS_IOPORT dependency for UHCI handoff Sasha Levin
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-11-07 23:24 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Niklas Schnelle, Arnd Bergmann, Greg Kroah-Hartman, Sasha Levin,
mathias.nyman, linux-usb
From: Niklas Schnelle <schnelle@linux.ibm.com>
[ Upstream commit 7ca9f9ba8aa7380dee5dd8346b57bbaf198b075a ]
A follow on patch will introduce CONFIG_USB_PCI_AMD governing the AMD
quirk and adding its compile time dependency on HAS_IOPORT. In order to
minimize the number of #ifdefs in C files and make that patch easier
to read first group the code together. This is pure code movement
no functional change is intended.
Co-developed-by: Arnd Bergmann <arnd@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@kernel.org>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Link: https://lore.kernel.org/r/20230911125653.1393895-2-schnelle@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/pci-quirks.c | 119 +++++++++++++++++-----------------
drivers/usb/host/pci-quirks.h | 14 ++--
2 files changed, 68 insertions(+), 65 deletions(-)
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index ef08d68b97149..4b0e344916ebc 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -60,6 +60,22 @@
#define EHCI_USBLEGCTLSTS 4 /* legacy control/status */
#define EHCI_USBLEGCTLSTS_SOOE (1 << 13) /* SMI on ownership change */
+/* ASMEDIA quirk use */
+#define ASMT_DATA_WRITE0_REG 0xF8
+#define ASMT_DATA_WRITE1_REG 0xFC
+#define ASMT_CONTROL_REG 0xE0
+#define ASMT_CONTROL_WRITE_BIT 0x02
+#define ASMT_WRITEREG_CMD 0x10423
+#define ASMT_FLOWCTL_ADDR 0xFA30
+#define ASMT_FLOWCTL_DATA 0xBA
+#define ASMT_PSEUDO_DATA 0
+
+/* Intel quirk use */
+#define USB_INTEL_XUSB2PR 0xD0
+#define USB_INTEL_USB2PRM 0xD4
+#define USB_INTEL_USB3_PSSEN 0xD8
+#define USB_INTEL_USB3PRM 0xDC
+
/* AMD quirk use */
#define AB_REG_BAR_LOW 0xe0
#define AB_REG_BAR_HIGH 0xe1
@@ -93,21 +109,6 @@
#define NB_PIF0_PWRDOWN_0 0x01100012
#define NB_PIF0_PWRDOWN_1 0x01100013
-#define USB_INTEL_XUSB2PR 0xD0
-#define USB_INTEL_USB2PRM 0xD4
-#define USB_INTEL_USB3_PSSEN 0xD8
-#define USB_INTEL_USB3PRM 0xDC
-
-/* ASMEDIA quirk use */
-#define ASMT_DATA_WRITE0_REG 0xF8
-#define ASMT_DATA_WRITE1_REG 0xFC
-#define ASMT_CONTROL_REG 0xE0
-#define ASMT_CONTROL_WRITE_BIT 0x02
-#define ASMT_WRITEREG_CMD 0x10423
-#define ASMT_FLOWCTL_ADDR 0xFA30
-#define ASMT_FLOWCTL_DATA 0xBA
-#define ASMT_PSEUDO_DATA 0
-
/*
* amd_chipset_gen values represent AMD different chipset generations
*/
@@ -460,50 +461,6 @@ void usb_amd_quirk_pll_disable(void)
}
EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable);
-static int usb_asmedia_wait_write(struct pci_dev *pdev)
-{
- unsigned long retry_count;
- unsigned char value;
-
- for (retry_count = 1000; retry_count > 0; --retry_count) {
-
- pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value);
-
- if (value == 0xff) {
- dev_err(&pdev->dev, "%s: check_ready ERROR", __func__);
- return -EIO;
- }
-
- if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
- return 0;
-
- udelay(50);
- }
-
- dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
- return -ETIMEDOUT;
-}
-
-void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
-{
- if (usb_asmedia_wait_write(pdev) != 0)
- return;
-
- /* send command and address to device */
- pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD);
- pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR);
- pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
-
- if (usb_asmedia_wait_write(pdev) != 0)
- return;
-
- /* send data to device */
- pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA);
- pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA);
- pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
-}
-EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
-
void usb_amd_quirk_pll_enable(void)
{
usb_amd_quirk_pll(0);
@@ -633,6 +590,50 @@ bool usb_amd_pt_check_port(struct device *device, int port)
}
EXPORT_SYMBOL_GPL(usb_amd_pt_check_port);
+static int usb_asmedia_wait_write(struct pci_dev *pdev)
+{
+ unsigned long retry_count;
+ unsigned char value;
+
+ for (retry_count = 1000; retry_count > 0; --retry_count) {
+
+ pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value);
+
+ if (value == 0xff) {
+ dev_err(&pdev->dev, "%s: check_ready ERROR", __func__);
+ return -EIO;
+ }
+
+ if ((value & ASMT_CONTROL_WRITE_BIT) == 0)
+ return 0;
+
+ udelay(50);
+ }
+
+ dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__);
+ return -ETIMEDOUT;
+}
+
+void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
+{
+ if (usb_asmedia_wait_write(pdev) != 0)
+ return;
+
+ /* send command and address to device */
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD);
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR);
+ pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+
+ if (usb_asmedia_wait_write(pdev) != 0)
+ return;
+
+ /* send data to device */
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA);
+ pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA);
+ pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT);
+}
+EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
+
/*
* Make sure the controller is completely inactive, unable to
* generate interrupts or do DMA.
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h
index e729de21fad7a..cde2263a9d2e4 100644
--- a/drivers/usb/host/pci-quirks.h
+++ b/drivers/usb/host/pci-quirks.h
@@ -3,8 +3,6 @@
#define __LINUX_USB_PCI_QUIRKS_H
#ifdef CONFIG_USB_PCI
-void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
-int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev);
bool usb_amd_hang_symptom_quirk(void);
bool usb_amd_prefetch_quirk(void);
@@ -12,23 +10,27 @@ void usb_amd_dev_put(void);
bool usb_amd_quirk_pll_check(void);
void usb_amd_quirk_pll_disable(void);
void usb_amd_quirk_pll_enable(void);
+void sb800_prefetch(struct device *dev, int on);
+bool usb_amd_pt_check_port(struct device *device, int port);
+
+void uhci_reset_hc(struct pci_dev *pdev, unsigned long base);
+int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base);
void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev);
void usb_enable_intel_xhci_ports(struct pci_dev *xhci_pdev);
void usb_disable_xhci_ports(struct pci_dev *xhci_pdev);
-void sb800_prefetch(struct device *dev, int on);
-bool usb_amd_pt_check_port(struct device *device, int port);
#else
struct pci_dev;
static inline void usb_amd_quirk_pll_disable(void) {}
static inline void usb_amd_quirk_pll_enable(void) {}
-static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
static inline void usb_amd_dev_put(void) {}
-static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
static inline void sb800_prefetch(struct device *dev, int on) {}
static inline bool usb_amd_pt_check_port(struct device *device, int port)
{
return false;
}
+
+static inline void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) {}
+static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {}
#endif /* CONFIG_USB_PCI */
#endif /* __LINUX_USB_PCI_QUIRKS_H */
--
2.42.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH AUTOSEL 5.10 3/5] usb: pci-quirks: handle HAS_IOPORT dependency for UHCI handoff
2023-11-07 23:24 [PATCH AUTOSEL 5.10 1/5] tty: vcc: Add check for kstrdup() in vcc_probe() Sasha Levin
2023-11-07 23:24 ` [PATCH AUTOSEL 5.10 2/5] usb: pci-quirks: group AMD specific quirk code together Sasha Levin
@ 2023-11-07 23:24 ` Sasha Levin
2023-11-07 23:24 ` [PATCH AUTOSEL 5.10 4/5] usb: gadget: f_ncm: Always set current gadget in ncm_bind() Sasha Levin
2023-11-07 23:25 ` [PATCH AUTOSEL 5.10 5/5] 9p/trans_fd: Annotate data-racy writes to file::f_flags Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-11-07 23:24 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Niklas Schnelle, Arnd Bergmann, Greg Kroah-Hartman, Sasha Levin,
mathias.nyman, linux-usb
From: Niklas Schnelle <schnelle@linux.ibm.com>
[ Upstream commit 358ad297e379ff548247e3e24c6619559942bfdd ]
In a future patch HAS_IOPORT=n will result in inb()/outb() and friends
not being declared. With the AMD quirk handled USB PCI quirks still use
inw() in uhci_check_and_reset_hc() and thus indirectly in
quirk_usb_handoff_uhci(). Handle this by conditionally compiling
uhci_check_and_reset_hc() and stubbing out quirk_usb_handoff_uhci() when
HAS_IOPORT is not available.
Co-developed-by: Arnd Bergmann <arnd@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@kernel.org>
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Link: https://lore.kernel.org/r/20230911125653.1393895-4-schnelle@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/host/pci-quirks.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 4b0e344916ebc..d9ac4cbe99518 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -634,6 +634,16 @@ void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev)
}
EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol);
+static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
+{
+ u16 cmd;
+
+ return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
+}
+
+#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
+
+#if defined(CONFIG_HAS_IOPORT) && IS_ENABLED(CONFIG_USB_UHCI_HCD)
/*
* Make sure the controller is completely inactive, unable to
* generate interrupts or do DMA.
@@ -715,14 +725,7 @@ int uhci_check_and_reset_hc(struct pci_dev *pdev, unsigned long base)
}
EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
-static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
-{
- u16 cmd;
- return !pci_read_config_word(pdev, PCI_COMMAND, &cmd) && (cmd & mask);
-}
-
#define pio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_IO)
-#define mmio_enabled(dev) io_type_enabled(dev, PCI_COMMAND_MEMORY)
static void quirk_usb_handoff_uhci(struct pci_dev *pdev)
{
@@ -742,6 +745,12 @@ static void quirk_usb_handoff_uhci(struct pci_dev *pdev)
uhci_check_and_reset_hc(pdev, base);
}
+#else /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */
+
+static void quirk_usb_handoff_uhci(struct pci_dev *pdev) {}
+
+#endif /* defined(CONFIG_HAS_IOPORT && IS_ENABLED(CONFIG_USB_UHCI_HCD) */
+
static int mmio_resource_enabled(struct pci_dev *pdev, int idx)
{
return pci_resource_start(pdev, idx) && mmio_enabled(pdev);
--
2.42.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH AUTOSEL 5.10 4/5] usb: gadget: f_ncm: Always set current gadget in ncm_bind()
2023-11-07 23:24 [PATCH AUTOSEL 5.10 1/5] tty: vcc: Add check for kstrdup() in vcc_probe() Sasha Levin
2023-11-07 23:24 ` [PATCH AUTOSEL 5.10 2/5] usb: pci-quirks: group AMD specific quirk code together Sasha Levin
2023-11-07 23:24 ` [PATCH AUTOSEL 5.10 3/5] usb: pci-quirks: handle HAS_IOPORT dependency for UHCI handoff Sasha Levin
@ 2023-11-07 23:24 ` Sasha Levin
2023-11-07 23:25 ` [PATCH AUTOSEL 5.10 5/5] 9p/trans_fd: Annotate data-racy writes to file::f_flags Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-11-07 23:24 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Hardik Gajjar, Greg Kroah-Hartman, Sasha Levin, quic_linyyuan,
maze, quic_kriskura, linux-usb
From: Hardik Gajjar <hgajjar@de.adit-jv.com>
[ Upstream commit a04224da1f3424b2c607b12a3bd1f0e302fb8231 ]
Previously, gadget assignment to the net device occurred exclusively
during the initial binding attempt.
Nevertheless, the gadget pointer could change during bind/unbind
cycles due to various conditions, including the unloading/loading
of the UDC device driver or the detachment/reconnection of an
OTG-capable USB hub device.
This patch relocates the gether_set_gadget() function out from
ncm_opts->bound condition check, ensuring that the correct gadget
is assigned during each bind request.
The provided logs demonstrate the consistency of ncm_opts throughout
the power cycle, while the gadget may change.
* OTG hub connected during boot up and assignment of gadget and
ncm_opts pointer
[ 2.366301] usb 2-1.5: New USB device found, idVendor=2996, idProduct=0105
[ 2.366304] usb 2-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2.366306] usb 2-1.5: Product: H2H Bridge
[ 2.366308] usb 2-1.5: Manufacturer: Aptiv
[ 2.366309] usb 2-1.5: SerialNumber: 13FEB2021
[ 2.427989] usb 2-1.5: New USB device found, VID=2996, PID=0105
[ 2.428959] dabridge 2-1.5:1.0: dabridge 2-4 total endpoints=5, 0000000093a8d681
[ 2.429710] dabridge 2-1.5:1.0: P(0105) D(22.06.22) F(17.3.16) H(1.1) high-speed
[ 2.429714] dabridge 2-1.5:1.0: Hub 2-2 P(0151) V(06.87)
[ 2.429956] dabridge 2-1.5:1.0: All downstream ports in host mode
[ 2.430093] gadget 000000003c414d59 ------> gadget pointer
* NCM opts and associated gadget pointer during First ncm_bind
[ 34.763929] NCM opts 00000000aa304ac9
[ 34.763930] NCM gadget 000000003c414d59
* OTG capable hub disconnecte or assume driver unload.
[ 97.203114] usb 2-1: USB disconnect, device number 2
[ 97.203118] usb 2-1.1: USB disconnect, device number 3
[ 97.209217] usb 2-1.5: USB disconnect, device number 4
[ 97.230990] dabr_udc deleted
* Reconnect the OTG hub or load driver assaign new gadget pointer.
[ 111.534035] usb 2-1.1: New USB device found, idVendor=2996, idProduct=0120, bcdDevice= 6.87
[ 111.534038] usb 2-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 111.534040] usb 2-1.1: Product: Vendor
[ 111.534041] usb 2-1.1: Manufacturer: Aptiv
[ 111.534042] usb 2-1.1: SerialNumber: Superior
[ 111.535175] usb 2-1.1: New USB device found, VID=2996, PID=0120
[ 111.610995] usb 2-1.5: new high-speed USB device number 8 using xhci-hcd
[ 111.630052] usb 2-1.5: New USB device found, idVendor=2996, idProduct=0105, bcdDevice=21.02
[ 111.630055] usb 2-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 111.630057] usb 2-1.5: Product: H2H Bridge
[ 111.630058] usb 2-1.5: Manufacturer: Aptiv
[ 111.630059] usb 2-1.5: SerialNumber: 13FEB2021
[ 111.687464] usb 2-1.5: New USB device found, VID=2996, PID=0105
[ 111.690375] dabridge 2-1.5:1.0: dabridge 2-8 total endpoints=5, 000000000d87c961
[ 111.691172] dabridge 2-1.5:1.0: P(0105) D(22.06.22) F(17.3.16) H(1.1) high-speed
[ 111.691176] dabridge 2-1.5:1.0: Hub 2-6 P(0151) V(06.87)
[ 111.691646] dabridge 2-1.5:1.0: All downstream ports in host mode
[ 111.692298] gadget 00000000dc72f7a9 --------> new gadget ptr on connect
* NCM opts and associated gadget pointer during second ncm_bind
[ 113.271786] NCM opts 00000000aa304ac9 -----> same opts ptr used during first bind
[ 113.271788] NCM gadget 00000000dc72f7a9 ----> however new gaget ptr, that will not set
in net_device due to ncm_opts->bound = true
Signed-off-by: Hardik Gajjar <hgajjar@de.adit-jv.com>
Link: https://lore.kernel.org/r/20231020153324.82794-1-hgajjar@de.adit-jv.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/gadget/function/f_ncm.c | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c
index 00aea45a04e95..d42cd1d036bdf 100644
--- a/drivers/usb/gadget/function/f_ncm.c
+++ b/drivers/usb/gadget/function/f_ncm.c
@@ -1435,7 +1435,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
struct usb_composite_dev *cdev = c->cdev;
struct f_ncm *ncm = func_to_ncm(f);
struct usb_string *us;
- int status;
+ int status = 0;
struct usb_ep *ep;
struct f_ncm_opts *ncm_opts;
@@ -1453,22 +1453,17 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f)
f->os_desc_table[0].os_desc = &ncm_opts->ncm_os_desc;
}
- /*
- * in drivers/usb/gadget/configfs.c:configfs_composite_bind()
- * configurations are bound in sequence with list_for_each_entry,
- * in each configuration its functions are bound in sequence
- * with list_for_each_entry, so we assume no race condition
- * with regard to ncm_opts->bound access
- */
- if (!ncm_opts->bound) {
- mutex_lock(&ncm_opts->lock);
- gether_set_gadget(ncm_opts->net, cdev->gadget);
+ mutex_lock(&ncm_opts->lock);
+ gether_set_gadget(ncm_opts->net, cdev->gadget);
+ if (!ncm_opts->bound)
status = gether_register_netdev(ncm_opts->net);
- mutex_unlock(&ncm_opts->lock);
- if (status)
- goto fail;
- ncm_opts->bound = true;
- }
+ mutex_unlock(&ncm_opts->lock);
+
+ if (status)
+ goto fail;
+
+ ncm_opts->bound = true;
+
us = usb_gstrings_attach(cdev, ncm_strings,
ARRAY_SIZE(ncm_string_defs));
if (IS_ERR(us)) {
--
2.42.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH AUTOSEL 5.10 5/5] 9p/trans_fd: Annotate data-racy writes to file::f_flags
2023-11-07 23:24 [PATCH AUTOSEL 5.10 1/5] tty: vcc: Add check for kstrdup() in vcc_probe() Sasha Levin
` (2 preceding siblings ...)
2023-11-07 23:24 ` [PATCH AUTOSEL 5.10 4/5] usb: gadget: f_ncm: Always set current gadget in ncm_bind() Sasha Levin
@ 2023-11-07 23:25 ` Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2023-11-07 23:25 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Marco Elver, syzbot+e441aeeb422763cc5511, Dominique Martinet,
Sasha Levin, ericvh, lucho, davem, edumazet, kuba, pabeni, v9fs,
netdev
From: Marco Elver <elver@google.com>
[ Upstream commit 355f074609dbf3042900ea9d30fcd2b0c323a365 ]
syzbot reported:
| BUG: KCSAN: data-race in p9_fd_create / p9_fd_create
|
| read-write to 0xffff888130fb3d48 of 4 bytes by task 15599 on cpu 0:
| p9_fd_open net/9p/trans_fd.c:842 [inline]
| p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092
| p9_client_create+0x595/0xa70 net/9p/client.c:1010
| v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410
| v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123
| legacy_get_tree+0x74/0xd0 fs/fs_context.c:611
| vfs_get_tree+0x51/0x190 fs/super.c:1519
| do_new_mount+0x203/0x660 fs/namespace.c:3335
| path_mount+0x496/0xb30 fs/namespace.c:3662
| do_mount fs/namespace.c:3675 [inline]
| __do_sys_mount fs/namespace.c:3884 [inline]
| [...]
|
| read-write to 0xffff888130fb3d48 of 4 bytes by task 15563 on cpu 1:
| p9_fd_open net/9p/trans_fd.c:842 [inline]
| p9_fd_create+0x210/0x250 net/9p/trans_fd.c:1092
| p9_client_create+0x595/0xa70 net/9p/client.c:1010
| v9fs_session_init+0xf9/0xd90 fs/9p/v9fs.c:410
| v9fs_mount+0x69/0x630 fs/9p/vfs_super.c:123
| legacy_get_tree+0x74/0xd0 fs/fs_context.c:611
| vfs_get_tree+0x51/0x190 fs/super.c:1519
| do_new_mount+0x203/0x660 fs/namespace.c:3335
| path_mount+0x496/0xb30 fs/namespace.c:3662
| do_mount fs/namespace.c:3675 [inline]
| __do_sys_mount fs/namespace.c:3884 [inline]
| [...]
|
| value changed: 0x00008002 -> 0x00008802
Within p9_fd_open(), O_NONBLOCK is added to f_flags of the read and
write files. This may happen concurrently if e.g. mounting process
modifies the fd in another thread.
Mark the plain read-modify-writes as intentional data-races, with the
assumption that the result of executing the accesses concurrently will
always result in the same result despite the accesses themselves not
being atomic.
Reported-by: syzbot+e441aeeb422763cc5511@syzkaller.appspotmail.com
Signed-off-by: Marco Elver <elver@google.com>
Link: https://lore.kernel.org/r/ZO38mqkS0TYUlpFp@elver.google.com
Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
Message-ID: <20231025103445.1248103-1-asmadeus@codewreck.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/9p/trans_fd.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index e070a0b8e5ca3..63f4d2067059e 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -823,14 +823,21 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd)
goto out_free_ts;
if (!(ts->rd->f_mode & FMODE_READ))
goto out_put_rd;
- /* prevent workers from hanging on IO when fd is a pipe */
- ts->rd->f_flags |= O_NONBLOCK;
+ /* Prevent workers from hanging on IO when fd is a pipe.
+ * It's technically possible for userspace or concurrent mounts to
+ * modify this flag concurrently, which will likely result in a
+ * broken filesystem. However, just having bad flags here should
+ * not crash the kernel or cause any other sort of bug, so mark this
+ * particular data race as intentional so that tooling (like KCSAN)
+ * can allow it and detect further problems.
+ */
+ data_race(ts->rd->f_flags |= O_NONBLOCK);
ts->wr = fget(wfd);
if (!ts->wr)
goto out_put_rd;
if (!(ts->wr->f_mode & FMODE_WRITE))
goto out_put_wr;
- ts->wr->f_flags |= O_NONBLOCK;
+ data_race(ts->wr->f_flags |= O_NONBLOCK);
client->trans = ts;
client->status = Connected;
--
2.42.0
^ permalink raw reply related [flat|nested] 5+ messages in thread