6.1.17-rc1 review
Subsystems (2)
Greg Kroah-Hartman
maintainerPATCH 157/200 USB: ene_usb6250: Allocate enough memory for full object
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit ce33e64c1788912976b61314b56935abd4bc97ef ]
The allocation of PageBuffer is 512 bytes in size, but the dereferencing of struct ms_bootblock_idi (also size 512) happens at a calculated offset within the allocation, which means the object could potentially extend beyond the end of the allocation. Avoid this case by just allocating enough space to catch any accesses beyond the end. Seen with GCC 13:
../drivers/usb/storage/ene_ub6250.c: In function 'ms_lib_process_bootblock':../drivers/usb/storage/ene_ub6250.c:1050:44: warning: array subscript 'struct ms_bootblock_idi[0]' is partly outside array bounds of 'unsigned char[512]' [-Warray-bounds=]
1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
| ^~../include/uapi/linux/byteorder/little_endian.h:37:51: note: in definition of macro '__le16_to_cpu'
37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
| ^../drivers/usb/storage/ene_ub6250.c:1050:29: note: in expansion of macro 'le16_to_cpu'
1050 | if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
| ^~~~~~~~~~~
In file included from ../drivers/usb/storage/ene_ub6250.c:5:
In function 'kmalloc',
inlined from 'ms_lib_process_bootblock' at ../drivers/usb/storage/ene_ub6250.c:942:15:
../include/linux/slab.h:580:24: note: at offset [256, 512] into object of size 512 allocated by 'kmalloc_trace'
580 | return kmalloc_trace(
| ^~~~~~~~~~~~~~
581 | kmalloc_caches[kmalloc_type(flags)][index],
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
582 | flags, size);
| ~~~~~~~~~~~~--- drivers/usb/storage/ene_ub6250.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/ene_ub6250.c +1 -1
@@ -939,7 +939,7 @@ static int ms_lib_process_bootblock(struct us_data *us, u16 PhyBlock, u8 *PageDastruct ms_lib_type_extdat ExtraData;struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; - PageBuffer =kmalloc (MS_BYTES_PER_PAGE ,GFP_KERNEL ); + PageBuffer =kzalloc (MS_BYTES_PER_PAGE *2 ,GFP_KERNEL );if (PageBuffer ==NULL )return (u32)-1 ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 158/200 usb: uvc: Enumerate valid values for color matching
In reply to Greg Kroah-HartmanFrom: Daniel Scally <[email protected]>
[ Upstream commit e16cab9c1596e251761d2bfb5e1467950d616963 ]
The color matching descriptors defined in the UVC Specification contain 3 fields with discrete numeric values representing particular settings. Enumerate those values so that later code setting them can be more readable.
--- include/uapi/linux/usb/video.h | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+)
include/uapi/linux/usb/video.h +30 -0
@@ -179,6 +179,36 @@#define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)#define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4) +/* 3.9.2.6 Color Matching Descriptor Values */ +enum uvc_color_primaries_values { +UVC_COLOR_PRIMARIES_UNSPECIFIED , +UVC_COLOR_PRIMARIES_BT_709_SRGB , +UVC_COLOR_PRIMARIES_BT_470_2_M , +UVC_COLOR_PRIMARIES_BT_470_2_B_G , +UVC_COLOR_PRIMARIES_SMPTE_170M , +UVC_COLOR_PRIMARIES_SMPTE_240M , +}; + +enum uvc_transfer_characteristics_values { +UVC_TRANSFER_CHARACTERISTICS_UNSPECIFIED , +UVC_TRANSFER_CHARACTERISTICS_BT_709 , +UVC_TRANSFER_CHARACTERISTICS_BT_470_2_M , +UVC_TRANSFER_CHARACTERISTICS_BT_470_2_B_G , +UVC_TRANSFER_CHARACTERISTICS_SMPTE_170M , +UVC_TRANSFER_CHARACTERISTICS_SMPTE_240M , +UVC_TRANSFER_CHARACTERISTICS_LINEAR , +UVC_TRANSFER_CHARACTERISTICS_SRGB , +}; + +enum uvc_matrix_coefficients { +UVC_MATRIX_COEFFICIENTS_UNSPECIFIED , +UVC_MATRIX_COEFFICIENTS_BT_709 , +UVC_MATRIX_COEFFICIENTS_FCC , +UVC_MATRIX_COEFFICIENTS_BT_470_2_B_G , +UVC_MATRIX_COEFFICIENTS_SMPTE_170M , +UVC_MATRIX_COEFFICIENTS_SMPTE_240M , +}; +/* ------------------------------------------------------------------------ * UVC structures */
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 159/200 usb: gadget: uvc: Make bSourceID read/write
In reply to Greg Kroah-HartmanFrom: Daniel Scally <[email protected]>
[ Upstream commit b3c839bd8a07d303bc59a900d55dd35c7826562c ]
At the moment, the UVC function graph is hardcoded IT -> PU -> OT. To add XU support we need the ability to insert the XU descriptors into the chain. To facilitate that, make the output terminal's bSourceID attribute writeable so that we can configure its source.
--- .../ABI/testing/configfs-usb-gadget-uvc | 2 +- drivers/usb/gadget/function/uvc_configfs.c | 59 ++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-)
Documentation/ABI/testing/configfs-usb-gadget-uvc +1 -1
@@ -52,7 +52,7 @@ Date: Dec 2014 KernelVersion: 4.0 Description: Default output terminal descriptors - All attributes read only: + All attributes read only except bSourceID: ============== ============================================= iTerminal index of string descriptor
drivers/usb/gadget/function/uvc_configfs.c +58 -1
69 lines not on this page · raw message
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 160/200 PCI: Align extra resources for hotplug bridges properly
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit 08f0a15ee8adb4846b08ca5d5c175fbf0f652bc9 ]
After division the extra resource space per hotplug bridge may not be aligned according to the window alignment, so align it before passing it down for further distribution.
--- drivers/pci/setup-bus.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
drivers/pci/setup-bus.c +19 -6
@@ -1891,6 +1891,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,* resource space between hotplug bridges. */ for_each_pci_bridge (dev, bus) { +struct resource *res;struct pci_bus *b; b = dev->subordinate;
@@ -1902,16 +1903,28 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,* hotplug-capable downstream ports taking alignment into * account. */ - io.end = io.start + io_per_hp -1 ; - mmio.end = mmio.start + mmio_per_hp -1 ; - mmio_pref.end = mmio_pref.start + mmio_pref_per_hp -1 ; + res = &dev->resource[PCI_BRIDGE_IO_WINDOW ]; + align =pci_resource_alignment (dev, res); + io.end = align ? io.start +ALIGN_DOWN (io_per_hp, align) -1 + : io.start + io_per_hp -1 ; + + res = &dev->resource[PCI_BRIDGE_MEM_WINDOW ]; + align =pci_resource_alignment (dev, res); + mmio.end = align ? mmio.start +ALIGN_DOWN (mmio_per_hp, align) -1 + : mmio.start + mmio_per_hp -1 ; + + res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW ]; + align =pci_resource_alignment (dev, res); + mmio_pref.end = align ? mmio_pref.start + +ALIGN_DOWN (mmio_pref_per_hp, align) -1 + : mmio_pref.start + mmio_pref_per_hp -1 ;pci_bus_distribute_available_resources (b, add_list, io, mmio, mmio_pref); - io.start += io_per_hp; - mmio.start += mmio_per_hp; - mmio_pref.start += mmio_pref_per_hp; + io.start += io.end +1 ; + mmio.start += mmio.end +1 ; + mmio_pref.start += mmio_pref.end +1 ; } }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 161/200 PCI: Take other bus devices into account when distributing resources
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit 9db0b9b6a14249ef65a5f1e5e3b37762af96f425 ]
A PCI bridge may reside on a bus with other devices as well. The resource distribution code does not take this into account and therefore it expands the bridge resource windows too much, not leaving space for the other devices (or functions of a multifunction device). This leads to an issue that Jonathan reported when running QEMU with the following topology (QEMU parameters):
-device pcie-root-port,port=0,id=root_port13,chassis=0,slot=2 \ -device x3130-upstream,id=sw1,bus=root_port13,multifunction=on \ -device e1000,bus=root_port13,addr=0.1 \ -device xio3130-downstream,id=fun1,bus=sw1,chassis=0,slot=3 \ -device e1000,bus=fun1
The first e1000 NIC here is another function in the switch upstream port. This leads to following errors:
pci 0000:00:04.0: bridge window [mem 0x10200000-0x103fffff] to [bus 02-04] pci 0000:02:00.0: bridge window [mem 0x10200000-0x103fffff] to [bus 03-04] pci 0000:02:00.1: BAR 0: failed to assign [mem size 0x00020000] e1000 0000:02:00.1: can't ioremap BAR 0: [??? 0x00000000 flags 0x0]
Fix this by taking into account bridge windows, device BARs and SR-IOV PF BARs on the bus (PF BARs include space for VF BARS so only account PF BARs), including the ones belonging to bridges themselves if it has any.
--- drivers/pci/setup-bus.c | 176 ++++++++++++++++++++++++---------------- 1 file changed, 106 insertions(+), 70 deletions(-)
drivers/pci/setup-bus.c +106 -70
@@ -1765,12 +1765,67 @@ static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res, add_size = size - new_size;pci_dbg (bridge,"bridge window %pR shrunken by %pa\n" , res, &add_size); + }else { +return ; } res->end = res->start + new_size -1 ;remove_from_list (add_list, res); } +static void remove_dev_resource (struct resource *avail,struct pci_dev *dev, +struct resource *res) +{ +resource_size_t size, align, tmp; + + size =resource_size (res); +if (!size) +return ; + + align =pci_resource_alignment (dev, res); + align = align ?ALIGN (avail->start, align) - avail->start :0 ; + tmp = align + size; + avail->start =min (avail->start + tmp, avail->end +1 ); +} + +static void remove_dev_resources (struct pci_dev *dev,struct resource *io, +struct resource *mmio, +struct resource *mmio_pref) +{ +int i; + +for (i =0 ; i <PCI_NUM_RESOURCES ; i++) { +struct resource *res = &dev->resource[i]; + +if (resource_type (res) ==IORESOURCE_IO ) { +remove_dev_resource (io, dev, res); + }else if (resource_type (res) ==IORESOURCE_MEM ) { + +/* +* Make sure prefetchable memory is reduced from +* the correct resource. Specifically we put 32-bit +* prefetchable memory in non-prefetchable window +* if there is an 64-bit pretchable window. +* +* See comments in __pci_bus_size_bridges() for +* more information. +*/ +if ((res->flags &IORESOURCE_PREFETCH ) && + ((res->flags &IORESOURCE_MEM_64 ) == + (mmio_pref->flags &IORESOURCE_MEM_64 ))) +remove_dev_resource (mmio_pref, dev, res); +else +remove_dev_resource (mmio, dev, res); + } + } +} + +/* +* io, mmio and mmio_pref contain the total amount of bridge window space +* available. This includes the minimal space needed to cover all the +* existing devices on the bus and the possible extra space that can be +* shared with the bridges. +*/ static void pci_bus_distribute_available_resources(struct pci_bus *bus, struct list_head *add_list, struct resource io,
@@ -1780,7 +1835,7 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus,unsigned int normal_bridges =0 , hotplug_bridges =0 ;struct resource *io_res, *mmio_res, *mmio_pref_res;struct pci_dev *dev, *bridge = bus->self; -resource_size_t io_per_hp, mmio_per_hp, mmio_pref_per_hp, align; +resource_size_t io_per_b, mmio_per_b, mmio_pref_per_b, align; io_res = &bridge->resource[PCI_BRIDGE_IO_WINDOW ]; mmio_res = &bridge->resource[PCI_BRIDGE_MEM_WINDOW ];
@@ -1824,100 +1879,81 @@ static void pci_bus_distribute_available_resources(struct pci_bus *bus, normal_bridges++; } -/* -* There is only one bridge on the bus so it gets all available -* resources which it can then distribute to the possible hotplug -* bridges below. -*/ -if (hotplug_bridges + normal_bridges ==1 ) { - dev = list_first_entry(&bus->devices, struct pci_dev, bus_list); -if (dev->subordinate) -pci_bus_distribute_available_resources (dev->subordinate, - add_list, io, mmio, mmio_pref); -return ; - } - -if (hotplug_bridges ==0 ) +if (!(hotplug_bridges + normal_bridges))return ;/* -* Calculate the total amount of extra resource space we can -* pass to bridges below this one. This is basically the -* extra space reduced by the minimal required space for the -* non-hotplug bridges. +* Calculate the amount of space we can forward from "bus" to any +* downstream buses, i.e., the space left over after assigning the +* BARs and windows on "bus". */ -for_each_pci_bridge (dev, bus) { -resource_size_t used_size; -struct resource *res; - -if (dev->is_hotplug_bridge) -continue ; - -/* -* Reduce the available resource space by what the -* bridge and devices below it occupy. -*/ - res = &dev->resource[PCI_BRIDGE_IO_WINDOW ]; - align =pci_resource_alignment (dev, res); - align = align ?ALIGN (io.start, align) - io.start :0 ; - used_size = align +resource_size (res); -if (!res->parent) - io.start =min (io.start + used_size, io.end +1 ); - - res = &dev->resource[PCI_BRIDGE_MEM_WINDOW ]; - align =pci_resource_alignment (dev, res); - align = align ?ALIGN (mmio.start, align) - mmio.start :0 ; - used_size = align +resource_size (res); -if (!res->parent) - mmio.start =min (mmio.start + used_size, mmio.end +1 ); - - res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW ]; - align =pci_resource_alignment (dev, res); - align = align ?ALIGN (mmio_pref.start, align) - - mmio_pref.start :0 ; - used_size = align +resource_size (res); -if (!res->parent) - mmio_pref.start =min (mmio_pref.start + used_size, - mmio_pref.end +1 ); +list_for_each_entry (dev, &bus->devices, bus_list) { +if (!dev->is_virtfn) +remove_dev_resources (dev, &io, &mmio, &mmio_pref); } - io_per_hp =div64_ul (resource_size (&io), hotplug_bridges); - mmio_per_hp =div64_ul (resource_size (&mmio), hotplug_bridges); - mmio_pref_per_hp =div64_ul (resource_size (&mmio_pref), - hotplug_bridges); -/* -* Go over devices on this bus and distribute the remaining -* resource space between hotplug bridges. +* If there is at least one hotplug bridge on this bus it gets all +* the extra resource space that was left after the reductions +* above. +* +* If there are no hotplug bridges the extra resource space is +* split between non-hotplug bridges. This is to allow possible +* hotplug bridges below them to get the extra space as well. */ +if (hotplug_bridges) { + io_per_b =div64_ul (resource_size (&io), hotplug_bridges); + mmio_per_b =div64_ul (resource_size (&mmio), hotplug_bridges); + mmio_pref_per_b =div64_ul (resource_size (&mmio_pref), + hotplug_bridges); + }else { + io_per_b =div64_ul (resource_size (&io), normal_bridges); + mmio_per_b =div64_ul (resource_size (&mmio), normal_bridges); + mmio_pref_per_b =div64_ul (resource_size (&mmio_pref), + normal_bridges); + } +for_each_pci_bridge (dev, bus) {struct resource *res;struct pci_bus *b; b = dev->subordinate; -if (!b || !dev->is_hotplug_bridge) +if (!b)continue ; +if (hotplug_bridges && !dev->is_hotplug_bridge) +continue ; + + res = &dev->resource[PCI_BRIDGE_IO_WINDOW ];/* -* Distribute available extra resources equally between -* hotplug-capable downstream ports taking alignment into -* account. +* Make sure the split resource space is properly aligned +* for bridge windows (align it down to avoid going above +* what is available). */ - res = &dev->resource[PCI_BRIDGE_IO_WINDOW ]; align =pci_resource_alignment (dev, res); - io.end = align ? io.start +ALIGN_DOWN (io_per_hp, align) -1 - : io.start + io_per_hp -1 ; + io.end = align ? io.start +ALIGN_DOWN (io_per_b, align) -1 + : io.start + io_per_b -1 ; + +/* +* The x_per_b holds the extra resource space that can be +* added for each bridge but there is the minimal already +* reserved as well so adjust x.start down accordingly to +* cover the whole space. +*/ + io.start -=resource_size (res); res = &dev->resource[PCI_BRIDGE_MEM_WINDOW ]; align =pci_resource_alignment (dev, res); - mmio.end = align ? mmio.start +ALIGN_DOWN (mmio_per_hp, align) -1 - : mmio.start + mmio_per_hp -1 ; + mmio.end = align ? mmio.start +ALIGN_DOWN (mmio_per_b, align) -1 + : mmio.start + mmio_per_b -1 ; + mmio.start -=resource_size (res); res = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW ]; align =pci_resource_alignment (dev, res); mmio_pref.end = align ? mmio_pref.start + -ALIGN_DOWN (mmio_pref_per_hp, align) -1 - : mmio_pref.start + mmio_pref_per_hp -1 ; +ALIGN_DOWN (mmio_pref_per_b, align) -1 + : mmio_pref.start + mmio_pref_per_b -1 ; + mmio_pref.start -=resource_size (res);pci_bus_distribute_available_resources (b, add_list, io, mmio, mmio_pref);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 162/200 PCI: Distribute available resources for root buses, too
In reply to Greg Kroah-HartmanFrom: Mika Westerberg <[email protected]>
[ Upstream commit 7180c1d08639f28e63110ad35815f7a1785b8a19 ]
Previously we distributed spare resources only upon hot-add, so if the initial root bus scan found devices that had not been fully configured by the BIOS, we allocated only enough resources to cover what was then present. If some of those devices were hotplug bridges, we did not leave any additional resource space for future expansion.
Distribute the available resources for root buses, too, to make this work the same way as the normal hotplug case.
A previous commit to do this was reverted due to a regression reported by Jonathan Cameron:
e96e27fc6f79 ("PCI: Distribute available resources for root buses, too") 5632e2beaf9d ("Revert "PCI: Distribute available resources for root buses, too"")
This commit changes pci_bridge_resources_not_assigned() to work with bridges that do not have all the resource windows programmed by the boot firmware (previously we expected all I/O, memory and prefetchable memory were programmed).
--- drivers/pci/setup-bus.c | 57 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-)
drivers/pci/setup-bus.c +56 -1
@@ -1770,7 +1770,10 @@ static void adjust_bridge_window(struct pci_dev *bridge, struct resource *res, } res->end = res->start + new_size -1 ; -remove_from_list (add_list, res); + +/* If the resource is part of the add_list, remove it now */ +if (add_list) +remove_from_list (add_list, res); } static void remove_dev_resource(struct resource *avail, struct pci_dev *dev,
@@ -1972,6 +1975,8 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge,if (!bridge->is_hotplug_bridge)return ; +pci_dbg (bridge,"distributing available resources\n" ); +/* Take the initial extra resources from the hotplug port */ available_io = bridge->resource[PCI_BRIDGE_IO_WINDOW ]; available_mmio = bridge->resource[PCI_BRIDGE_MEM_WINDOW ];
@@ -1983,6 +1988,54 @@ static void pci_bridge_distribute_available_resources(struct pci_dev *bridge, available_mmio_pref); } +static bool pci_bridge_resources_not_assigned (struct pci_dev *dev) +{ +const struct resource *r; + +/* +* If the child device's resources are not yet assigned it means we +* are configuring them (not the boot firmware), so we should be +* able to extend the upstream bridge resources in the same way we +* do with the normal hotplug case. +*/ + r = &dev->resource[PCI_BRIDGE_IO_WINDOW ]; +if (r->flags && !(r->flags &IORESOURCE_STARTALIGN )) +return false; + r = &dev->resource[PCI_BRIDGE_MEM_WINDOW ]; +if (r->flags && !(r->flags &IORESOURCE_STARTALIGN )) +return false; + r = &dev->resource[PCI_BRIDGE_PREF_MEM_WINDOW ]; +if (r->flags && !(r->flags &IORESOURCE_STARTALIGN )) +return false; + +return true; +} + +static void +pci_root_bus_distribute_available_resources (struct pci_bus *bus, +struct list_head *add_list) +{ +struct pci_dev *dev, *bridge = bus->self; + +for_each_pci_bridge (dev, bus) { +struct pci_bus *b; + + b = dev->subordinate; +if (!b) +continue ; + +/* +* Need to check "bridge" here too because it is NULL +* in case of root bus. +*/ +if (bridge &&pci_bridge_resources_not_assigned (dev)) +pci_bridge_distribute_available_resources (bridge, + add_list); +else +pci_root_bus_distribute_available_resources (b, add_list); + } +} +/* * First try will not touch PCI bridge res. * Second and later try will clear small leaf bridge res.
@@ -2022,6 +2075,8 @@ void pci_assign_unassigned_root_bus_resources(struct pci_bus *bus)*/ __pci_bus_size_bridges (bus, add_list); +pci_root_bus_distribute_available_resources (bus, add_list); +/* Depth last, allocate resources and update the hardware. */ __pci_bus_assign_resources (bus, add_list, &fail_head);if (add_list)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 163/200 tty: pcn_uart: fix memory leak with using debugfs_lookup()
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
[ Upstream commit 04a189c720aa2b6091442113ce9b9bc93552dff8 ]
When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once.
--- drivers/tty/serial/pch_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/pch_uart.c +1 -1
@@ -1779,7 +1779,7 @@ static void pch_uart_exit_port(struct eg20t_port *priv)char name[32 ];snprintf (name,sizeof (name),"uart%d_regs" , priv->port.line); -debugfs_remove (debugfs_lookup (name,NULL )); +debugfs_lookup_and_remove (name,NULL );uart_remove_one_port (&pch_uart_driver, &priv->port);free_page ((unsigned long )priv->rxbuf.buf); }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 164/200 misc: vmw_balloon: fix memory leak with using debugfs_lookup()
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
[ Upstream commit 209cdbd07cfaa4b7385bad4eeb47e5ec1887d33d ]
When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once.
--- drivers/misc/vmw_balloon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/misc/vmw_balloon.c +1 -1
@@ -1709,7 +1709,7 @@ static void __init vmballoon_debugfs_init(struct vmballoon *b) static void __exit vmballoon_debugfs_exit(struct vmballoon *b) {static_key_disable (&balloon_stat_enabled.key); -debugfs_remove (debugfs_lookup ("vmmemctl" ,NULL )); +debugfs_lookup_and_remove ("vmmemctl" ,NULL );kfree (b->stats); b->stats =NULL ; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 165/200 drivers: base: component: fix memory leak with using debugfs_lookup()
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
[ Upstream commit 8deb87b1e810dd558371e88ffd44339fbef27870 ]
When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once.
--- drivers/base/component.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/component.c +1 -1
@@ -125,7 +125,7 @@ static void component_debugfs_add(struct aggregate_device *m)static void component_debugfs_del (struct aggregate_device *m) { -debugfs_remove (debugfs_lookup (dev_name (m->parent), component_debugfs_dir)); +debugfs_lookup_and_remove (dev_name (m->parent), component_debugfs_dir); }#else
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 166/200 drivers: base: dd: fix memory leak with using debugfs_lookup()
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
[ Upstream commit 36c893d3a759ae7c91ee7d4871ebfc7504f08c40 ]
When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once.
--- drivers/base/dd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/base/dd.c +1 -1
@@ -372,7 +372,7 @@ late_initcall(deferred_probe_initcall); static void __exit deferred_probe_exit(void) { -debugfs_remove_recursive (debugfs_lookup ("devices_deferred" ,NULL )); +debugfs_lookup_and_remove ("devices_deferred" ,NULL ); }__exitcall (deferred_probe_exit);
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 167/200 kernel/fail_function: fix memory leak with using debugfs_lookup()
In reply to Greg Kroah-HartmanFrom: Greg Kroah-Hartman <[email protected]>
[ Upstream commit 2bb3669f576559db273efe49e0e69f82450efbca ]
When calling debugfs_lookup() the result must have dput() called on it, otherwise the memory will leak over time. To make things simpler, just call debugfs_lookup_and_remove() instead which handles all of the logic at once.
--- kernel/fail_function.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
kernel/fail_function.c +1 -4
@@ -163,10 +163,7 @@ static void fei_debugfs_add_attr(struct fei_attr *attr)static void fei_debugfs_remove_attr (struct fei_attr *attr) { -struct dentry *dir; - - dir =debugfs_lookup (attr->kp.symbol_name, fei_debugfs_dir); -debugfs_remove_recursive (dir); +debugfs_lookup_and_remove (attr->kp.symbol_name, fei_debugfs_dir); }static int fei_kprobe_handler (struct kprobe *kp,struct pt_regs *regs)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 168/200 PCI: loongson: Add more devices that need MRRS quirk
In reply to Greg Kroah-HartmanFrom: Huacai Chen <[email protected]>
[ Upstream commit c768f8c5f40fcdc6f058cc2f02592163d6c6716c ]
Loongson-2K SOC and LS7A2000 chipset add new PCI IDs that need MRRS quirk. Add them.
--- drivers/pci/controller/pci-loongson.c | 33 +++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-)
drivers/pci/controller/pci-loongson.c +24 -9
@@ -15,9 +15,14 @@#include "../pci.h" /* Device IDs */ -#define DEV_PCIE_PORT_0 0x7a09 -#define DEV_PCIE_PORT_1 0x7a19 -#define DEV_PCIE_PORT_2 0x7a29 +#define DEV_LS2K_PCIE_PORT0 0x1a05 +#define DEV_LS7A_PCIE_PORT0 0x7a09 +#define DEV_LS7A_PCIE_PORT1 0x7a19 +#define DEV_LS7A_PCIE_PORT2 0x7a29 +#define DEV_LS7A_PCIE_PORT3 0x7a39 +#define DEV_LS7A_PCIE_PORT4 0x7a49 +#define DEV_LS7A_PCIE_PORT5 0x7a59 +#define DEV_LS7A_PCIE_PORT6 0x7a69#define DEV_LS2K_APB 0x7a02#define DEV_LS7A_GMAC 0x7a03
@@ -53,11 +58,11 @@ static void bridge_class_quirk(struct pci_dev *dev) dev->class =PCI_CLASS_BRIDGE_PCI_NORMAL ; }DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , -DEV_PCIE_PORT_0 , bridge_class_quirk); +DEV_LS7A_PCIE_PORT0 , bridge_class_quirk);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , -DEV_PCIE_PORT_1 , bridge_class_quirk); +DEV_LS7A_PCIE_PORT1 , bridge_class_quirk);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , -DEV_PCIE_PORT_2 , bridge_class_quirk); +DEV_LS7A_PCIE_PORT2 , bridge_class_quirk);static void system_bus_quirk (struct pci_dev *pdev) {
@@ -87,11 +92,21 @@ static void loongson_mrrs_quirk(struct pci_dev *pdev) bridge->no_inc_mrrs =1 ; }DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , -DEV_PCIE_PORT_0 , loongson_mrrs_quirk); +DEV_LS2K_PCIE_PORT0 , loongson_mrrs_quirk);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , -DEV_PCIE_PORT_1 , loongson_mrrs_quirk); +DEV_LS7A_PCIE_PORT0 , loongson_mrrs_quirk);DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , -DEV_PCIE_PORT_2 , loongson_mrrs_quirk); +DEV_LS7A_PCIE_PORT1 , loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , +DEV_LS7A_PCIE_PORT2 , loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , +DEV_LS7A_PCIE_PORT3 , loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , +DEV_LS7A_PCIE_PORT4 , loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , +DEV_LS7A_PCIE_PORT5 , loongson_mrrs_quirk); +DECLARE_PCI_FIXUP_EARLY (PCI_VENDOR_ID_LOONGSON , +DEV_LS7A_PCIE_PORT6 , loongson_mrrs_quirk);static void loongson_pci_pin_quirk (struct pci_dev *pdev) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 169/200 PCI: Add ACS quirk for Wangxun NICs
In reply to Greg Kroah-HartmanFrom: Mengyuan Lou <[email protected]>
[ Upstream commit a2b9b123ccac913e9f9b80337d687a2fe786a634 ]
Wangxun has verified there is no peer-to-peer between functions for the below selection of SFxxx, RP1000 and RP2000 NICS. They may be multi-function devices, but the hardware does not advertise ACS capability.
Add an ACS quirk for these devices so the functions can be in independent IOMMU groups.
--- drivers/pci/quirks.c | 22 ++++++++++++++++++++++ include/linux/pci_ids.h | 2 ++ 2 files changed, 24 insertions(+)
drivers/pci/quirks.c +22 -0
@@ -4835,6 +4835,26 @@ static int pci_quirk_brcm_acs(struct pci_dev *dev, u16 acs_flags) PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF); } +/* +* Wangxun 10G/1G NICs have no ACS capability, and on multi-function +* devices, peer-to-peer transactions are not be used between the functions. +* So add an ACS quirk for below devices to isolate functions. +* SFxxx 1G NICs(em). +* RP1000/RP2000 10G NICs(sp). +*/ +static int pci_quirk_wangxun_nic_acs (struct pci_dev *dev,u16 acs_flags) +{ +switch (dev->device) { + case 0x0100 ... 0x010F: +case 0x1001 : +case 0x2001 : +return pci_acs_ctrl_enabled (acs_flags, +PCI_ACS_SV |PCI_ACS_RR |PCI_ACS_CR |PCI_ACS_UF ); + } + +return false; +} + static const struct pci_dev_acs_enabled { u16 vendor; u16 device;
@@ -4980,6 +5000,8 @@ static const struct pci_dev_acs_enabled { { PCI_VENDOR_ID_NXP, 0x8d9b, pci_quirk_nxp_rp_acs },/* Zhaoxin Root/Downstream Ports */ { PCI_VENDOR_ID_ZHAOXIN, PCI_ANY_ID, pci_quirk_zhaoxin_pcie_ports_acs }, +/* Wangxun nics */ + { PCI_VENDOR_ID_WANGXUN, PCI_ANY_ID, pci_quirk_wangxun_nic_acs }, { 0 } };
include/linux/pci_ids.h +2 -0
@@ -3012,6 +3012,8 @@#define PCI_DEVICE_ID_INTEL_VMD_9A0B 0x9a0b#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 +#define PCI_VENDOR_ID_WANGXUN 0x8088 +#define PCI_VENDOR_ID_SCALEMP 0x8686#define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 170/200 PCI: pciehp: Add Qualcomm quirk for Command Completed erratum
In reply to Greg Kroah-HartmanFrom: Manivannan Sadhasivam <[email protected]>
[ Upstream commit 82b34b0800af8c9fc9988c290cdc813e0ca0df31 ]
The Qualcomm PCI bridge device (Device ID 0x010e) found in chipsets such as SC8280XP used in Lenovo Thinkpad X13s, does not set the Command Completed bit unless writes to the Slot Command register change "Control" bits.
This results in timeouts like below during boot and resume from suspend:
pcieport 0002:00:00.0: pciehp: Timeout on hotplug command 0x03c0 (issued 2020 msec ago)
...
pcieport 0002:00:00.0: pciehp: Timeout on hotplug command 0x13f1 (issued 107724 msec ago)
Add the device to the Command Completed quirk to mark commands "completed" immediately unless they change the "Control" bits.
--- drivers/pci/hotplug/pciehp_hpc.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/pci/hotplug/pciehp_hpc.c +2 -0
@@ -1086,6 +1086,8 @@ static void quirk_cmd_compl(struct pci_dev *pdev) }DECLARE_PCI_FIXUP_CLASS_EARLY (PCI_VENDOR_ID_INTEL ,PCI_ANY_ID ,PCI_CLASS_BRIDGE_PCI ,8 , quirk_cmd_compl); +DECLARE_PCI_FIXUP_CLASS_EARLY (PCI_VENDOR_ID_QCOM ,0x010e , +PCI_CLASS_BRIDGE_PCI ,8 , quirk_cmd_compl);DECLARE_PCI_FIXUP_CLASS_EARLY (PCI_VENDOR_ID_QCOM ,0x0110 ,PCI_CLASS_BRIDGE_PCI ,8 , quirk_cmd_compl); DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_QCOM, 0x0400,
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 171/200 phy: rockchip-typec: Fix unsigned comparison with less than zero
In reply to Greg Kroah-HartmanFrom: Jiapeng Chong <[email protected]>
[ Upstream commit f765c59c5a72546a2d74a92ae5d0eb0329d8e247 ]
The dp and ufp are defined as bool type, the return value type of function extcon_get_state should be int, so the type of dp and ufp are modified to int.
./drivers/phy/rockchip/phy-rockchip-typec.c:827:12-14: WARNING: Unsigned expression compared with zero: dp > 0.
--- drivers/phy/rockchip/phy-rockchip-typec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/phy/rockchip/phy-rockchip-typec.c +1 -2
@@ -808,9 +808,8 @@ static int tcphy_get_mode(struct rockchip_typec_phy *tcphy)struct extcon_dev *edev = tcphy->extcon;union extcon_property_value property;unsigned int id; -bool ufp, dp;u8 mode; -int ret; +int ret, ufp, dp;if (!edev)return MODE_DFP_USB ;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 172/200 RDMA/cma: Distinguish between sockaddr_in and sockaddr_in6 by size
In reply to Greg Kroah-HartmanFrom: Kees Cook <[email protected]>
[ Upstream commit 876e480da2f74715fc70e37723e77ca16a631e35 ]
Clang can do some aggressive inlining, which provides it with greater visibility into the sizes of various objects that are passed into helpers. Specifically, compare_netdev_and_ip() can see through the type given to the "sa" argument, which means it can generate code for "struct sockaddr_in" that would have been passed to ipv6_addr_cmp() (that expects to operate on the larger "struct sockaddr_in6"), which would result in a compile-time buffer overflow condition detected by memcmp(). Logically, this state isn't reachable due to the sa_family assignment two callers above and the check in compare_netdev_and_ip(). Instead, provide a compile-time check on sizes so the size-mismatched code will be elided when inlining. Avoids the following warning from Clang:
../include/linux/fortify-string.h:652:4: error: call to '__read_overflow' declared with 'error' attribute: detected read beyond size of object (1st parameter)
__read_overflow();
^note: In function 'cma_netevent_callback'
note: which inlined function 'node_from_ndev_ip'
1 error generated.
When the underlying object size is not known (e.g. with GCC and older Clang), the result of __builtin_object_size() is SIZE_MAX, which will also compile away, leaving the code as it was originally.
--- drivers/infiniband/core/cma.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/infiniband/core/cma.c +12 -5
@@ -479,13 +479,20 @@ static int compare_netdev_and_ip(int ifindex_a, struct sockaddr *sa,if (sa->sa_family != sb->sa_family)return sa->sa_family - sb->sa_family; -if (sa->sa_family ==AF_INET ) -return memcmp ((char *)&((struct sockaddr_in *)sa)->sin_addr, - (char *)&((struct sockaddr_in *)sb)->sin_addr, +if (sa->sa_family ==AF_INET && +__builtin_object_size (sa,0 ) >=sizeof (struct sockaddr_in )) { +return memcmp (&((struct sockaddr_in *)sa)->sin_addr, + &((struct sockaddr_in *)sb)->sin_addr,sizeof (((struct sockaddr_in *)sa)->sin_addr)); + } + +if (sa->sa_family ==AF_INET6 && +__builtin_object_size (sa,0 ) >=sizeof (struct sockaddr_in6 )) { +return ipv6_addr_cmp (&((struct sockaddr_in6 *)sa)->sin6_addr, + &((struct sockaddr_in6 *)sb)->sin6_addr); + } -return ipv6_addr_cmp (&((struct sockaddr_in6 *)sa)->sin6_addr, - &((struct sockaddr_in6 *)sb)->sin6_addr); +return -1 ; }static int cma_add_id_to_tree (struct rdma_id_private *node_id_priv)
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 173/200 iommu: Attach device group to old domain in error path
In reply to Greg Kroah-HartmanFrom: Vasant Hegde <[email protected]>
[ Upstream commit 2cc73c5712f97de98c38c2fafc1f288354a9f3c3 ]
iommu_attach_group() attaches all devices in a group to domain and then sets group domain (group->domain). Current code (__iommu_attach_group()) does not handle error path. This creates problem as devices to domain attachment is in inconsistent state.
Flow:
- During boot iommu attach devices to default domain
- Later some device driver (like amd/iommu_v2 or vfio) tries to attach device to new domain.
- In iommu_attach_group() path we detach device from current domain. Then it tries to attach devices to new domain.
- If it fails to attach device to new domain then device to domain link is broken.
- iommu_attach_group() returns error.
- At this stage iommu_attach_group() caller thinks, attaching device to new domain failed and devices are still attached to old domain.
- But in reality device to old domain link is broken. It will result in all sort of failures (like IO page fault) later.
To recover from this situation, we need to attach all devices back to the old domain. Also log warning if it fails attach device back to old domain.
--- drivers/iommu/iommu.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
drivers/iommu/iommu.c +15 -1
@@ -2089,8 +2089,22 @@ static int __iommu_attach_group(struct iommu_domain *domain, ret =__iommu_group_for_each_dev (group, domain, iommu_group_do_attach_device); -if (ret ==0 ) +if (ret ==0 ) { group->domain = domain; + }else { +/* +* To recover from the case when certain device within the +* group fails to attach to the new domain, we need force +* attaching all devices back to the old domain. The old +* domain is compatible for all devices in the group, +* hence the iommu driver should always return success. +*/ +struct iommu_domain *old_domain = group->domain; + + group->domain =NULL ; +WARN (__iommu_group_set_domain (group, old_domain), +"iommu driver failed to attach a compatible domain" ); + }return ret; }
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 174/200 soundwire: cadence: Remove wasted space in response_buf
In reply to Greg Kroah-HartmanFrom: Richard Fitzgerald <[email protected]>
[ Upstream commit 827c32d0df4bbe0d1c47d79f6a5eabfe9ac75216 ]
The response_buf was declared much larger (128 entries) than the number of responses that could ever be written into it. The Cadence IP is configurable up to a maximum of 32 entries, and the datasheet says that RX_FIFO_AVAIL can be 2 larger than this. So allow up to 34 responses.
Also add checking in cdns_read_response() to prevent overflowing reponse_buf if RX_FIFO_AVAIL contains an unexpectedly large number.
--- drivers/soundwire/cadence_master.c | 7 +++++++ drivers/soundwire/cadence_master.h | 13 ++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-)
drivers/soundwire/cadence_master.c +7 -0
@@ -774,8 +774,15 @@ static void cdns_read_response(struct sdw_cdns *cdns)u32 num_resp, cmd_base;int i; +/* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */ +BUILD_BUG_ON (ARRAY_SIZE (cdns->response_buf) <CDNS_MCP_CMD_LEN +2 ); + num_resp =cdns_readl (cdns,CDNS_MCP_FIFOSTAT ); num_resp &=CDNS_MCP_RX_FIFO_AVAIL ; +if (num_resp >ARRAY_SIZE (cdns->response_buf)) { +dev_warn (cdns->dev,"RX AVAIL %d too long\n" , num_resp); + num_resp =ARRAY_SIZE (cdns->response_buf); + } cmd_base =CDNS_MCP_CMD_BASE ;
drivers/soundwire/cadence_master.h +12 -1
@@ -8,6 +8,12 @@#define SDW_CADENCE_GSYNC_KHZ 4/* 4 kHz */ #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000) +/* +* The Cadence IP supports up to 32 entries in the FIFO, though implementations +* can configure the IP to have a smaller FIFO. +*/ +#define CDNS_MCP_IP_MAX_CMD_LEN 32 +/** * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance *
@@ -114,7 +120,12 @@ struct sdw_cdns {struct sdw_bus bus;unsigned int instance; -u32 response_buf[0x80 ]; +/* +* The datasheet says the RX FIFO AVAIL can be 2 entries more +* than the FIFO capacity, so allow for this. +*/ +u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN +2 ]; +struct completion tx_complete;struct sdw_defer *defer;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 175/200 soundwire: cadence: Drain the RX FIFO after an IO timeout
In reply to Greg Kroah-HartmanFrom: Richard Fitzgerald <[email protected]>
[ Upstream commit 0603a47bd3a8f439d7844b841eee1819353063e0 ]
If wait_for_completion_timeout() times-out in _cdns_xfer_msg() it is possible that something could have been written to the RX FIFO. In this case, we should drain the RX FIFO so that anything in it doesn't carry over and mess up the next transfer.
Obviously, if we got to this state something went wrong, and we don't really know the state of everything. The cleanup in this situation cannot be bullet-proof but we should attempt to avoid breaking future transaction, if only to reduce the amount of error noise when debugging the failure from a kernel log.
Note that this patch only implements the draining for blocking (non-deferred) transfers. The deferred API doesn't have any proper handling of error conditions and would need some re-design before implementing cleanup. That is a task for a separate patch...
--- drivers/soundwire/cadence_master.c | 50 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 23 deletions(-)
drivers/soundwire/cadence_master.c +27 -23
@@ -555,6 +555,29 @@ cdns_fill_msg_resp(struct sdw_cdns *cdns,return SDW_CMD_OK ; } +static void cdns_read_response (struct sdw_cdns *cdns) +{ +u32 num_resp, cmd_base; +int i; + +/* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */ +BUILD_BUG_ON (ARRAY_SIZE (cdns->response_buf) <CDNS_MCP_CMD_LEN +2 ); + + num_resp =cdns_readl (cdns,CDNS_MCP_FIFOSTAT ); + num_resp &=CDNS_MCP_RX_FIFO_AVAIL ; +if (num_resp >ARRAY_SIZE (cdns->response_buf)) { +dev_warn (cdns->dev,"RX AVAIL %d too long\n" , num_resp); + num_resp =ARRAY_SIZE (cdns->response_buf); + } + + cmd_base =CDNS_MCP_CMD_BASE ; + +for (i =0 ; i < num_resp; i++) { + cdns->response_buf[i] =cdns_readl (cdns, cmd_base); + cmd_base +=CDNS_MCP_CMD_WORD_LEN ; + } +} +static enum sdw_command_response _cdns_xfer_msg (struct sdw_cdns *cdns,struct sdw_msg *msg,int cmd,int offset,int count,bool defer)
@@ -596,6 +619,10 @@ _cdns_xfer_msg(struct sdw_cdns *cdns, struct sdw_msg *msg, int cmd,dev_err (cdns->dev,"IO transfer timed out, cmd %d device %d addr %x len %d\n" , cmd, msg->dev_num, msg->addr, msg->len); msg->len =0 ; + +/* Drain anything in the RX_FIFO */ +cdns_read_response (cdns); +return SDW_CMD_TIMEOUT ; }
@@ -769,29 +796,6 @@ EXPORT_SYMBOL(cdns_read_ping_status);* IRQ handling */ -static void cdns_read_response (struct sdw_cdns *cdns) -{ -u32 num_resp, cmd_base; -int i; - -/* RX_FIFO_AVAIL can be 2 entries more than the FIFO size */ -BUILD_BUG_ON (ARRAY_SIZE (cdns->response_buf) <CDNS_MCP_CMD_LEN +2 ); - - num_resp =cdns_readl (cdns,CDNS_MCP_FIFOSTAT ); - num_resp &=CDNS_MCP_RX_FIFO_AVAIL ; -if (num_resp >ARRAY_SIZE (cdns->response_buf)) { -dev_warn (cdns->dev,"RX AVAIL %d too long\n" , num_resp); - num_resp =ARRAY_SIZE (cdns->response_buf); - } - - cmd_base =CDNS_MCP_CMD_BASE ; - -for (i =0 ; i < num_resp; i++) { - cdns->response_buf[i] =cdns_readl (cdns, cmd_base); - cmd_base +=CDNS_MCP_CMD_WORD_LEN ; - } -} -static int cdns_update_slave_status (struct sdw_cdns *cdns,u64 slave_intstat) {
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 176/200 net: tls: avoid hanging tasks on the tx_lock
In reply to Greg Kroah-HartmanFrom: Jakub Kicinski <[email protected]>
commit f3221361dc85d4de22586ce8441ec2c67b454f5d upstream.
syzbot sent a hung task report and Eric explains that adversarial receiver may keep RWIN at 0 for a long time, so we are not guaranteed to make forward progress. Thread which took tx_lock and went to sleep may not release tx_lock for hours. Use interruptible sleep where possible and reschedule the work if it can't take the lock.
Testing: existing selftest passes
--- net/tls/tls_sw.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-)
net/tls/tls_sw.c +19 -7
@@ -941,7 +941,9 @@ int tls_sw_sendmsg(struct sock *sk, stru MSG_CMSG_COMPAT))return -EOPNOTSUPP ; -mutex_lock (&tls_ctx->tx_lock); + ret =mutex_lock_interruptible (&tls_ctx->tx_lock); +if (ret) +return ret;lock_sock (sk);if (unlikely (msg->msg_controllen)) {
@@ -1275,7 +1277,9 @@ int tls_sw_sendpage(struct sock *sk, str MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))return -EOPNOTSUPP ; -mutex_lock (&tls_ctx->tx_lock); + ret =mutex_lock_interruptible (&tls_ctx->tx_lock); +if (ret) +return ret;lock_sock (sk); ret =tls_sw_do_sendpage (sk, page, offset, size, flags);release_sock (sk);
@@ -2416,11 +2420,19 @@ static void tx_work_handler(struct work_if (!test_and_clear_bit (BIT_TX_SCHEDULED , &ctx->tx_bitmask))return ; -mutex_lock (&tls_ctx->tx_lock); -lock_sock (sk); -tls_tx_records (sk,-1 ); -release_sock (sk); -mutex_unlock (&tls_ctx->tx_lock); + +if (mutex_trylock (&tls_ctx->tx_lock)) { +lock_sock (sk); +tls_tx_records (sk,-1 ); +release_sock (sk); +mutex_unlock (&tls_ctx->tx_lock); + }else if (!test_and_set_bit (BIT_TX_SCHEDULED , &ctx->tx_bitmask)) { +/* Someone is holding the tx_lock, they will likely run Tx +* and cancel the work on their way out of the lock section. +* Schedule a long delay just in case. +*/ +schedule_delayed_work (&ctx->tx_work.work,msecs_to_jiffies (10 )); + } }static bool tls_is_tx_ready (struct tls_sw_context_tx *ctx)
Greg Kroah-Hartman
maintainerPATCH 177/200 x86/resctl: fix scheduler confusion with current
In reply to Greg Kroah-HartmanFrom: Linus Torvalds <[email protected]>
commit 7fef099702527c3b2c5234a2ea6a24411485a13a upstream.
The implementation of 'current' on x86 is very intentionally special: it is a very common thing to look up, and it uses 'this_cpu_read_stable()' to get the current thread pointer efficiently from per-cpu storage.
And the keyword in there is 'stable': the current thread pointer never changes as far as a single thread is concerned. Even if when a thread is preempted, or moved to another CPU, or even across an explicit call 'schedule()' that thread will still have the same value for 'current'.
It is, after all, the kernel base pointer to thread-local storage. That's why it's stable to begin with, but it's also why it's important enough that we have that special 'this_cpu_read_stable()' access for it.
So this is all done very intentionally to allow the compiler to treat 'current' as a value that never visibly changes, so that the compiler can do CSE and combine multiple different 'current' accesses into one.
However, there is obviously one very special situation when the currently running thread does actually change: inside the scheduler itself.
So the scheduler code paths are special, and do not have a 'current' thread at all. Instead there are _two_ threads: the previous and the next thread - typically called 'prev' and 'next' (or prev_p/next_p) internally.
So this is all actually quite straightforward and simple, and not all that complicated.
Except for when you then have special code that is run in scheduler context, that code then has to be aware that 'current' isn't really a valid thing. Did you mean 'prev'? Did you mean 'next'?
In fact, even if then look at the code, and you use 'current' after the new value has been assigned to the percpu variable, we have explicitly told the compiler that 'current' is magical and always stable. So the compiler is quite free to use an older (or newer) value of 'current', and the actual assignment to the percpu storage is not relevant even if it might look that way.
Which is exactly what happened in the resctl code, that blithely used 'current' in '__resctrl_sched_in()' when it really wanted the new process state (as implied by the name: we're scheduling 'into' that new resctl state). And clang would end up just using the old thread pointer value at least in some configurations.
This could have happened with gcc too, and purely depends on random compiler details. Clang just seems to have been more aggressive about moving the read of the per-cpu current_task pointer around.
The fix is trivial: just make the resctl code adhere to the scheduler rules of using the prev/next thread pointer explicitly, instead of using 'current' in a situation where it just wasn't valid.
That same code is then also used outside of the scheduler context (when a thread resctl state is explicitly changed), and then we will just pass in 'current' as that pointer, of course. There is no ambiguity in that case.
The fix may be trivial, but noticing and figuring out what went wrong was not. The credit for that goes to Stephane Eranian.
--- arch/x86/include/asm/resctrl.h | 12 ++++++------ arch/x86/kernel/cpu/resctrl/rdtgroup.c | 4 ++-- arch/x86/kernel/process_32.c | 2 +- arch/x86/kernel/process_64.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-)
arch/x86/include/asm/resctrl.h +6 -6
@@ -51,7 +51,7 @@ DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_* simple as possible. * Must be called with preemption disabled. */ -static void __resctrl_sched_in (void ) +static inline void __resctrl_sched_in (struct task_struct *tsk) {struct resctrl_pqr_state *state =this_cpu_ptr (&pqr_state);u32 closid = state->default_closid;
@@ -63,13 +63,13 @@ static void __resctrl_sched_in(void)* Else use the closid/rmid assigned to this cpu. */ if (static_branch_likely (&rdt_alloc_enable_key)) { - tmp =READ_ONCE (current->closid); + tmp =READ_ONCE (tsk->closid);if (tmp) closid = tmp; }if (static_branch_likely (&rdt_mon_enable_key)) { - tmp =READ_ONCE (current->rmid); + tmp =READ_ONCE (tsk->rmid);if (tmp) rmid = tmp; }
@@ -90,17 +90,17 @@ static inline unsigned int resctrl_arch_ return val * scale; } -static inline void resctrl_sched_in (void ) +static inline void resctrl_sched_in (struct task_struct *tsk) {if (static_branch_likely (&rdt_enable_key)) -__resctrl_sched_in (); +__resctrl_sched_in (tsk); }void resctrl_cpu_detect (struct cpuinfo_x86 *c);#else -static inline void resctrl_sched_in (void ) {} +static inline void resctrl_sched_in (struct task_struct *tsk) {}static inline void resctrl_cpu_detect (struct cpuinfo_x86 *c) {}#endif /* CONFIG_X86_CPU_RESCTRL */
arch/x86/kernel/cpu/resctrl/rdtgroup.c +2 -2
@@ -314,7 +314,7 @@ static void update_cpu_closid_rmid(void* executing task might have its own closid selected. Just reuse * the context switch code. */ -resctrl_sched_in (); +resctrl_sched_in (current); }/*
@@ -535,7 +535,7 @@ static void _update_task_closid_rmid(voi* Otherwise, the MSR is updated when the task is scheduled in. */ if (task == current) -resctrl_sched_in (); +resctrl_sched_in (task); }static void update_task_closid_rmid (struct task_struct *t)
arch/x86/kernel/process_32.c +1 -1
@@ -212,7 +212,7 @@ __switch_to(struct task_struct *prev_p,switch_fpu_finish ();/* Load the Intel cache allocation PQR MSR. */ -resctrl_sched_in (); +resctrl_sched_in (next_p);return prev_p; }
arch/x86/kernel/process_64.c +1 -1
@@ -656,7 +656,7 @@ __switch_to(struct task_struct *prev_p, }/* Load the Intel cache allocation PQR MSR. */ -resctrl_sched_in (); +resctrl_sched_in (next_p);return prev_p; }
Greg Kroah-Hartman
maintainerPATCH 178/200 vDPA/ifcvf: decouple hw features manipulators from the adapter
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit d59f633dd05940739b5f46f5d4403cafb91d2742 upstream.
This commit gets rid of ifcvf_adapter in hw features related functions in ifcvf_base. Then these functions are more rubust and de-coupling from the ifcvf_adapter layer. So these functions could be invoded once the device is probed, even before the adapter is allocaed.
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_base.c | 9 ++------- drivers/vdpa/ifcvf/ifcvf_base.h | 1 + drivers/vdpa/ifcvf/ifcvf_main.c | 1 + 3 files changed, 4 insertions(+), 7 deletions(-)
drivers/vdpa/ifcvf/ifcvf_base.c +2 -7
@@ -220,10 +220,8 @@ u64 ifcvf_get_features(struct ifcvf_hw *int ifcvf_verify_min_features (struct ifcvf_hw *hw,u64 features) { -struct ifcvf_adapter *ifcvf =vf_to_adapter (hw); -if (!(features &BIT_ULL (VIRTIO_F_ACCESS_PLATFORM )) && features) { -IFCVF_ERR (ifcvf->pdev,"VIRTIO_F_ACCESS_PLATFORM is not negotiated\n" ); +IFCVF_ERR (hw->pdev,"VIRTIO_F_ACCESS_PLATFORM is not negotiated\n" );return -EINVAL ; }
@@ -301,14 +299,11 @@ static void ifcvf_set_features(struct ifstatic int ifcvf_config_features (struct ifcvf_hw *hw) { -struct ifcvf_adapter *ifcvf; - - ifcvf =vf_to_adapter (hw);ifcvf_set_features (hw, hw->req_features);ifcvf_add_status (hw,VIRTIO_CONFIG_S_FEATURES_OK );if (!(ifcvf_get_status (hw) &VIRTIO_CONFIG_S_FEATURES_OK )) { -IFCVF_ERR (ifcvf->pdev,"Failed to set FEATURES_OK status\n" ); +IFCVF_ERR (hw->pdev,"Failed to set FEATURES_OK status\n" );return -EIO ; }
drivers/vdpa/ifcvf/ifcvf_base.h +1 -0
@@ -89,6 +89,7 @@ struct ifcvf_hw {u16 nr_vring;/* VIRTIO_PCI_CAP_DEVICE_CFG size */ u32 cap_dev_config_size; +struct pci_dev *pdev; };struct ifcvf_adapter {
drivers/vdpa/ifcvf/ifcvf_main.c +1 -0
@@ -842,6 +842,7 @@ static int ifcvf_probe(struct pci_dev *p vf = &adapter->vf; vf->dev_type =get_dev_type (pdev); vf->base =pcim_iomap_table (pdev); + vf->pdev = pdev; adapter->pdev = pdev; adapter->vdpa.dma_dev = &pdev->dev;
Greg Kroah-Hartman
maintainerPATCH 179/200 vDPA/ifcvf: decouple config space ops from the adapter
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit af8eb69a62b73a2ce5f91575453534ac07f06eb4 upstream.
This commit decopules the config space ops from the adapter layer, so these functions can be invoked once the device is probed.
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_base.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-)
drivers/vdpa/ifcvf/ifcvf_base.c +5 -16
@@ -10,11 +10,6 @@#include "ifcvf_base.h" -struct ifcvf_adapter *vf_to_adapter (struct ifcvf_hw *hw) -{ - return container_of(hw, struct ifcvf_adapter, vf); -} -u16 ifcvf_set_vq_vector (struct ifcvf_hw *hw,u16 qid,int vector) {struct virtio_pci_common_cfg __iomem *cfg = hw->common_cfg;
@@ -37,8 +32,6 @@ u16 ifcvf_set_config_vector(struct ifcvfstatic void __iomem *get_cap_addr (struct ifcvf_hw *hw,struct virtio_pci_cap *cap) { -struct ifcvf_adapter *ifcvf; -struct pci_dev *pdev;u32 length, offset;u8 bar;
@@ -46,17 +39,14 @@ static void __iomem *get_cap_addr(struct offset =le32_to_cpu (cap->offset); bar = cap->bar; - ifcvf=vf_to_adapter (hw); - pdev = ifcvf->pdev; -if (bar >=IFCVF_PCI_MAX_RESOURCE ) { -IFCVF_DBG (pdev, +IFCVF_DBG (hw->pdev,"Invalid bar number %u to get capabilities\n" , bar);return NULL ; } -if (offset + length >pci_resource_len (pdev, bar)) { -IFCVF_DBG (pdev, +if (offset + length >pci_resource_len (hw->pdev, bar)) { +IFCVF_DBG (hw->pdev,"offset(%u) + len(%u) overflows bar%u's capability\n" , offset, length, bar);return NULL ;
@@ -92,6 +82,7 @@ int ifcvf_init_hw(struct ifcvf_hw *hw, sIFCVF_ERR (pdev,"Failed to read PCI capability list\n" );return -EIO ; } + hw->pdev = pdev;while (pos) { ret = ifcvf_read_config_range(pdev, (u32 *)&cap,
@@ -230,13 +221,11 @@ int ifcvf_verify_min_features(struct ifcu32 ifcvf_get_config_size (struct ifcvf_hw *hw) { -struct ifcvf_adapter *adapter;u32 net_config_size =sizeof (struct virtio_net_config );u32 blk_config_size =sizeof (struct virtio_blk_config );u32 cap_size = hw->cap_dev_config_size;u32 config_size; - adapter =vf_to_adapter (hw);/* If the onboard device config space size is greater than * the size of struct virtio_net/blk_config, only the spec * implementing contents size is returned, this is very
@@ -251,7 +240,7 @@ u32 ifcvf_get_config_size(struct ifcvf_hbreak ;default : config_size =0 ; -IFCVF_ERR (adapter->pdev,"VIRTIO ID %u not supported\n" , hw->dev_type); +IFCVF_ERR (hw->pdev,"VIRTIO ID %u not supported\n" , hw->dev_type); }return config_size;
Greg Kroah-Hartman
maintainerPATCH 180/200 vDPA/ifcvf: alloc the mgmt_dev before the adapter
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit 66e3970b16d1e960afbece65739a3628273633f1 upstream.
This commit reverses the order of allocating the management device and the adapter. So that it would be possible to move the allocation of the adapter to dev_add().
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_main.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-)
drivers/vdpa/ifcvf/ifcvf_main.c +14 -17
@@ -831,22 +831,30 @@ static int ifcvf_probe(struct pci_dev *p }pci_set_master (pdev); + ifcvf_mgmt_dev =kzalloc (sizeof (struct ifcvf_vdpa_mgmt_dev ),GFP_KERNEL ); +if (!ifcvf_mgmt_dev) { +IFCVF_ERR (pdev,"Failed to alloc memory for the vDPA management device\n" ); +return -ENOMEM ; + } adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, dev, &ifc_vdpa_ops,1 ,1 ,NULL , false);if (IS_ERR (adapter)) {IFCVF_ERR (pdev,"Failed to allocate vDPA structure" ); -return PTR_ERR (adapter); + ret =PTR_ERR (adapter); + goto err; } + adapter->pdev = pdev; + adapter->vdpa.dma_dev = &pdev->dev; + adapter->vdpa.mdev = &ifcvf_mgmt_dev->mdev; + ifcvf_mgmt_dev->adapter = adapter; + vf = &adapter->vf; vf->dev_type =get_dev_type (pdev); vf->base =pcim_iomap_table (pdev); vf->pdev = pdev; - adapter->pdev = pdev; - adapter->vdpa.dma_dev = &pdev->dev; - ret =ifcvf_init_hw (vf, pdev);if (ret) {IFCVF_ERR (pdev,"Failed to init IFCVF hw\n" );
@@ -859,16 +867,6 @@ static int ifcvf_probe(struct pci_dev *p vf->hw_features =ifcvf_get_hw_features (vf); vf->config_size =ifcvf_get_config_size (vf); - ifcvf_mgmt_dev =kzalloc (sizeof (struct ifcvf_vdpa_mgmt_dev ),GFP_KERNEL ); -if (!ifcvf_mgmt_dev) { -IFCVF_ERR (pdev,"Failed to alloc memory for the vDPA management device\n" ); -return -ENOMEM ; - } - - ifcvf_mgmt_dev->mdev.ops = &ifcvf_vdpa_mgmt_dev_ops; - ifcvf_mgmt_dev->mdev.device = dev; - ifcvf_mgmt_dev->adapter = adapter; - dev_type =get_dev_type (pdev);switch (dev_type) {case VIRTIO_ID_NET :
@@ -883,12 +881,11 @@ static int ifcvf_probe(struct pci_dev *p goto err; } + ifcvf_mgmt_dev->mdev.ops = &ifcvf_vdpa_mgmt_dev_ops; + ifcvf_mgmt_dev->mdev.device = dev; ifcvf_mgmt_dev->mdev.max_supported_vqs = vf->nr_vring; ifcvf_mgmt_dev->mdev.supported_features = vf->hw_features; - adapter->vdpa.mdev = &ifcvf_mgmt_dev->mdev; - - ret =vdpa_mgmtdev_register (&ifcvf_mgmt_dev->mdev);if (ret) { IFCVF_ERR(pdev,
Greg Kroah-Hartman
maintainerPATCH 181/200 vDPA/ifcvf: decouple vq IRQ releasers from the adapter
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit 004cbcabab46d9346e2524c4eedd71ea57fe4f3c upstream.
This commit decouples the IRQ releasers from the adapter, so that these functions could be safely invoked once probe
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_main.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)
drivers/vdpa/ifcvf/ifcvf_main.c +9 -12
@@ -69,10 +69,9 @@ static void ifcvf_free_irq_vectors(voidpci_free_irq_vectors (data); } -static void ifcvf_free_per_vq_irq (struct ifcvf_adapter *adapter) +static void ifcvf_free_per_vq_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;int i;for (i =0 ; i < vf->nr_vring; i++) {
@@ -83,10 +82,9 @@ static void ifcvf_free_per_vq_irq(struct } } -static void ifcvf_free_vqs_reused_irq (struct ifcvf_adapter *adapter) +static void ifcvf_free_vqs_reused_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;if (vf->vqs_reused_irq != -EINVAL ) {devm_free_irq (&pdev->dev, vf->vqs_reused_irq, vf);
@@ -95,14 +93,12 @@ static void ifcvf_free_vqs_reused_irq(st } -static void ifcvf_free_vq_irq (struct ifcvf_adapter *adapter) +static void ifcvf_free_vq_irq (struct ifcvf_hw *vf) { -struct ifcvf_hw *vf = &adapter->vf; -if (vf->msix_vector_status ==MSIX_VECTOR_PER_VQ_AND_CONFIG ) -ifcvf_free_per_vq_irq (adapter); +ifcvf_free_per_vq_irq (vf);else -ifcvf_free_vqs_reused_irq (adapter); +ifcvf_free_vqs_reused_irq (vf); }static void ifcvf_free_config_irq (struct ifcvf_adapter *adapter)
@@ -126,8 +122,9 @@ static void ifcvf_free_config_irq(structstatic void ifcvf_free_irq (struct ifcvf_adapter *adapter) {struct pci_dev *pdev = adapter->pdev; +struct ifcvf_hw *vf = &adapter->vf; -ifcvf_free_vq_irq (adapter); +ifcvf_free_vq_irq (vf);ifcvf_free_config_irq (adapter);ifcvf_free_irq_vectors (pdev); }
Greg Kroah-Hartman
maintainerPATCH 182/200 vDPA/ifcvf: decouple config IRQ releaser from the adapter
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit 23dac55cec3afdbc1b4eaed1c79f2cee00477f8b upstream.
This commit decouples config IRQ releaser from the adapter, so that it could be invoked once probe or in err handlers. ifcvf_free_irq() works on ifcvf_hw in this commit
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_main.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-)
drivers/vdpa/ifcvf/ifcvf_main.c +10 -12
@@ -101,10 +101,9 @@ static void ifcvf_free_vq_irq(struct ifcifcvf_free_vqs_reused_irq (vf); } -static void ifcvf_free_config_irq (struct ifcvf_adapter *adapter) +static void ifcvf_free_config_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;if (vf->config_irq == -EINVAL )return ;
@@ -119,13 +118,12 @@ static void ifcvf_free_config_irq(struct } } -static void ifcvf_free_irq (struct ifcvf_adapter *adapter) +static void ifcvf_free_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;ifcvf_free_vq_irq (vf); -ifcvf_free_config_irq (adapter); +ifcvf_free_config_irq (vf);ifcvf_free_irq_vectors (pdev); }
@@ -187,7 +185,7 @@ static int ifcvf_request_per_vq_irq(strureturn 0 ; err: -ifcvf_free_irq (adapter); +ifcvf_free_irq (vf);return -EFAULT ; }
@@ -221,7 +219,7 @@ static int ifcvf_request_vqs_reused_irq(return 0 ; err: -ifcvf_free_irq (adapter); +ifcvf_free_irq (vf);return -EFAULT ; }
@@ -262,7 +260,7 @@ static int ifcvf_request_dev_irq(structreturn 0 ; err: -ifcvf_free_irq (adapter); +ifcvf_free_irq (vf);return -EFAULT ;
@@ -317,7 +315,7 @@ static int ifcvf_request_config_irq(strureturn 0 ; err: -ifcvf_free_irq (adapter); +ifcvf_free_irq (vf);return -EFAULT ; }
@@ -508,7 +506,7 @@ static int ifcvf_vdpa_reset(struct vdpa_if (status_old &VIRTIO_CONFIG_S_DRIVER_OK ) {ifcvf_stop_datapath (adapter); -ifcvf_free_irq (adapter); +ifcvf_free_irq (vf); }ifcvf_reset_vring (adapter);
Greg Kroah-Hartman
maintainerPATCH 183/200 vDPA/ifcvf: decouple vq irq requester from the adapter
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit f9a9ffb2e4dbde81090416fc51662441c2a7b73b upstream.
This commit decouples the vq irq requester from the adapter, so that these functions can be invoked since probe.
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_main.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-)
drivers/vdpa/ifcvf/ifcvf_main.c +8 -11
@@ -155,10 +155,9 @@ static int ifcvf_alloc_vectors(struct ifreturn ret; } -static int ifcvf_request_per_vq_irq (struct ifcvf_adapter *adapter) +static int ifcvf_request_per_vq_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;int i, vector, ret, irq; vf->vqs_reused_irq = -EINVAL ;
@@ -190,10 +189,9 @@ err:return -EFAULT ; } -static int ifcvf_request_vqs_reused_irq (struct ifcvf_adapter *adapter) +static int ifcvf_request_vqs_reused_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;int i, vector, ret, irq; vector =0 ;
@@ -266,15 +264,14 @@ err: } -static int ifcvf_request_vq_irq (struct ifcvf_adapter *adapter) +static int ifcvf_request_vq_irq (struct ifcvf_hw *vf) { -struct ifcvf_hw *vf = &adapter->vf;int ret;if (vf->msix_vector_status ==MSIX_VECTOR_PER_VQ_AND_CONFIG ) - ret =ifcvf_request_per_vq_irq (adapter); + ret =ifcvf_request_per_vq_irq (vf);else - ret =ifcvf_request_vqs_reused_irq (adapter); + ret =ifcvf_request_vqs_reused_irq (vf);return ret; }
@@ -341,7 +338,7 @@ static int ifcvf_request_irq(struct ifcvreturn ret; } - ret =ifcvf_request_vq_irq (adapter); + ret =ifcvf_request_vq_irq (vf);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 184/200 vDPA/ifcvf: decouple config/dev IRQ requester and vectors allocator from the adapter
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit a70d833e696e538a0feff5e539086c74a90ddf90 upstream.
This commit decouples the config irq requester, the device shared irq requester and the MSI vectors allocator from the adapter. So they can be safely invoked since probe before the adapter is allocated.
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_main.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)
drivers/vdpa/ifcvf/ifcvf_main.c +9 -12
@@ -132,10 +132,9 @@ static void ifcvf_free_irq(struct ifcvf_* It returns the number of allocated vectors, negative * return value when fails. */ -static int ifcvf_alloc_vectors (struct ifcvf_adapter *adapter) +static int ifcvf_alloc_vectors (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;int max_intr, ret;/* all queues and config interrupt */
@@ -222,10 +221,9 @@ err:return -EFAULT ; } -static int ifcvf_request_dev_irq (struct ifcvf_adapter *adapter) +static int ifcvf_request_dev_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;int i, vector, ret, irq; vector =0 ;
@@ -276,10 +274,9 @@ static int ifcvf_request_vq_irq(struct ireturn ret; } -static int ifcvf_request_config_irq (struct ifcvf_adapter *adapter) +static int ifcvf_request_config_irq (struct ifcvf_hw *vf) { -struct pci_dev *pdev = adapter->pdev; -struct ifcvf_hw *vf = &adapter->vf; +struct pci_dev *pdev = vf->pdev;int config_vector, ret;if (vf->msix_vector_status ==MSIX_VECTOR_PER_VQ_AND_CONFIG )
@@ -322,7 +319,7 @@ static int ifcvf_request_irq(struct ifcvstruct ifcvf_hw *vf = &adapter->vf;int nvectors, ret, max_intr; - nvectors =ifcvf_alloc_vectors (adapter); + nvectors =ifcvf_alloc_vectors (vf);if (nvectors <=0 )return -EFAULT ;
@@ -333,7 +330,7 @@ static int ifcvf_request_irq(struct ifcvif (nvectors ==1 ) { vf->msix_vector_status =MSIX_VECTOR_DEV_SHARED ; - ret =ifcvf_request_dev_irq (adapter); + ret =ifcvf_request_dev_irq (vf);return ret; }
@@ -342,7 +339,7 @@ static int ifcvf_request_irq(struct ifcvif (ret)return ret; - ret =ifcvf_request_config_irq (adapter); + ret =ifcvf_request_config_irq (vf);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 185/200 vDPA/ifcvf: ifcvf_request_irq works on ifcvf_hw
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit 7cfd36b7e8be6bdaeb5af0f9729871b732a7a3c8 upstream.
All ifcvf_request_irq's callees are refactored to work on ifcvf_hw, so it should be decoupled from the adapter as well
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/vdpa/ifcvf/ifcvf_main.c +2 -3
@@ -314,9 +314,8 @@ err:return -EFAULT ; } -static int ifcvf_request_irq (struct ifcvf_adapter *adapter) +static int ifcvf_request_irq (struct ifcvf_hw *vf) { -struct ifcvf_hw *vf = &adapter->vf;int nvectors, ret, max_intr; nvectors =ifcvf_alloc_vectors (vf);
@@ -468,7 +467,7 @@ static void ifcvf_vdpa_set_status(structif ((status &VIRTIO_CONFIG_S_DRIVER_OK ) && !(status_old &VIRTIO_CONFIG_S_DRIVER_OK )) { - ret =ifcvf_request_irq (adapter); + ret =ifcvf_request_irq (vf);if (ret) { status =ifcvf_get_status (vf); status |=VIRTIO_CONFIG_S_FAILED ;
Greg Kroah-Hartman
maintainerPATCH 186/200 vDPA/ifcvf: manage ifcvf_hw in the mgmt_dev
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit 6a3b2f179b49f2c6452ecc37b4778a43848b454c upstream.
This commit allocates the hw structure in the management device structure. So the hardware can be initialized once the management device is allocated in probe.
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_base.h | 5 +++-- drivers/vdpa/ifcvf/ifcvf_main.c | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-)
drivers/vdpa/ifcvf/ifcvf_base.h +3 -2
@@ -39,7 +39,7 @@#define IFCVF_INFO (pdev, fmt, ...) dev_info(&pdev->dev, fmt, ##__VA_ARGS__)#define ifcvf_private_to_vf (adapter) \ - (&((struct ifcvf_adapter *)adapter)->vf) + (((struct ifcvf_adapter *)adapter)->vf)/* all vqs and config interrupt has its own vector */ #define MSIX_VECTOR_PER_VQ_AND_CONFIG 1
@@ -95,7 +95,7 @@ struct ifcvf_hw {struct ifcvf_adapter {struct vdpa_device vdpa;struct pci_dev *pdev; -struct ifcvf_hw vf; +struct ifcvf_hw *vf; };struct ifcvf_vring_lm_cfg {
@@ -110,6 +110,7 @@ struct ifcvf_lm_cfg {struct ifcvf_vdpa_mgmt_dev {struct vdpa_mgmt_dev mdev; +struct ifcvf_hw vf;struct ifcvf_adapter *adapter;struct pci_dev *pdev; };
drivers/vdpa/ifcvf/ifcvf_main.c +4 -3
@@ -402,7 +402,7 @@ static struct ifcvf_hw *vdpa_to_vf(struc {struct ifcvf_adapter *adapter =vdpa_to_adapter (vdpa_dev); -return &adapter->vf; +return adapter->vf; }static u64 ifcvf_vdpa_get_device_features (struct vdpa_device *vdpa_dev)
@@ -750,7 +750,7 @@ static int ifcvf_vdpa_dev_add(struct vdpreturn -EOPNOTSUPP ; adapter = ifcvf_mgmt_dev->adapter; - vf = &adapter->vf; + vf = adapter->vf; pdev = adapter->pdev; vdpa_dev = &adapter->vdpa;
@@ -838,10 +838,11 @@ static int ifcvf_probe(struct pci_dev *p adapter->vdpa.mdev = &ifcvf_mgmt_dev->mdev; ifcvf_mgmt_dev->adapter = adapter; - vf = &adapter->vf; + vf = &ifcvf_mgmt_dev->vf; vf->dev_type =get_dev_type (pdev); vf->base =pcim_iomap_table (pdev); vf->pdev = pdev; + adapter->vf = vf; ret =ifcvf_init_hw (vf, pdev);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 187/200 vDPA/ifcvf: allocate the adapter in dev_add()
In reply to Greg Kroah-HartmanFrom: Zhu Lingshan <[email protected]>
commit 93139037b582134deb1ed894bbc4bc1d34ff35e7 upstream.
The adapter is the container of the vdpa_device, this commits allocate the adapter in dev_add() rather than in probe(). So that the vdpa_device() could be re-created when the userspace creates the vdpa device, and free-ed in dev_del()
Message-Id: <[email protected]>
--- drivers/vdpa/ifcvf/ifcvf_main.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-)
drivers/vdpa/ifcvf/ifcvf_main.c +13 -21
@@ -746,12 +746,20 @@ static int ifcvf_vdpa_dev_add(struct vdpint ret; ifcvf_mgmt_dev = container_of(mdev, struct ifcvf_vdpa_mgmt_dev, mdev); -if (!ifcvf_mgmt_dev->adapter) -return -EOPNOTSUPP ; + vf = &ifcvf_mgmt_dev->vf; + pdev = vf->pdev; + adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, + &pdev->dev, &ifc_vdpa_ops,1 ,1 ,NULL , false); +if (IS_ERR (adapter)) { +IFCVF_ERR (pdev,"Failed to allocate vDPA structure" ); +return PTR_ERR (adapter); + } - adapter = ifcvf_mgmt_dev->adapter; - vf = adapter->vf; - pdev = adapter->pdev; + ifcvf_mgmt_dev->adapter = adapter; + adapter->pdev = pdev; + adapter->vdpa.dma_dev = &pdev->dev; + adapter->vdpa.mdev = mdev; + adapter->vf = vf; vdpa_dev = &adapter->vdpa;if (name)
@@ -769,7 +777,6 @@ static int ifcvf_vdpa_dev_add(struct vdpreturn 0 ; } -static void ifcvf_vdpa_dev_del (struct vdpa_mgmt_dev *mdev,struct vdpa_device *dev) {struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev;
@@ -788,7 +795,6 @@ static int ifcvf_probe(struct pci_dev *p {struct ifcvf_vdpa_mgmt_dev *ifcvf_mgmt_dev;struct device *dev = &pdev->dev; -struct ifcvf_adapter *adapter;struct ifcvf_hw *vf;u32 dev_type;int ret, i;
@@ -825,24 +831,10 @@ static int ifcvf_probe(struct pci_dev *preturn -ENOMEM ; } - adapter = vdpa_alloc_device(struct ifcvf_adapter, vdpa, - dev, &ifc_vdpa_ops,1 ,1 ,NULL , false); -if (IS_ERR (adapter)) { -IFCVF_ERR (pdev,"Failed to allocate vDPA structure" ); - ret =PTR_ERR (adapter); - goto err; - } - - adapter->pdev = pdev; - adapter->vdpa.dma_dev = &pdev->dev; - adapter->vdpa.mdev = &ifcvf_mgmt_dev->mdev; - ifcvf_mgmt_dev->adapter = adapter; - vf = &ifcvf_mgmt_dev->vf; vf->dev_type =get_dev_type (pdev); vf->base =pcim_iomap_table (pdev); vf->pdev = pdev; - adapter->vf = vf; ret =ifcvf_init_hw (vf, pdev);if (ret) {
Greg Kroah-Hartman
maintainerPATCH 188/200 drm/display/dp_mst: Add drm_atomic_get_old_mst_topology_state()
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
commit 9ffdb67af0ee625ae127711845532f670cc6a4e7 upstream.
Add a function to get the old MST topology state, required by a follow-up i915 patch.
While at it clarify the code comment of drm_atomic_get_new_mst_topology_state() and add _new prefix to the new state pointer to remind about its difference from the old state.
v2: Use old_/new_ prefixes for the state pointers. (Ville)
--- drivers/gpu/drm/display/drm_dp_mst_topology.c | 33 ++++++++++++++++++++++---- include/drm/display/drm_dp_mst_helper.h | 3 ++ 2 files changed, 32 insertions(+), 4 deletions(-)
drivers/gpu/drm/display/drm_dp_mst_topology.c +29 -4
@@ -5355,27 +5355,52 @@ struct drm_dp_mst_topology_state *drm_atEXPORT_SYMBOL (drm_atomic_get_mst_topology_state);/** +* drm_atomic_get_old_mst_topology_state: get old MST topology state in atomic state, if any +* @state: global atomic state +* @mgr: MST topology manager, also the private object in this case +* +* This function wraps drm_atomic_get_old_private_obj_state() passing in the MST atomic +* state vtable so that the private object state returned is that of a MST +* topology object. +* +* Returns: +* +* The old MST topology state, or NULL if there's no topology state for this MST mgr +* in the global atomic state +*/ +struct drm_dp_mst_topology_state * +drm_atomic_get_old_mst_topology_state (struct drm_atomic_state *state, +struct drm_dp_mst_topology_mgr *mgr) +{ +struct drm_private_state *old_priv_state = +drm_atomic_get_old_private_obj_state (state, &mgr->base); + +return old_priv_state ?to_dp_mst_topology_state (old_priv_state) :NULL ; +} +EXPORT_SYMBOL (drm_atomic_get_old_mst_topology_state); + +/** * drm_atomic_get_new_mst_topology_state: get new MST topology state in atomic state, if any * @state: global atomic state * @mgr: MST topology manager, also the private object in this case * -* This function wraps drm_atomic_get_priv_obj_state() passing in the MST atomic +* This function wraps drm_atomic_get_new_private_obj_state() passing in the MST atomic * state vtable so that the private object state returned is that of a MST * topology object. * * Returns: * -* The MST topology state, or NULL if there's no topology state for this MST mgr +* The new MST topology state, or NULL if there's no topology state for this MST mgr * in the global atomic state */ struct drm_dp_mst_topology_state *drm_atomic_get_new_mst_topology_state (struct drm_atomic_state *state,struct drm_dp_mst_topology_mgr *mgr) { -struct drm_private_state *priv_state = +struct drm_private_state *new_priv_state =drm_atomic_get_new_private_obj_state (state, &mgr->base); -return priv_state ?to_dp_mst_topology_state (priv_state) :NULL ; +return new_priv_state ?to_dp_mst_topology_state (new_priv_state) :NULL ; }EXPORT_SYMBOL (drm_atomic_get_new_mst_topology_state);
include/drm/display/drm_dp_mst_helper.h +3 -0
@@ -867,6 +867,9 @@ struct drm_dp_mst_topology_state * drm_atomic_get_mst_topology_state(struct drm_atomic_state *state, struct drm_dp_mst_topology_mgr *mgr);struct drm_dp_mst_topology_state * +drm_atomic_get_old_mst_topology_state (struct drm_atomic_state *state, +struct drm_dp_mst_topology_mgr *mgr); +struct drm_dp_mst_topology_state *drm_atomic_get_new_mst_topology_state (struct drm_atomic_state *state,struct drm_dp_mst_topology_mgr *mgr); struct drm_dp_mst_atomic_payload *
Greg Kroah-Hartman
maintainerPATCH 189/200 drm/display/dp_mst: Fix down/up message handling after sink disconnect
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
commit 1d082618bbf3b6755b8cc68c0a8122af2842d593 upstream.
If the sink gets disconnected during receiving a multi-packet DP MST AUX down-reply/up-request sideband message, the state keeping track of which packets have been received already is not reset. This results in a failed sanity check for the subsequent message packet received after a sink is reconnected (due to the pending message not yet completed with an end-of-message-transfer packet), indicated by the
"sideband msg set header failed"
error.
Fix the above by resetting the up/down message reception state after a disconnect event.
--- drivers/gpu/drm/display/drm_dp_mst_topology.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/display/drm_dp_mst_topology.c +3 -0
@@ -3644,6 +3644,9 @@ int drm_dp_mst_topology_mgr_set_mst(strudrm_dp_dpcd_writeb (mgr->aux,DP_MSTM_CTRL ,0 ); ret =0 ; mgr->payload_id_table_cleared = false; + +memset (&mgr->down_rep_recv,0 ,sizeof (mgr->down_rep_recv)); +memset (&mgr->up_req_recv,0 ,sizeof (mgr->up_req_recv)); } out_unlock:
Greg Kroah-Hartman
maintainerPATCH 190/200 drm/display/dp_mst: Fix down message handling after a packet reception error
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
commit 1241aedb6b5c7a5a8ad73e5eb3a41cfe18a3e00e upstream.
After an error during receiving a packet for a multi-packet DP MST sideband message, the state tracking which packets have been received already is not reset. This prevents the reception of subsequent down messages (due to the pending message not yet completed with an end-of-message-transfer packet).
Fix the above by resetting the reception state after a packet error.
--- drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/display/drm_dp_mst_topology.c +1 -1
@@ -3859,7 +3859,7 @@ static int drm_dp_mst_handle_down_rep(ststruct drm_dp_sideband_msg_rx *msg = &mgr->down_rep_recv;if (!drm_dp_get_one_sb_msg (mgr, false, &mstb)) - goto out; + goto out_clear_reply;/* Multi-packet message transmission, don't clear the reply */ if (!msg->have_eomt)
Greg Kroah-Hartman
maintainerPATCH 191/200 drm/display/dp_mst: Fix payload addition on a disconnected sink
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
commit 33f960e23c29d113fe3193e0bdc19ac4f3776f20 upstream.
If an MST stream is enabled on a disconnected sink, the payload for the stream is not created and the MST manager's payload count/next start VC slot is not updated. Since the payload's start VC slot may still contain a valid value (!= -1) the subsequent disabling of such a stream could cause an incorrect decrease of the payload count/next start VC slot in drm_dp_remove_payload() and hence later payload additions will fail.
Fix the above by marking the payload as invalid in the above case, so that it's skipped during payload removal. While at it add a debug print for this case.
--- drivers/gpu/drm/display/drm_dp_mst_topology.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/gpu/drm/display/drm_dp_mst_topology.c +6 -1
@@ -3309,8 +3309,13 @@ int drm_dp_add_payload_part1(struct drm_dp_mst_topology_mgr *mgr,int ret; port =drm_dp_mst_topology_get_port_validated (mgr, payload->port); -if (!port) +if (!port) { +drm_dbg_kms (mgr->dev, +"VCPI %d for port %p not in topology, not creating a payload\n" , + payload->vcpi, payload->port); + payload->vc_start_slot =-1 ;return 0 ; + }if (mgr->payload_count ==0 ) mgr->next_start_slot = mst_state->start_slot;
Signature · 1 line
2.39.2
Greg Kroah-Hartman
maintainerPATCH 192/200 drm/i915/dp_mst: Add the MST topology state for modesetted CRTCs
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
commit 326b1e792ff08b4d8ecb9605aec98e4e5feef56e upstream.
Add the MST topology for a CRTC to the atomic state if the driver needs to force a modeset on the CRTC after the encoder compute config functions are called.
Later the MST encoder's disable hook also adds the state, but that isn't guaranteed to work (since in that hook getting the state may fail, which can't be handled there). This should fix that, while a later patch fixes the use of the MST state in the disable hook.
v2: Add missing forward struct declartions, caught by hdrtest.
v3: Factor out intel_dp_mst_add_topology_state_for_connector() used
later in the patchset.
--- drivers/gpu/drm/i915/display/intel_display.c | 4 + drivers/gpu/drm/i915/display/intel_dp_mst.c | 61 +++++++++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_dp_mst.h | 4 + 3 files changed, 69 insertions(+)
drivers/gpu/drm/i915/display/intel_display.c +4 -0
@@ -5969,6 +5969,10 @@ int intel_modeset_all_pipes(struct intelif (ret)return ret; + ret =intel_dp_mst_add_topology_state_for_crtc (state, crtc); +if (ret) +return ret; + ret =intel_atomic_add_affected_planes (state, crtc);if (ret)return ret;
drivers/gpu/drm/i915/display/intel_dp_mst.c +61 -0
64 lines not on this page · raw message
drivers/gpu/drm/i915/display/intel_dp_mst.h +4 -0
@@ -8,6 +8,8 @@#include <linux/types.h> +struct intel_atomic_state ; +struct intel_crtc ;struct intel_crtc_state ;struct intel_digital_port ;struct intel_dp ;
@@ -18,5 +20,7 @@ int intel_dp_mst_encoder_active_links(stbool intel_dp_mst_is_master_trans (const struct intel_crtc_state *crtc_state);bool intel_dp_mst_is_slave_trans (const struct intel_crtc_state *crtc_state);bool intel_dp_mst_source_support (struct intel_dp *intel_dp); +int intel_dp_mst_add_topology_state_for_crtc (struct intel_atomic_state *state, +struct intel_crtc *crtc);#endif /* __INTEL_DP_MST_H__ */
Greg Kroah-Hartman
maintainerPATCH 193/200 drm/i915: Fix system suspend without fbdev being initialized
In reply to Greg Kroah-HartmanFrom: Imre Deak <[email protected]>
commit 8038510b1fe443ffbc0e356db5f47cbb8678a594 upstream.
If fbdev is not initialized for some reason - in practice on platforms without display - suspending fbdev should be skipped during system suspend, fix this up. While at it add an assert that suspending fbdev only happens with the display present.
This fixes the following:
[ 91.227923] PM: suspend entry (s2idle) [ 91.254598] Filesystems sync: 0.025 seconds [ 91.270518] Freezing user space processes [ 91.272266] Freezing user space processes completed (elapsed 0.001 seconds) [ 91.272686] OOM killer disabled. [ 91.272872] Freezing remaining freezable tasks [ 91.274295] Freezing remaining freezable tasks completed (elapsed 0.001 seconds) [ 91.659622] BUG: kernel NULL pointer dereference, address: 00000000000001c8 [ 91.659981] #PF: supervisor write access in kernel mode [ 91.660252] #PF: error_code(0x0002) - not-present page [ 91.660511] PGD 0 P4D 0 [ 91.660647] Oops: 0002 [#1] PREEMPT SMP NOPTI [ 91.660875] CPU: 4 PID: 917 Comm: bash Not tainted 6.2.0-rc7+ #54 [ 91.661185] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20221117gitfff6d81270b5-9.fc37 unknown [ 91.661680] RIP: 0010:mutex_lock+0x19/0x30 [ 91.661914] Code: 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 0f 1f 44 00 00 53 48 89 fb e8 62 d3 ff ff 31 c0 65 48 8b 14 25 00 15 03 00 <f0> 48 0f b1 13 75 06 5b c3 cc cc cc cc 48 89 df 5b eb b4 0f 1f 40 [ 91.662840] RSP: 0018:ffffa1e8011ffc08 EFLAGS: 00010246 [ 91.663087] RAX: 0000000000000000 RBX: 00000000000001c8 RCX: 0000000000000000 [ 91.663440] RDX: ffff8be455eb0000 RSI: 0000000000000001 RDI: 00000000000001c8 [ 91.663802] RBP: ffff8be459440000 R08: ffff8be459441f08 R09: ffffffff8e1432c0 [ 91.664167] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000001 [ 91.664532] R13: 00000000000001c8 R14: 0000000000000000 R15: ffff8be442f4fb20 [ 91.664905] FS: 00007f28ffc16740(0000) GS:ffff8be4bb900000(0000) knlGS:0000000000000000 [ 91.665334] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 91.665626] CR2: 00000000000001c8 CR3: 0000000114926006 CR4: 0000000000770ee0 [ 91.665988] PKRU: 55555554 [ 91.666131] Call Trace: [ 91.666265] <TASK> [ 91.666381] intel_fbdev_set_suspend+0x97/0x1b0 [i915] [ 91.666738] i915_drm_suspend+0xb9/0x100 [i915] [ 91.667029] pci_pm_suspend+0x78/0x170 [ 91.667234] ? __pfx_pci_pm_suspend+0x10/0x10 [ 91.667461] dpm_run_callback+0x47/0x150 [ 91.667673] __device_suspend+0x10a/0x4e0 [ 91.667880] dpm_suspend+0x134/0x270 [ 91.668069] dpm_suspend_start+0x79/0x80 [ 91.668272] suspend_devices_and_enter+0x11b/0x890 [ 91.668526] pm_suspend.cold+0x270/0x2fc [ 91.668737] state_store+0x46/0x90 [ 91.668916] kernfs_fop_write_iter+0x11b/0x200 [ 91.669153] vfs_write+0x1e1/0x3a0 [ 91.669336] ksys_write+0x53/0xd0 [ 91.669510] do_syscall_64+0x58/0xc0 [ 91.669699] ? syscall_exit_to_user_mode_prepare+0x18e/0x1c0 [ 91.669980] ? syscall_exit_to_user_mode_prepare+0x18e/0x1c0 [ 91.670278] ? syscall_exit_to_user_mode+0x17/0x40 [ 91.670524] ? do_syscall_64+0x67/0xc0 [ 91.670717] ? __irq_exit_rcu+0x3d/0x140 [ 91.670931] entry_SYSCALL_64_after_hwframe+0x72/0xdc [ 91.671202] RIP: 0033:0x7f28ffd14284
v2: CC stable. (Jani)
--- drivers/gpu/drm/i915/display/intel_fbdev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/gpu/drm/i915/display/intel_fbdev.c +7 -1
@@ -624,7 +624,13 @@ void intel_fbdev_set_suspend(struct drm_struct intel_fbdev *ifbdev = dev_priv->display.fbdev.fbdev;struct fb_info *info; -if (!ifbdev || !ifbdev->vma) +if (!ifbdev) +return ; + +if (drm_WARN_ON (&dev_priv->drm, !HAS_DISPLAY (dev_priv))) +return ; + +if (!ifbdev->vma) goto set_suspend; info = ifbdev->helper.fbdev;
Greg Kroah-Hartman
maintainerPATCH 194/200 media: uvcvideo: Fix race condition with usb_kill_urb
In reply to Greg Kroah-HartmanFrom: Ricardo Ribalda <[email protected]>
commit 619d9b710cf06f7a00a17120ca92333684ac45a8 upstream.
usb_kill_urb warranties that all the handlers are finished when it returns, but does not protect against threads that might be handling asynchronously the urb.
For UVC, the function uvc_ctrl_status_event_async() takes care of control changes asynchronously.
If the code is executed in the following order:
CPU 0 CPU 1
===== =====uvc_status_complete()
uvc_status_stop()uvc_ctrl_status_event_work()
uvc_status_start() -> FAIL
Then uvc_status_start will keep failing and this error will be shown:
<4>[ 5.540139] URB 0000000000000000 submitted while active
drivers/usb/core/urb.c:378 usb_submit_urb+0x4c3/0x528
Let's improve the current situation, by not re-submiting the urb if we are stopping the status event. Also process the queued work (if any) during stop.
CPU 0 CPU 1
===== =====uvc_status_complete()
uvc_status_stop() uvc_status_start()uvc_ctrl_status_event_work() -> FAIL
Hopefully, with the usb layer protection this should be enough to cover all the cases.
--- drivers/media/usb/uvc/uvc_ctrl.c | 5 +++++ drivers/media/usb/uvc/uvc_status.c | 37 +++++++++++++++++++++++++++++++++++++ drivers/media/usb/uvc/uvcvideo.h | 1 + 3 files changed, 43 insertions(+)
drivers/media/usb/uvc/uvc_ctrl.c +5 -0
@@ -6,6 +6,7 @@* Laurent Pinchart ([email protected]) */ +#include <asm/barrier.h> #include <linux/bitops.h> #include <linux/kernel.h> #include <linux/list.h>
@@ -1509,6 +1510,10 @@ static void uvc_ctrl_status_event_work(suvc_ctrl_status_event (w->chain, w->ctrl, w->data); +/* The barrier is needed to synchronize with uvc_status_stop(). */ +if (smp_load_acquire (&dev->flush_status)) +return ; +/* Resubmit the URB. */ w->urb->interval = dev->int_ep->desc.bInterval; ret =usb_submit_urb (w->urb,GFP_KERNEL );
drivers/media/usb/uvc/uvc_status.c +37 -0
@@ -6,6 +6,7 @@* Laurent Pinchart ([email protected]) */ +#include <asm/barrier.h> #include <linux/kernel.h> #include <linux/input.h> #include <linux/slab.h>
@@ -309,5 +310,41 @@ int uvc_status_start(struct uvc_device *void uvc_status_stop (struct uvc_device *dev) { +struct uvc_ctrl_work *w = &dev->async_ctrl; + +/* +* Prevent the asynchronous control handler from requeing the URB. The +* barrier is needed so the flush_status change is visible to other +* CPUs running the asynchronous handler before usb_kill_urb() is +* called below. +*/ +smp_store_release (&dev->flush_status, true); + +/* +* Cancel any pending asynchronous work. If any status event was queued, +* process it synchronously. +*/ +if (cancel_work_sync (&w->work)) +uvc_ctrl_status_event (w->chain, w->ctrl, w->data); + +/* Kill the urb. */ usb_kill_urb (dev->int_urb); + +/* +* The URB completion handler may have queued asynchronous work. This +* won't resubmit the URB as flush_status is set, but it needs to be +* cancelled before returning or it could then race with a future +* uvc_status_start() call. +*/ +if (cancel_work_sync (&w->work)) +uvc_ctrl_status_event (w->chain, w->ctrl, w->data); + +/* +* From this point, there are no events on the queue and the status URB +* is dead. No events will be queued until uvc_status_start() is called. +* The barrier is needed to make sure that flush_status is visible to +* uvc_ctrl_status_event_work() when uvc_status_start() will be called +* again. +*/ +smp_store_release (&dev->flush_status, false); }
drivers/media/usb/uvc/uvcvideo.h +1 -0
@@ -558,6 +558,7 @@ struct uvc_device {/* Status Interrupt Endpoint */ struct usb_host_endpoint *int_ep;struct urb *int_urb; +bool flush_status;u8 *status;struct input_dev *input;char input_phys[64 ];
Greg Kroah-Hartman
maintainerPATCH 195/200 io_uring: fix two assignments in if conditions
In reply to Greg Kroah-HartmanFrom: Xinghui Li <[email protected]>
commit df730ec21f7ba395b1b22e7f93a3a85b1d1b7882 upstream.
Fixes two errors:
"ERROR: do not use assignment in if condition
130: FILE: io_uring/net.c:130:
+ if (!(issue_flags & IO_URING_F_UNLOCKED) &&
ERROR: do not use assignment in if condition
599: FILE: io_uring/poll.c:599:
+ } else if (!(issue_flags & IO_URING_F_UNLOCKED) &&"
reported by checkpatch.pl in net.c and poll.c .
--- io_uring/net.c | 16 +++++++++------- io_uring/poll.c | 7 +++++-- 2 files changed, 14 insertions(+), 9 deletions(-)
io_uring/net.c +9 -7
@@ -126,13 +126,15 @@ static struct io_async_msghdr *io_msg_alstruct io_cache_entry *entry;struct io_async_msghdr *hdr; -if (!(issue_flags &IO_URING_F_UNLOCKED ) && - (entry =io_alloc_cache_get (&ctx->netmsg_cache)) !=NULL ) { - hdr = container_of(entry, struct io_async_msghdr, cache); - hdr->free_iov =NULL ; - req->flags |=REQ_F_ASYNC_DATA ; - req->async_data = hdr; -return hdr; +if (!(issue_flags &IO_URING_F_UNLOCKED )) { + entry =io_alloc_cache_get (&ctx->netmsg_cache); +if (entry) { + hdr = container_of(entry, struct io_async_msghdr, cache); + hdr->free_iov =NULL ; + req->flags |=REQ_F_ASYNC_DATA ; + req->async_data = hdr; +return hdr; + } }if (!io_alloc_async_data (req)) {
io_uring/poll.c +5 -2
@@ -678,10 +678,13 @@ static struct async_poll *io_req_alloc_aif (req->flags &REQ_F_POLLED ) { apoll = req->apoll;kfree (apoll->double_poll); - }else if (!(issue_flags &IO_URING_F_UNLOCKED ) && - (entry =io_alloc_cache_get (&ctx->apoll_cache)) !=NULL ) { + }else if (!(issue_flags &IO_URING_F_UNLOCKED )) { + entry =io_alloc_cache_get (&ctx->apoll_cache); +if (entry ==NULL ) + goto alloc_apoll; apoll = container_of(entry, struct async_poll, cache); }else { +alloc_apoll: apoll =kmalloc (sizeof (*apoll),GFP_ATOMIC );if (unlikely (!apoll))return NULL ;
Greg Kroah-Hartman
maintainerPATCH 196/200 io_uring/poll: allow some retries for poll triggering spuriously
In reply to Greg Kroah-HartmanFrom: Jens Axboe <[email protected]>
commit c16bda37594f83147b167d381d54c010024efecf upstream.
If we get woken spuriously when polling and fail the operation with -EAGAIN again, then we generally only allow polling again if data had been transferred at some point. This is indicated with REQ_F_PARTIAL_IO. However, if the spurious poll triggers when the socket was originally empty, then we haven't transferred data yet and we will fail the poll re-arm. This either punts the socket to io-wq if it's blocking, or it fails the request with -EAGAIN if not. Neither condition is desirable, as the former will slow things down, while the latter will make the application confused.
We want to ensure that a repeated poll trigger doesn't lead to infinite work making no progress, that's what the REQ_F_PARTIAL_IO check was for. But it doesn't protect against a loop post the first receive, and it's unnecessarily strict if we started out with an empty socket.
Add a somewhat random retry count, just to put an upper limit on the potential number of retries that will be done. This should be high enough that we won't really hit it in practice, unless something needs to be aborted anyway.
--- io_uring/poll.c | 14 ++++++++++++-- io_uring/poll.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-)
io_uring/poll.c +12 -2
@@ -668,6 +668,14 @@ static void io_async_queue_proc(struct f__io_queue_proc (&apoll->poll, pt, head, &apoll->double_poll); } +/* +* We can't reliably detect loops in repeated poll triggers and issue +* subsequently failing. But rather than fail these immediately, allow a +* certain amount of retries before we give up. Given that this condition +* should _rarely_ trigger even once, we should be fine with a larger value. +*/ +#define APOLL_MAX_RETRY 128 +static struct async_poll *io_req_alloc_apoll (struct io_kiocb *req,unsigned issue_flags) {
@@ -683,14 +691,18 @@ static struct async_poll *io_req_alloc_aif (entry ==NULL ) goto alloc_apoll; apoll = container_of(entry, struct async_poll, cache); + apoll->poll.retries =APOLL_MAX_RETRY ; }else { alloc_apoll: apoll =kmalloc (sizeof (*apoll),GFP_ATOMIC );if (unlikely (!apoll))return NULL ; + apoll->poll.retries =APOLL_MAX_RETRY ; } apoll->double_poll =NULL ; req->apoll = apoll; +if (unlikely (!--apoll->poll.retries)) +return NULL ;return apoll; }
@@ -712,8 +724,6 @@ int io_arm_poll_handler(struct io_kiocbreturn IO_APOLL_ABORTED ;if (!file_can_poll (req->file))return IO_APOLL_ABORTED ; -if ((req->flags & (REQ_F_POLLED |REQ_F_PARTIAL_IO )) ==REQ_F_POLLED ) -return IO_APOLL_ABORTED ;if (!(req->flags &REQ_F_APOLL_MULTISHOT )) mask |=EPOLLONESHOT ;
io_uring/poll.h +1 -0
@@ -12,6 +12,7 @@ struct io_poll {struct file *file;struct wait_queue_head *head;__poll_t events; +int retries;struct wait_queue_entry wait; };
Greg Kroah-Hartman
maintainerPATCH 197/200 arm64: efi: Make efi_rt_lock a raw_spinlock
In reply to Greg Kroah-HartmanFrom: Pierre Gondois <[email protected]>
commit 0e68b5517d3767562889f1d83fdb828c26adb24f upstream.
Running a rt-kernel base on 6.2.0-rc3-rt1 on an Ampere Altra outputs the following:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 9, name: kworker/u320:0
preempt_count: 2, expected: 0
RCU nest depth: 0, expected: 0
3 locks held by kworker/u320:0/9:
#0: ffff3fff8c27d128 ((wq_completion)efi_rts_wq){+.+.}-{0:0}, at: process_one_work (./include/linux/atomic/atomic-long.h:41)
#1: ffff80000861bdd0 ((work_completion)(&efi_rts_work.work)){+.+.}-{0:0}, at: process_one_work (./include/linux/atomic/atomic-long.h:41)
#2: ffffdf7e1ed3e460 (efi_rt_lock){+.+.}-{3:3}, at: efi_call_rts (drivers/firmware/efi/runtime-wrappers.c:101)
Preemption disabled at:
efi_virtmap_load (./arch/arm64/include/asm/mmu_context.h:248)
CPU: 0 PID: 9 Comm: kworker/u320:0 Tainted: G W 6.2.0-rc3-rt1
Hardware name: WIWYNN Mt.Jade Server System B81.03001.0005/Mt.Jade Motherboard, BIOS 1.08.20220218 (SCP: 1.08.20220218) 2022/02/18
Workqueue: efi_rts_wq efi_call_rts
Call trace:
dump_backtrace (arch/arm64/kernel/stacktrace.c:158)
show_stack (arch/arm64/kernel/stacktrace.c:165)
dump_stack_lvl (lib/dump_stack.c:107 (discriminator 4))
dump_stack (lib/dump_stack.c:114)
__might_resched (kernel/sched/core.c:10134)
rt_spin_lock (kernel/locking/rtmutex.c:1769 (discriminator 4))
efi_call_rts (drivers/firmware/efi/runtime-wrappers.c:101)
[...]This seems to come from commit ff7a167961d1 ("arm64: efi: Execute runtime services from a dedicated stack") which adds a spinlock. This spinlock is taken through:efi_call_rts()
\-efi_call_virt()
\-efi_call_virt_pointer()
\-arch_efi_call_virt_setup()
Make 'efi_rt_lock' a raw_spinlock to avoid being preempted.
[ardb: The EFI runtime services are called with a different set of
translation tables, and are permitted to use the SIMD registers. The context switch code preserves/restores neither, and so EFI calls must be made with preemption disabled, rather than only disabling migration.]
--- arch/arm64/include/asm/efi.h | 6 +++--- arch/arm64/kernel/efi.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
arch/arm64/include/asm/efi.h +3 -3
@@ -33,7 +33,7 @@ int efi_set_mapping_permissions(struct m ({ \efi_virtmap_load (); \__efi_fpsimd_begin (); \ -spin_lock (&efi_rt_lock); \ +raw_spin_lock (&efi_rt_lock); \ })#undef arch_efi_call_virt
@@ -42,12 +42,12 @@ int efi_set_mapping_permissions(struct m#define arch_efi_call_virt_teardown () \ ({ \ - spin_unlock(&efi_rt_lock); \ + raw_spin_unlock(&efi_rt_lock); \ __efi_fpsimd_end(); \ efi_virtmap_unload(); \ }) -extern spinlock_t efi_rt_lock; +extern raw_spinlock_t efi_rt_lock;extern u64 *efi_rt_stack_top;efi_status_t __efi_rt_asm_wrapper (void *,const char *, ...);
arch/arm64/kernel/efi.c +1 -1
@@ -146,7 +146,7 @@ asmlinkage efi_status_t efi_handle_corrureturn s; } -DEFINE_SPINLOCK (efi_rt_lock); +DEFINE_RAW_SPINLOCK (efi_rt_lock); asmlinkage u64 *efi_rt_stack_top __ro_after_init;
Greg Kroah-Hartman
maintainerPATCH 198/200 arm64: mte: Fix/clarify the PG_mte_tagged semantics
In reply to Greg Kroah-HartmanFrom: Catalin Marinas <[email protected]>
commit e059853d14ca4ed0f6a190d7109487918a22a976 upstream.
Currently the PG_mte_tagged page flag mostly means the page contains valid tags and it should be set after the tags have been cleared or restored. However, in mte_sync_tags() it is set before setting the tags to avoid, in theory, a race with concurrent mprotect(PROT_MTE) for shared pages. However, a concurrent mprotect(PROT_MTE) with a copy on write in another thread can cause the new page to have stale tags. Similarly, tag reading via ptrace() can read stale tags if the PG_mte_tagged flag is set before actually clearing/restoring the tags.
Fix the PG_mte_tagged semantics so that it is only set after the tags have been cleared or restored. This is safe for swap restoring into a MAP_SHARED or CoW page since the core code takes the page lock. Add two functions to test and set the PG_mte_tagged flag with acquire and release semantics. The downside is that concurrent mprotect(PROT_MTE) on a MAP_SHARED page may cause tag loss. This is already the case for KVM guests if a VMM changes the page protection while the guest triggers a user_mem_abort().
--- arch/arm64/include/asm/mte.h | 30 ++++++++++++++++++++++++++++++ arch/arm64/include/asm/pgtable.h | 2 +- arch/arm64/kernel/cpufeature.c | 4 +++- arch/arm64/kernel/elfcore.c | 2 +- arch/arm64/kernel/hibernate.c | 2 +- arch/arm64/kernel/mte.c | 17 +++++++++++------ arch/arm64/kvm/guest.c | 4 ++-- arch/arm64/kvm/mmu.c | 4 ++-- arch/arm64/mm/copypage.c | 5 +++-- arch/arm64/mm/fault.c | 2 +- arch/arm64/mm/mteswap.c | 2 +- 11 files changed, 56 insertions(+), 18 deletions(-)
arch/arm64/include/asm/mte.h +30 -0
@@ -37,6 +37,29 @@ void mte_free_tag_storage(char *storage)/* track which pages have valid allocation tags */ #define PG_mte_tagged PG_arch_2 +static inline void set_page_mte_tagged (struct page *page) +{ +/* +* Ensure that the tags written prior to this function are visible +* before the page flags update. +*/ +smp_wmb (); +set_bit (PG_mte_tagged, &page->flags); +} + +static inline bool page_mte_tagged (struct page *page) +{ +bool ret =test_bit (PG_mte_tagged, &page->flags); + +/* +* If the page is tagged, ensure ordering with a likely subsequent +* read of the tags. +*/ +if (ret) +smp_rmb (); +return ret; +} +void mte_zero_clear_page_tags (void *addr);void mte_sync_tags (pte_t old_pte,pte_t pte);void mte_copy_page_tags (void *kto,const void *kfrom);
@@ -56,6 +79,13 @@ size_t mte_probe_user_range(const char _/* unused if !CONFIG_ARM64_MTE, silence the compiler */ #define PG_mte_tagged 0 +static inline void set_page_mte_tagged (struct page *page) +{ +} +static inline bool page_mte_tagged (struct page *page) +{ +return false; +}static inline void mte_zero_clear_page_tags (void *addr) { }
arch/arm64/include/asm/pgtable.h +1 -1
@@ -1050,7 +1050,7 @@ static inline void arch_swap_invalidate_static inline void arch_swap_restore (swp_entry_t entry,struct folio *folio) {if (system_supports_mte () &&mte_restore_tags (entry, &folio->page)) -set_bit (PG_mte_tagged, &folio->flags); +set_page_mte_tagged (&folio->page); }#endif /* CONFIG_ARM64_MTE */
arch/arm64/kernel/cpufeature.c +3 -1
@@ -2074,8 +2074,10 @@ static void cpu_enable_mte(struct arm64_* Clear the tags in the zero page. This needs to be done via the * linear map which has the Tagged attribute. */ -if (!test_and_set_bit (PG_mte_tagged, &ZERO_PAGE (0 )->flags)) +if (!page_mte_tagged (ZERO_PAGE (0 ))) {mte_clear_page_tags (lm_alias (empty_zero_page)); +set_page_mte_tagged (ZERO_PAGE (0 )); + }kasan_init_hw_tags_cpu (); }
arch/arm64/kernel/elfcore.c +1 -1
@@ -46,7 +46,7 @@ static int mte_dump_tag_range(struct cor* Pages mapped in user space as !pte_access_permitted() (e.g. * PROT_EXEC only) may not have the PG_mte_tagged flag set. */ -if (!test_bit (PG_mte_tagged, &page->flags)) { +if (!page_mte_tagged (page)) {put_page (page);dump_skip (cprm,MTE_PAGE_TAG_STORAGE );continue ;
arch/arm64/kernel/hibernate.c +1 -1
@@ -271,7 +271,7 @@ static int swsusp_mte_save_tags(void)if (!page)continue ; -if (!test_bit (PG_mte_tagged, &page->flags)) +if (!page_mte_tagged (page))continue ; ret =save_tags (page, pfn);
arch/arm64/kernel/mte.c +11 -6
@@ -41,8 +41,10 @@ static void mte_sync_page_tags(struct paif (check_swap &&is_swap_pte (old_pte)) {swp_entry_t entry =pte_to_swp_entry (old_pte); -if (!non_swap_entry (entry) &&mte_restore_tags (entry, page)) +if (!non_swap_entry (entry) &&mte_restore_tags (entry, page)) { +set_page_mte_tagged (page);return ; + } }if (!pte_is_tagged)
@@ -52,8 +54,10 @@ static void mte_sync_page_tags(struct pa* Test PG_mte_tagged again in case it was racing with another * set_pte_at(). */ -if (!test_and_set_bit (PG_mte_tagged, &page->flags)) +if (!page_mte_tagged (page)) {mte_clear_page_tags (page_address (page)); +set_page_mte_tagged (page); + } }void mte_sync_tags (pte_t old_pte,pte_t pte)
@@ -69,9 +73,11 @@ void mte_sync_tags(pte_t old_pte, pte_t/* if PG_mte_tagged is set, tags have already been initialised */ for (i =0 ; i < nr_pages; i++, page++) { -if (!test_bit (PG_mte_tagged, &page->flags)) +if (!page_mte_tagged (page)) {mte_sync_page_tags (page, old_pte, check_swap, pte_is_tagged); +set_page_mte_tagged (page); + } }/* ensure the tags are visible before the PTE is set */
@@ -96,8 +102,7 @@ int memcmp_pages(struct page *page1, str* pages is tagged, set_pte_at() may zero or change the tags of the * other page via mte_sync_tags(). */ -if (test_bit (PG_mte_tagged, &page1->flags) || -test_bit (PG_mte_tagged, &page2->flags)) +if (page_mte_tagged (page1) ||page_mte_tagged (page2))return addr1 != addr2;return ret;
@@ -454,7 +459,7 @@ static int __access_remote_tags(struct mput_page (page);break ; } -WARN_ON_ONCE (!test_bit (PG_mte_tagged, &page->flags)); +WARN_ON_ONCE (!page_mte_tagged (page));/* limit access to the end of the page */ offset =offset_in_page (addr);
arch/arm64/kvm/guest.c +2 -2
@@ -1059,7 +1059,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct k maddr =page_address (page);if (!write) { -if (test_bit (PG_mte_tagged, &page->flags)) +if (page_mte_tagged (page)) num_tags =mte_copy_tags_to_user (tags, maddr,MTE_GRANULES_PER_PAGE );else
@@ -1076,7 +1076,7 @@ long kvm_vm_ioctl_mte_copy_tags(struct k* completed fully */ if (num_tags ==MTE_GRANULES_PER_PAGE ) -set_bit (PG_mte_tagged, &page->flags); +set_page_mte_tagged (page);kvm_release_pfn_dirty (pfn); }
arch/arm64/kvm/mmu.c +2 -2
@@ -1110,9 +1110,9 @@ static int sanitise_mte_tags(struct kvmreturn -EFAULT ;for (i =0 ; i < nr_pages; i++, page++) { -if (!test_bit (PG_mte_tagged, &page->flags)) { +if (!page_mte_tagged (page)) {mte_clear_page_tags (page_address (page)); -set_bit (PG_mte_tagged, &page->flags); +set_page_mte_tagged (page); } }
arch/arm64/mm/copypage.c +3 -2
@@ -21,9 +21,10 @@ void copy_highpage(struct page *to, strucopy_page (kto, kfrom); -if (system_supports_mte () &&test_bit (PG_mte_tagged, &from->flags)) { -set_bit (PG_mte_tagged, &to->flags); +if (system_supports_mte () &&page_mte_tagged (from)) { +page_kasan_tag_reset (to);mte_copy_page_tags (kto, kfrom); +set_page_mte_tagged (to); } }EXPORT_SYMBOL (copy_highpage);
arch/arm64/mm/fault.c +1 -1
@@ -944,5 +944,5 @@ struct page *alloc_zeroed_user_highpage_void tag_clear_highpage (struct page *page) {mte_zero_clear_page_tags (page_address (page)); -set_bit (PG_mte_tagged, &page->flags); +set_page_mte_tagged (page); }
arch/arm64/mm/mteswap.c +1 -1
@@ -24,7 +24,7 @@ int mte_save_tags(struct page *page) {void *tag_storage, *ret; -if (!test_bit (PG_mte_tagged, &page->flags)) +if (!page_mte_tagged (page))return 0 ; tag_storage =mte_allocate_tag_storage ();
Greg Kroah-Hartman
maintainerPATCH 199/200 arm64: Reset KASAN tag in copy_highpage with HW tags only
In reply to Greg Kroah-HartmanFrom: Peter Collingbourne <[email protected]>
commit e74a68468062d7ebd8ce17069e12ccc64cc6a58c upstream.
During page migration, the copy_highpage function is used to copy the page data to the target page. If the source page is a userspace page with MTE tags, the KASAN tag of the target page must have the match-all tag in order to avoid tag check faults during subsequent accesses to the page by the kernel. However, the target page may have been allocated in a number of ways, some of which will use the KASAN allocator and will therefore end up setting the KASAN tag to a non-match-all tag. Therefore, update the target page's KASAN tag to match the source page.
We ended up unintentionally fixing this issue as a result of a bad merge conflict resolution between commit e059853d14ca ("arm64: mte:
Fix/clarify the PG_mte_tagged semantics") and commit 20794545c146 ("arm64:
kasan: Revert "arm64: mte: reset the page tag in page->flags""), which preserved a tag reset for PG_mte_tagged pages which was considered to be unnecessary at the time. Because SW tags KASAN uses separate tag storage, update the code to only reset the tags when HW tags KASAN is enabled.
--- arch/arm64/mm/copypage.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/mm/copypage.c +2 -1
@@ -22,7 +22,8 @@ void copy_highpage(struct page *to, strucopy_page (kto, kfrom);if (system_supports_mte () &&page_mte_tagged (from)) { -page_kasan_tag_reset (to); +if (kasan_hw_tags_enabled ()) +page_kasan_tag_reset (to);mte_copy_page_tags (kto, kfrom);set_page_mte_tagged (to); }
Greg Kroah-Hartman
maintainerPATCH 200/200 usb: gadget: uvc: fix missing mutex_unlock() if kstrtou8() fails
In reply to Greg Kroah-HartmanFrom: Yang Yingliang <[email protected]>
commit 7ebb605d2283fb2647b4fa82030307ce00bee436 upstream.
If kstrtou8() fails, the mutex_unlock() is missed, move kstrtou8() before mutex_lock() to fix it up.
--- drivers/usb/gadget/function/uvc_configfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/uvc_configfs.c +4 -4
@@ -524,6 +524,10 @@ static ssize_t uvcg_default_output_b_souint result;u8 num; + result =kstrtou8 (page,0 , &num); +if (result) +return result; +mutex_lock (su_mutex);/* for navigating configfs hierarchy */ opts_item = group->cg_item.ci_parent->ci_parent->
@@ -531,10 +535,6 @@ static ssize_t uvcg_default_output_b_sou opts =to_f_uvc_opts (opts_item); cd = &opts->uvc_output_terminal; - result =kstrtou8 (page,0 , &num); -if (result) -return result; -mutex_lock (&opts->lock); cd->bSourceID = num;mutex_unlock (&opts->lock);
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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 Sun, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.17-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Hi Greg
6.1.17-rc1
compiles, boots and runs here on x86_64
(AMD Ryzen 5 PRO 4650G, Slackware64-15.0)
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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 Sun, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.17-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.1:
11 builds: 11 pass, 0 fail
28 boots: 28 pass, 0 fail
130 tests: 130 pass, 0 failLinux version: 6.1.17-rc1-gf345f456043c
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000,
tegra20-ventana, tegra210-p2371-2180,
tegra210-p3450-0000, tegra30-cardhu-a04Jon
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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 Sun, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 9 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.17-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
thanks,
-- Shuah
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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 Sun, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
Build results:
total: 155 pass: 155 fail: 0 Qemu test results: total: 516 pass: 516 fail: 0
Guenter
Quoted 5 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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) and powerpc (ps3_defconfig, GCC 12.2.0).
Signature · 1 line
An old man doll... just what I always wanted! - Clara
Quoted 10 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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 Sun, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.17-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.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.
## Build
* kernel: 6.1.17-rc1
* git: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc
* git branch: linux-6.1.y
* git commit: f345f456043c26b6a0d011d779ae746c16a9f8f1
* git describe: v6.1.16-201-gf345f456043c
* test details:
https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.1.y/build/v6.1.16-201-gf345f456043c
## Test Regressions (compared to v6.1.16)
## Metric Regressions (compared to v6.1.16)
## Test Fixes (compared to v6.1.16)
## Metric Fixes (compared to v6.1.16)
## Test result summary
total: 166217, pass: 146661, fail: 5029, skip: 14499, xfail: 28
## Build Summary
* arc: 5 total, 5 passed, 0 failed
* arm: 149 total, 148 passed, 1 failed
* arm64: 51 total, 50 passed, 1 failed
* i386: 39 total, 36 passed, 3 failed
* mips: 30 total, 28 passed, 2 failed
* parisc: 8 total, 8 passed, 0 failed
* powerpc: 38 total, 36 passed, 2 failed
* riscv: 16 total, 15 passed, 1 failed
* s390: 16 total, 16 passed, 0 failed
* sh: 14 total, 12 passed, 2 failed
* sparc: 8 total, 8 passed, 0 failed
* x86_64: 44 total, 44 passed, 0 failed
## Test suites summary
* boot
* fwts
* igt-gpu-tools
* kselftest-android
* kselftest-arm64
* kselftest-breakpoints
* kselftest-capabilities
* kselftest-cgroup
* kselftest-clone3
* kselftest-core
* kselftest-cpu-hotplug
* kselftest-cpufreq
* kselftest-drivers-dma-buf
* kselftest-efivarfs
* kselftest-filesystems
* kselftest-filesystems-binderfs
* kselftest-firmware
* kselftest-fpu
* kselftest-ftrace
* kselftest-futex
* kselftest-gpio
* kselftest-intel_pstate
* kselftest-ipc
* kselftest-ir
* kselftest-kcmp
* kselftest-kexec
* kselftest-kvm
* kselftest-lib
* kselftest-livepatch
* kselftest-membarrier
* kselftest-memfd
* kselftest-memory-hotplug
* kselftest-mincore
* kselftest-mount
* kselftest-mqueue
* kselftest-net
* kselftest-net-forwarding
* kselftest-net-mptcp
* kselftest-netfilter
* kselftest-nsfs
* kselftest-openat2
* kselftest-pid_namespace
* kselftest-pidfd
* kselftest-proc
* kselftest-pstore
* kselftest-ptrace
* kselftest-rseq
* kselftest-rtc
* kselftest-seccomp
* kselftest-sigaltstack
* kselftest-size
* kselftest-splice
* kselftest-static_keys
* kselftest-sync
* kselftest-sysctl
* kselftest-tc-testing
* kselftest-timens
* kselftest-timers
* kselftest-tmpfs
* kselftest-tpm2
* kselftest-user
* kselftest-vm
* kselftest-x86
* kselftest-zram
* kunit
* kvm-unit-tests
* libgpiod
* libhugetlbfs
* log-parser-boot
* log-parser-test
* ltp-cap_bounds
* ltp-commands
* ltp-containers
* ltp-controllers
* ltp-cpuhotplug
* ltp-crypto
* ltp-cve
* ltp-dio
* ltp-fcntl-locktests
* ltp-filecaps
* ltp-fs
* ltp-fs_bind
* ltp-fs_perms_simple
* ltp-fsx
* ltp-hugetlb
* ltp-io
* ltp-ipc
* ltp-math
* ltp-mm
* ltp-nptl
* ltp-open-posix-tests
* ltp-pty
* ltp-sched
* ltp-securebits
* ltp-smoke
* ltp-syscalls
* ltp-tracing
* network-basic-tests
* packetdrill
* perf
* rcutorture
* v4l2-compliance
* vdso
--
Linaro LKFT
https://lkft.linaro.org
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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.
And no complaints here either!
Thanks,
Conor.
Hi Greg,
Quoted 7 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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 Sun, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
Build test (gcc version 12.2.1 20230210):
mips: 52 configs -> no failure
arm: 100 configs -> no failure
arm64: 3 configs -> no failurex86_64: 4 configs -> no failure alpha allmodconfig -> no failure csky allmodconfig -> no failure powerpc allmodconfig -> no failure riscv allmodconfig -> no failure s390 allmodconfig -> no failure xtensa allmodconfig -> no failure
Boot test:x86_64: Booted on my test laptop. No regression.x86_64: Booted on qemu. No regression. [1]
[1]. https://openqa.qa.codethink.co.uk/tests/3076
Signature · 2 lines
Regards Sudip
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.1.17 release. There are 200 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 Sun, 12 Mar 2023 13:36:38 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.1.17-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.1.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian