Commit Graph

19 Commits

Author SHA1 Message Date
Vadim Pasternak
8c2eb7b646 platform/mellanox: mlxreg-hotplug: Add devm_free_irq call to remove flow
Add devm_free_irq() call to mlxreg-hotplug remove() for clean release
of devices irq resource. Fix debugobjects warning triggered by rmmod
It prevents of use-after-free memory, related to
mlxreg_hotplug_work_handler.

Issue has been reported as debugobjects warning triggered by
'rmmod mlxtreg-hotplug' flow, while running kernel with
CONFIG_DEBUG_OBJECTS* options.

[ 2489.623551] ODEBUG: free active (active state 0) object type: work_struct hint: mlxreg_hotplug_work_handler+0x0/0x7f0 [mlxreg_hotplug]
[ 2489.637097] WARNING: CPU: 5 PID: 3924 at lib/debugobjects.c:328 debug_print_object+0xfe/0x180
[ 2489.637165] RIP: 0010:debug_print_object+0xfe/0x180
?
[ 2489.637214] Call Trace:
[ 2489.637225]  __debug_check_no_obj_freed+0x25e/0x320
[ 2489.637231]  kfree+0x82/0x110
[ 2489.637238]  release_nodes+0x33c/0x4e0
[ 2489.637242]  ? devres_remove_group+0x1b0/0x1b0
[ 2489.637247]  device_release_driver_internal+0x146/0x270
[ 2489.637251]  driver_detach+0x73/0xe0
[ 2489.637254]  bus_remove_driver+0xa1/0x170
[ 2489.637261]  __x64_sys_delete_module+0x29e/0x320
[ 2489.637265]  ? __ia32_sys_delete_module+0x320/0x320
[ 2489.637268]  ? blkcg_exit_queue+0x20/0x20
[ 2489.637273]  ? task_work_run+0x7d/0x100
[ 2489.637278]  ? exit_to_usermode_loop+0x5b/0xf0
[ 2489.637281]  do_syscall_64+0x73/0x160
[ 2489.637287]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 2489.637290] RIP: 0033:0x7f95c3596fd7

The difference in release flow with and with no devm_free_irq is listed
below:

bus: 'platform': remove driver mlxreg-hotplug
 mlxreg_hotplug_remove(start)
					-> devm_free_irq (with new code)
 mlxreg_hotplug_remove (end)
 release_nodes (start)
  mlxreg-hotplug: DEVRES REL devm_hwmon_release (8 bytes)
  device: 'hwmon3': device_unregister
  PM: Removing info for No Bus:hwmon3
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (88 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (6 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (5 bytes)
  mlxreg-hotplug: DEVRES REL devm_irq_release (16 bytes) (no new code)
  mlxreg-hotplug: DEVRES REL devm_kzalloc_release (1376 bytes)
   ------------[ cut here ]------------ (no new code):
   ODEBUG: free active (active state 0) object type: work_struct hint: mlxreg_hotplug_work_handler

 release_nodes(end)
driver: 'mlxreg-hotplug': driver_release

Fixes: 1f976f6978 ("platform/x86: Move Mellanox platform hotplug driver to platform/mellanox")
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
2019-06-12 11:49:20 +03:00
Vadim Pasternak
e4c275f776 platform/mellanox: mlxreg-hotplug: Fix KASAN warning
Fix the following KASAN warning produced when booting a 64-bit kernel:
[   13.334750] BUG: KASAN: stack-out-of-bounds in find_first_bit+0x19/0x70
[   13.342166] Read of size 8 at addr ffff880235067178 by task kworker/2:1/42
[   13.342176] CPU: 2 PID: 42 Comm: kworker/2:1 Not tainted 4.20.0-rc1+ #106
[   13.342179] Hardware name: Mellanox Technologies Ltd. MSN2740/Mellanox x86 SFF board, BIOS 5.6.5 06/07/2016
[   13.342190] Workqueue: events deferred_probe_work_func
[   13.342194] Call Trace:
[   13.342206]  dump_stack+0xc7/0x15b
[   13.342214]  ? show_regs_print_info+0x5/0x5
[   13.342220]  ? kmsg_dump_rewind_nolock+0x59/0x59
[   13.342234]  ? _raw_write_lock_irqsave+0x100/0x100
[   13.351593]  print_address_description+0x73/0x260
[   13.351603]  kasan_report+0x260/0x380
[   13.351611]  ? find_first_bit+0x19/0x70
[   13.351619]  find_first_bit+0x19/0x70
[   13.351630]  mlxreg_hotplug_work_handler+0x73c/0x920 [mlxreg_hotplug]
[   13.351639]  ? __lock_text_start+0x8/0x8
[   13.351646]  ? _raw_write_lock_irqsave+0x80/0x100
[   13.351656]  ? mlxreg_hotplug_remove+0x1e0/0x1e0 [mlxreg_hotplug]
[   13.351663]  ? regmap_volatile+0x40/0xb0
[   13.351668]  ? regcache_write+0x4c/0x90
[   13.351676]  ? mlxplat_mlxcpld_reg_write+0x24/0x30 [mlx_platform]
[   13.351681]  ? _regmap_write+0xea/0x220
[   13.351688]  ? __mutex_lock_slowpath+0x10/0x10
[   13.351696]  ? devm_add_action+0x70/0x70
[   13.351701]  ? mutex_unlock+0x1d/0x40
[   13.351710]  mlxreg_hotplug_probe+0x82e/0x989 [mlxreg_hotplug]
[   13.351723]  ? mlxreg_hotplug_work_handler+0x920/0x920 [mlxreg_hotplug]
[   13.351731]  ? sysfs_do_create_link_sd.isra.2+0xf4/0x190
[   13.351737]  ? sysfs_rename_link_ns+0xf0/0xf0
[   13.351743]  ? devres_close_group+0x2b0/0x2b0
[   13.351749]  ? pinctrl_put+0x20/0x20
[   13.351755]  ? acpi_dev_pm_attach+0x2c/0xd0
[   13.351763]  platform_drv_probe+0x70/0xd0
[   13.351771]  really_probe+0x480/0x6e0
[   13.351778]  ? device_attach+0x10/0x10
[   13.351784]  ? __lock_text_start+0x8/0x8
[   13.351790]  ? _raw_write_lock_irqsave+0x80/0x100
[   13.351797]  ? _raw_write_lock_irqsave+0x80/0x100
[   13.351806]  ? __driver_attach+0x190/0x190
[   13.351812]  driver_probe_device+0x17d/0x1a0
[   13.351819]  ? __driver_attach+0x190/0x190
[   13.351825]  bus_for_each_drv+0xd6/0x130
[   13.351831]  ? bus_rescan_devices+0x20/0x20
[   13.351837]  ? __mutex_lock_slowpath+0x10/0x10
[   13.351845]  __device_attach+0x18c/0x230
[   13.351852]  ? device_bind_driver+0x70/0x70
[   13.351859]  ? __mutex_lock_slowpath+0x10/0x10
[   13.351866]  bus_probe_device+0xea/0x110
[   13.351874]  deferred_probe_work_func+0x1c9/0x290
[   13.351882]  ? driver_deferred_probe_add+0x1d0/0x1d0
[   13.351889]  ? preempt_notifier_dec+0x20/0x20
[   13.351897]  ? read_word_at_a_time+0xe/0x20
[   13.351904]  ? strscpy+0x151/0x290
[   13.351912]  ? set_work_pool_and_clear_pending+0x9c/0xf0
[   13.351918]  ? __switch_to_asm+0x34/0x70
[   13.351924]  ? __switch_to_asm+0x40/0x70
[   13.351929]  ? __switch_to_asm+0x34/0x70
[   13.351935]  ? __switch_to_asm+0x40/0x70
[   13.351942]  process_one_work+0x5cc/0xa00
[   13.351952]  ? pwq_dec_nr_in_flight+0x1e0/0x1e0
[   13.351960]  ? pci_mmcfg_check_reserved+0x80/0xb8
[   13.351967]  ? run_rebalance_domains+0x250/0x250
[   13.351980]  ? stack_access_ok+0x35/0x80
[   13.351986]  ? deref_stack_reg+0xa1/0xe0
[   13.351994]  ? schedule+0xcd/0x250
[   13.352000]  ? worker_enter_idle+0x2d6/0x330
[   13.352006]  ? __schedule+0xeb0/0xeb0
[   13.352014]  ? fork_usermode_blob+0x130/0x130
[   13.352019]  ? mutex_lock+0xa7/0x100
[   13.352026]  ? _raw_spin_lock_irq+0x98/0xf0
[   13.352032]  ? _raw_read_unlock_irqrestore+0x30/0x30
[   13.352037] i2c i2c-2: Added multiplexed i2c bus 11
[   13.352043]  worker_thread+0x181/0xa80
[   13.352052]  ? __switch_to_asm+0x34/0x70
[   13.352058]  ? __switch_to_asm+0x40/0x70
[   13.352064]  ? process_one_work+0xa00/0xa00
[   13.352070]  ? __switch_to_asm+0x34/0x70
[   13.352076]  ? __switch_to_asm+0x40/0x70
[   13.352081]  ? __switch_to_asm+0x34/0x70
[   13.352086]  ? __switch_to_asm+0x40/0x70
[   13.352092]  ? __switch_to_asm+0x34/0x70
[   13.352097]  ? __switch_to_asm+0x40/0x70
[   13.352105]  ? __schedule+0x3d6/0xeb0
[   13.352112]  ? migrate_swap_stop+0x470/0x470
[   13.352119]  ? save_stack+0x89/0xb0
[   13.352127]  ? kmem_cache_alloc_trace+0xe5/0x570
[   13.352132]  ? kthread+0x59/0x1d0
[   13.352138]  ? ret_from_fork+0x35/0x40
[   13.352154]  ? __schedule+0xeb0/0xeb0
[   13.352161]  ? remove_wait_queue+0x150/0x150
[   13.352169]  ? _raw_write_lock_irqsave+0x80/0x100
[   13.352175]  ? __lock_text_start+0x8/0x8
[   13.352183]  ? process_one_work+0xa00/0xa00
[   13.352188]  kthread+0x1a4/0x1d0
[   13.352195]  ? kthread_create_worker_on_cpu+0xc0/0xc0
[   13.352202]  ret_from_fork+0x35/0x40

[   13.353879] The buggy address belongs to the page:
[   13.353885] page:ffffea0008d419c0 count:0 mapcount:0 mapping:0000000000000000 index:0x0
[   13.353890] flags: 0x2ffff8000000000()
[   13.353897] raw: 02ffff8000000000 ffffea0008d419c8 ffffea0008d419c8 0000000000000000
[   13.353903] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[   13.353905] page dumped because: kasan: bad access detected

[   13.353908] Memory state around the buggy address:
[   13.353912]  ffff880235067000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   13.353917]  ffff880235067080: 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04
[   13.353921] >ffff880235067100: f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 f2 f2 f2 f2 04
[   13.353923]                                                                 ^
[   13.353927]  ffff880235067180: f2 f2 f2 f2 f2 f2 f2 04 f2 f2 f2 00 00 00 00 00
[   13.353931]  ffff880235067200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   13.353933] ==================================================================

The warning is caused by the below loop:
	for_each_set_bit(bit, (unsigned long *)&asserted, 8) {
while "asserted" is declared as 'unsigned'.

The casting of 32-bit unsigned integer pointer to a 64-bit unsigned long
pointer. There are two problems here.
It causes the access of four extra byte, which can corrupt memory
The 32-bit pointer address may not be 64-bit aligned.

The fix changes variable "asserted" to "unsigned long".

Fixes: 1f976f6978 ("platform/x86: Move Mellanox platform hotplug driver to platform/mellanox")
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2019-02-23 09:20:32 -08:00
Vadim Pasternak
83cdb2c111 platform/x86: mlx-platform: Add support for fan capability registers
Provide support for the fan capability registers for the next generation
systems of types MQM87xx, MSN34xx, MSN37xx. These new registers provide
configuration for tachometers and fan drawers connectivity.  Use these
registers for next generation led, fan and hotplug structures in order
to distinguish between the systems which have minor configuration
differences. This reduces the amount of code used to describe such
systems.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2019-01-26 11:08:25 -08:00
Vadim Pasternak
9272d2d1d3 platform/mellanox: mlxreg-hotplug: Add hotplug hwmon uevent notification
Notify user when hotplug device signal is received in order to allow user
to handle such case, if it wishes to take some action on this matter.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-08-01 17:41:31 -07:00
Vadim Pasternak
66342d1c9c platform/mellanox: mlxreg-hotplug: Improve mechanism of ASIC health discovery
Simplify the logic of ASIC health discovery.
ASIC device can indicate its health state as a good, booting or dormant.
During ASIC reset the device is dropped to dormant state and should get to
the stable good health state through the intermediate booting state.
The sequence for getting to the steady state health after reset is:
(dormant -> booting -> good)+.
Initial implementation assumes that ?good? within this sequence is always
repeated twice and device is getting steady state only after the second
?good?. This patch removes this dependency, since the second ?good? is
received because of the noise on line and can be ignored. Device reaches
steady state after the first ?good? is received.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-08-01 17:41:31 -07:00
Linus Torvalds
f3b5020e16 platform-drivers-x86 for v4.18-1
Several incremental improvements including new keycodes, new models, new
 quirks, and related documentation. Adds LED platform driver activation
 for Mellanox systems.  Some minor optimizations and cleanups. Includes
 several bug fixes, message silencing, mostly minor.
 
 The following commits were previously merged during the 4.17 RC cycle:
  - 06b8b00b33 platform/x86: asus-wireless: Fix NULL pointer dereference
  - 6ed66c3ce0 platform/x86: Kconfig: Fix dell-laptop dependency chain.
  - 74783c99bf platform/x86: DELL_WMI use depends on instead of select for DELL_SMBIOS
  - cf48bf9eee platform/x86: asus-wmi: Fix NULL pointer dereference
 
 The following is an automated git shortlog grouped by driver:
 
 acer-wmi:
  -  add another KEY_POWER keycode
 
 apple-gmux:
  -  fix gmux_get_client_id()'s return type
 
 asus-laptop:
  -  Simplify getting .drvdata
 
 asus-wireless:
  -  Fix format specifier
 
 dell-laptop:
  -  Fix keyboard backlight timeout on XPS 13 9370
 
 dell-smbios:
  -  Match on www.dell.com in OEM strings too
 
 dell-wmi:
  -  Ignore new rfkill and fn-lock events
  -  Set correct keycode for Fn + left arrow
 
 fujitsu-laptop:
  -  Simplify soft key handling
 
 ideapad-laptop:
  -  Add E42-80 to no_hw_rfkill
  -  Add fn-lock setting
  -  Add MIIX 720-12IKB to no_hw_rfkill
 
 lib/string_helpers:
  -  Add missed declaration of struct task_struct
 
 intel_scu_ipc:
  -  Replace mdelay with usleep_range in intel_scu_ipc_i2c_cntrl
 
 mlx-platform:
  -  Add LED platform driver activation
 
 platform/mellanox:
  -  Add new ODM system types to mlx-platform
  -  mlxreg-hotplug: add extra cycle for hotplug work queue
  -  mlxreg-hotplug: Document fixes for hotplug private data
 
 platform_data/mlxreg:
  -  Document fixes for hotplug device
 
 silead_dmi:
  -  Add entry for Chuwi Hi8 tablet touchscreen
  -  Add touchscreen info for the Onda V891w tablet
  -  Add info for the PoV mobii TAB-P800W (v2.0)
  -  Add touchscreen info for the Jumper EZpad 6 Pro
 
 thinkpad_acpi:
  -  silence false-positive-prone pr_warn
  -  do not report thermal sensor state for tablet mode switch
  -  silence HKEY 0x6032, 0x60f0, 0x6030
 -----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJbIFzqAAoJEKbMaAwKp3644JcIAJ8iBMobacNWjIJvPJ8ytwLE
 NUP7/W/8NUXkwnxXzURorlnoO6Uj4+54c+QfO+HQV/+Y46fJaX9x2tWRtcEkpJU3
 L6c59kYAMlu5rN5ekCcQex4FKL8Pd7q6QpF8KZtP8gw2ujUEeGA1m/qcTmUlkOQF
 AFfbSFJtmMOinbL5ufkaW7Gu91EVFhuvgIoK/XdOhwAbyYAPEbtttKlUjkZGx6GU
 iJbpimcmdtfXBqMzvpOHw/4EUXLwgDVr1F8PdGmvEHyK45SHIZcK936Ihiq+CjVA
 USFKZhMMYU4sifI77pIP9Trftm+FdaLnPumGVj836OMp1+k10YBy1hDIGwI6i68=
 =+O74
 -----END PGP SIGNATURE-----

Merge tag 'platform-drivers-x86-v4.18-1' of git://git.infradead.org/linux-platform-drivers-x86

Pull x86 platform driver updates from Darren Hart:
 "Several incremental improvements including new keycodes, new models,
  new quirks, and related documentation. Adds LED platform driver
  activation for Mellanox systems. Some minor optimizations and
  cleanups. Includes several bug fixes, message silencing, mostly minor

  Automated summary:

  acer-wmi:
   -  add another KEY_POWER keycode

  apple-gmux:
   -  fix gmux_get_client_id()'s return type

  asus-laptop:
   -  Simplify getting .drvdata

  asus-wireless:
   -  Fix format specifier

  dell-laptop:
   -  Fix keyboard backlight timeout on XPS 13 9370

  dell-smbios:
   -  Match on www.dell.com in OEM strings too

  dell-wmi:
   -  Ignore new rfkill and fn-lock events
   -  Set correct keycode for Fn + left arrow

  fujitsu-laptop:
   -  Simplify soft key handling

  ideapad-laptop:
   -  Add E42-80 to no_hw_rfkill
   -  Add fn-lock setting
   -  Add MIIX 720-12IKB to no_hw_rfkill

  lib/string_helpers:
   -  Add missed declaration of struct task_struct

  intel_scu_ipc:
   -  Replace mdelay with usleep_range in intel_scu_ipc_i2c_cntrl

  mlx-platform:
   -  Add LED platform driver activation

  platform/mellanox:
   -  Add new ODM system types to mlx-platform
   -  mlxreg-hotplug: add extra cycle for hotplug work queue
   -  mlxreg-hotplug: Document fixes for hotplug private data

  platform_data/mlxreg:
   -  Document fixes for hotplug device

  silead_dmi:
   -  Add entry for Chuwi Hi8 tablet touchscreen
   -  Add touchscreen info for the Onda V891w tablet
   -  Add info for the PoV mobii TAB-P800W (v2.0)
   -  Add touchscreen info for the Jumper EZpad 6 Pro

  thinkpad_acpi:
   -  silence false-positive-prone pr_warn
   -  do not report thermal sensor state for tablet mode switch
   -  silence HKEY 0x6032, 0x60f0, 0x6030"

* tag 'platform-drivers-x86-v4.18-1' of git://git.infradead.org/linux-platform-drivers-x86: (30 commits)
  platform/x86: silead_dmi: Add entry for Chuwi Hi8 tablet touchscreen
  platform/x86: dell-laptop: Fix keyboard backlight timeout on XPS 13 9370
  platform/x86: dell-wmi: Ignore new rfkill and fn-lock events
  platform/x86: mlx-platform: Add LED platform driver activation
  platform/mellanox: Add new ODM system types to mlx-platform
  platform/mellanox: mlxreg-hotplug: add extra cycle for hotplug work queue
  platform/x86: ideapad-laptop: Add E42-80 to no_hw_rfkill
  platform/x86: silead_dmi: Add touchscreen info for the Onda V891w tablet
  platform/x86: silead_dmi: Add info for the PoV mobii TAB-P800W (v2.0)
  platform/x86: silead_dmi: Add touchscreen info for the Jumper EZpad 6 Pro
  platform/x86: asus-wireless: Fix format specifier
  platform/x86: asus-wmi: Fix NULL pointer dereference
  platform/x86: dell-wmi: Set correct keycode for Fn + left arrow
  platform/x86: acer-wmi: add another KEY_POWER keycode
  platform/x86: ideapad-laptop: Add fn-lock setting
  platform/x86: ideapad-laptop: Add MIIX 720-12IKB to no_hw_rfkill
  lib/string_helpers: Add missed declaration of struct task_struct
  platform/x86: DELL_WMI use depends on instead of select for DELL_SMBIOS
  platform/mellanox: mlxreg-hotplug: Document fixes for hotplug private data
  platform_data/mlxreg: Document fixes for hotplug device
  ...
2018-06-14 16:30:30 +09:00
Kees Cook
a86854d0c5 treewide: devm_kzalloc() -> devm_kcalloc()
The devm_kzalloc() function has a 2-factor argument form, devm_kcalloc().
This patch replaces cases of:

        devm_kzalloc(handle, a * b, gfp)

with:
        devm_kcalloc(handle, a * b, gfp)

as well as handling cases of:

        devm_kzalloc(handle, a * b * c, gfp)

with:

        devm_kzalloc(handle, array3_size(a, b, c), gfp)

as it's slightly less ugly than:

        devm_kcalloc(handle, array_size(a, b), c, gfp)

This does, however, attempt to ignore constant size factors like:

        devm_kzalloc(handle, 4 * 1024, gfp)

though any constants defined via macros get caught up in the conversion.

Any factors with a sizeof() of "unsigned char", "char", and "u8" were
dropped, since they're redundant.

Some manual whitespace fixes were needed in this patch, as Coccinelle
really liked to write "=devm_kcalloc..." instead of "= devm_kcalloc...".

The Coccinelle script used for this was:

// Fix redundant parens around sizeof().
@@
expression HANDLE;
type TYPE;
expression THING, E;
@@

(
  devm_kzalloc(HANDLE,
-	(sizeof(TYPE)) * E
+	sizeof(TYPE) * E
  , ...)
|
  devm_kzalloc(HANDLE,
-	(sizeof(THING)) * E
+	sizeof(THING) * E
  , ...)
)

// Drop single-byte sizes and redundant parens.
@@
expression HANDLE;
expression COUNT;
typedef u8;
typedef __u8;
@@

(
  devm_kzalloc(HANDLE,
-	sizeof(u8) * (COUNT)
+	COUNT
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(__u8) * (COUNT)
+	COUNT
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(char) * (COUNT)
+	COUNT
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(unsigned char) * (COUNT)
+	COUNT
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(u8) * COUNT
+	COUNT
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(__u8) * COUNT
+	COUNT
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(char) * COUNT
+	COUNT
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(unsigned char) * COUNT
+	COUNT
  , ...)
)

// 2-factor product with sizeof(type/expression) and identifier or constant.
@@
expression HANDLE;
type TYPE;
expression THING;
identifier COUNT_ID;
constant COUNT_CONST;
@@

(
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(TYPE) * (COUNT_ID)
+	COUNT_ID, sizeof(TYPE)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(TYPE) * COUNT_ID
+	COUNT_ID, sizeof(TYPE)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(TYPE) * (COUNT_CONST)
+	COUNT_CONST, sizeof(TYPE)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(TYPE) * COUNT_CONST
+	COUNT_CONST, sizeof(TYPE)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(THING) * (COUNT_ID)
+	COUNT_ID, sizeof(THING)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(THING) * COUNT_ID
+	COUNT_ID, sizeof(THING)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(THING) * (COUNT_CONST)
+	COUNT_CONST, sizeof(THING)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(THING) * COUNT_CONST
+	COUNT_CONST, sizeof(THING)
  , ...)
)

// 2-factor product, only identifiers.
@@
expression HANDLE;
identifier SIZE, COUNT;
@@

- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	SIZE * COUNT
+	COUNT, SIZE
  , ...)

// 3-factor product with 1 sizeof(type) or sizeof(expression), with
// redundant parens removed.
@@
expression HANDLE;
expression THING;
identifier STRIDE, COUNT;
type TYPE;
@@

(
  devm_kzalloc(HANDLE,
-	sizeof(TYPE) * (COUNT) * (STRIDE)
+	array3_size(COUNT, STRIDE, sizeof(TYPE))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(TYPE) * (COUNT) * STRIDE
+	array3_size(COUNT, STRIDE, sizeof(TYPE))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(TYPE) * COUNT * (STRIDE)
+	array3_size(COUNT, STRIDE, sizeof(TYPE))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(TYPE) * COUNT * STRIDE
+	array3_size(COUNT, STRIDE, sizeof(TYPE))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(THING) * (COUNT) * (STRIDE)
+	array3_size(COUNT, STRIDE, sizeof(THING))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(THING) * (COUNT) * STRIDE
+	array3_size(COUNT, STRIDE, sizeof(THING))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(THING) * COUNT * (STRIDE)
+	array3_size(COUNT, STRIDE, sizeof(THING))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(THING) * COUNT * STRIDE
+	array3_size(COUNT, STRIDE, sizeof(THING))
  , ...)
)

// 3-factor product with 2 sizeof(variable), with redundant parens removed.
@@
expression HANDLE;
expression THING1, THING2;
identifier COUNT;
type TYPE1, TYPE2;
@@

(
  devm_kzalloc(HANDLE,
-	sizeof(TYPE1) * sizeof(TYPE2) * COUNT
+	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+	array3_size(COUNT, sizeof(TYPE1), sizeof(TYPE2))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(THING1) * sizeof(THING2) * COUNT
+	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(THING1) * sizeof(THING2) * (COUNT)
+	array3_size(COUNT, sizeof(THING1), sizeof(THING2))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(TYPE1) * sizeof(THING2) * COUNT
+	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
  , ...)
|
  devm_kzalloc(HANDLE,
-	sizeof(TYPE1) * sizeof(THING2) * (COUNT)
+	array3_size(COUNT, sizeof(TYPE1), sizeof(THING2))
  , ...)
)

// 3-factor product, only identifiers, with redundant parens removed.
@@
expression HANDLE;
identifier STRIDE, SIZE, COUNT;
@@

(
  devm_kzalloc(HANDLE,
-	(COUNT) * STRIDE * SIZE
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
|
  devm_kzalloc(HANDLE,
-	COUNT * (STRIDE) * SIZE
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
|
  devm_kzalloc(HANDLE,
-	COUNT * STRIDE * (SIZE)
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
|
  devm_kzalloc(HANDLE,
-	(COUNT) * (STRIDE) * SIZE
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
|
  devm_kzalloc(HANDLE,
-	COUNT * (STRIDE) * (SIZE)
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
|
  devm_kzalloc(HANDLE,
-	(COUNT) * STRIDE * (SIZE)
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
|
  devm_kzalloc(HANDLE,
-	(COUNT) * (STRIDE) * (SIZE)
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
|
  devm_kzalloc(HANDLE,
-	COUNT * STRIDE * SIZE
+	array3_size(COUNT, STRIDE, SIZE)
  , ...)
)

// Any remaining multi-factor products, first at least 3-factor products,
// when they're not all constants...
@@
expression HANDLE;
expression E1, E2, E3;
constant C1, C2, C3;
@@

(
  devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
  devm_kzalloc(HANDLE,
-	(E1) * E2 * E3
+	array3_size(E1, E2, E3)
  , ...)
|
  devm_kzalloc(HANDLE,
-	(E1) * (E2) * E3
+	array3_size(E1, E2, E3)
  , ...)
|
  devm_kzalloc(HANDLE,
-	(E1) * (E2) * (E3)
+	array3_size(E1, E2, E3)
  , ...)
|
  devm_kzalloc(HANDLE,
-	E1 * E2 * E3
+	array3_size(E1, E2, E3)
  , ...)
)

// And then all remaining 2 factors products when they're not all constants,
// keeping sizeof() as the second factor argument.
@@
expression HANDLE;
expression THING, E1, E2;
type TYPE;
constant C1, C2, C3;
@@

(
  devm_kzalloc(HANDLE, sizeof(THING) * C2, ...)
|
  devm_kzalloc(HANDLE, sizeof(TYPE) * C2, ...)
|
  devm_kzalloc(HANDLE, C1 * C2 * C3, ...)
|
  devm_kzalloc(HANDLE, C1 * C2, ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(TYPE) * (E2)
+	E2, sizeof(TYPE)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(TYPE) * E2
+	E2, sizeof(TYPE)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(THING) * (E2)
+	E2, sizeof(THING)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	sizeof(THING) * E2
+	E2, sizeof(THING)
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	(E1) * E2
+	E1, E2
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	(E1) * (E2)
+	E1, E2
  , ...)
|
- devm_kzalloc
+ devm_kcalloc
  (HANDLE,
-	E1 * E2
+	E1, E2
  , ...)
)

Signed-off-by: Kees Cook <keescook@chromium.org>
2018-06-12 16:19:22 -07:00
Vadim Pasternak
4b5e32df66 platform/mellanox: mlxreg-hotplug: add extra cycle for hotplug work queue
Add extra cycle for hotplug work queue to handle the case when a signal is
It adds missed logic for signal acknowledge, by adding an extra run for
received, but no specific signal assertion is detected. Such case
theoretically can happen for example in case several units are removed or
inserted at the same time. In this situation acknowledge for some signal
can be missed at signal top aggreagation status level. The extra run will
allow to handler to acknowledge the missed signal.

The interrupt handling flow performs the next steps:
(1)
Enter mlxreg_hotplug_work_handler due to signal assertion.
Aggregation status register is changed for example from 0xff to 0xfd
(event signal group related to bit 1).
(2)
Mask aggregation interrupts, read aggregation status register and save it
(0xfd) in aggr_cache, then traverse down to handle signal from groups
related to the changed bit.
(3)
Read and mask group related signal.
Acknowledge and unmask group related signal (acknowledge should clear
aggregation status register from 0xfd back to 0xff).
(4)
Re-schedule work queue for the immediate execution.
(5)
Enter mlxreg_hotplug_work_handler due to re-scheduling.
Aggregation status is changed from previous 0xfd to 0xff.
Go over steps (2) - (5) and in case no new signal assertion
is detected - unmask aggregation interrupts.

The possible race could happen in case new signal from the same group is
asserted after step (3) and prior step (5). In such case aggregation
status will change back from 0xff to 0xfd and the value read from the
aggregation status register will be the same as a value saved in
aggr_cache. As a result the handler will not traverse down and signal
will stay unhandled.

Example of faulty flow:
The signal routing flow is as following (f.e. for of FANi removing):
 - FAN status and event registers related bit is changed;
 -- intermediate aggregation status register is changed;
 --- top aggregation status register is changed;
 ---- interrupt routed to CPU and interrupt handler is invoked.

When interrupt handler is invoked it follows the next simple logic (f.e
FAN3 is removed):
 (a1) mask top aggregation interrupt mask register;
 (a2) read top aggregation interrupt status register and test to which
      underling group belongs a signal (FANs in this case and is changed
	  from 0xff to 0xfb and 0xfb is saved as a last status value);
   (b1) mask FANs interrupt mask register;
   (b2) read FANs status register and test which FAN has been changed
        FAN3 in this example);
     (c1) perform relevant action;
              <--------------- (FAN2 is removed at this point)
   (b3) clear FANs interrupt event register to acknowledge FAN3 signal;
   (b4) unmask FANs interrupt mask register
 (a3) unmask top aggregation interrupt mask register;

 An interrupt handler is invoked, since FAN2 interrupt is not acknowledge.
 It should set top aggregation interrupt status register bit 6 (0xfb).
 In step (a2)
 (a2) read top aggregation interrupt and comparing it with saved value
      does not show change (same 0xfb) and after (a2) execution jumps to
	  (a3) and signal leaved unhandled

The fix will enforce handler to traverse down in case the signal is
received, but signal assertion is not detected.

Fixes: 304887041d ("platform/x86: Introduce support for Mellanox hotplug driver")
Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-06-01 09:54:34 -07:00
Vadim Pasternak
321089a4da platform/mellanox: mlxreg-hotplug: Document fixes for hotplug private data
Add missing description of dev, regmap, dwork_irq, after_probe in struct
mlxreg_hotplug_priv_data.

Remove dwork field from the structure mlxreg_hotplug_priv_data itself and
for the descriptions, since it is not used.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-05-12 15:38:40 -07:00
Vadim Pasternak
ef0f62264b platform/x86: mlx-platform: Add physical bus number auto detection
mlx-platform does not provide a bus number to i2c-mlxcpld, assuming it
is always one. On some x86 systems, other i2c drivers may probe before
i2c-mlxcpld, causing bus one to be busy.

Make mlx-platform determine which adapter number is free prior to
activating i2c-mlxpld, adjusting the mux base numbers accordingly.
Update the mlxreg-hotplug pdata similarly.

This adds an explicit mlx-platform build dependency on I2C, update the
Kconfig accordingly. Add the missing REGMAP dependency while we're at
it.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
[dvhart: Rewrite commit message more concisely]
[dvhart: Add build dependencies]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-03-23 16:14:29 -07:00
Vadim Pasternak
f709e1bfb0 platform/mellanox: mlxreg-hotplug: Change input for device create routine
Change the first input parameter in mlxreg_hotplug_device_create to the
pointer to mlxreg_hotplug private data in order to use the fields from
the private data structure.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
[dvhart: Cleaned up commit message]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-03-23 16:14:28 -07:00
Vadim Pasternak
d726f6b199 platform/x86: mlx-platform: Add deffered bus functionality
mlx-platform activates i2c-mux-reg, which creates buses needed by
mlxreg-hotplug. If the mlxreg-hotplug probe runs before the i2c-mux-reg
probe completes, it may attempt to connect a device to an adapter number
that has not been created yet, and fail.

Make mlx-platform driver record the highest bus number in mlxreg-hotplug
platform data and defer mlxreg-hotplug probe until all the buses are
created.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
[dvhart: rewrite commit message more concisely]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-03-23 16:14:28 -07:00
Geert Uytterhoeven
b81e830c9a platform/mellanox: mlxreg-hotplug: Fix uninitialized variable
With gcc-4.1.2:

    drivers/platform/mellanox/mlxreg-hotplug.c: In function ‘mlxreg_hotplug_health_work_helper’:
    drivers/platform/mellanox/mlxreg-hotplug.c:347: warning: ‘ret’ is used uninitialized in this function

Indeed, if mlxreg_core_item.count is zero, ret is used uninitialized.

While this is unlikely to happen (it is set to ARRAY_SIZE(...) in x86
board files), this is done in another source file, so fix this by
preinitializing ret to zero.

Fixes: c6acad68eb ("platform/mellanox: mlxreg-hotplug: Modify to use a regmap interface")
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-02-08 17:43:37 -08:00
Vadim Pasternak
7805fa8d78 platform/mellanox: mlxreg-hotplug: Add check for negative adapter number
Verify before creation of hotplug device if the associated adapter number
is negative. It could be in case hotplug event is not associated with
hotplug device.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-01-31 10:36:50 -08:00
Vadim Pasternak
c6acad68eb platform/mellanox: mlxreg-hotplug: Modify to use a regmap interface
Restructure mlxreg header for unification of hotplug item definitions.

Unify hotplug items to allow any kind of item (power controller, fan
eeprom, psu eeprom, asic health) in common way.

Use a hardware independent regmap interface, enabling the support of
hotplug events over programmable devices attached to different bus
types, such as I2C, LPC, or SPI. Add a device node to the
mlxreg_core_data structure.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
[dvhart: spelling corrections, refactor device node introduction]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-01-31 10:36:49 -08:00
Vadim Pasternak
752849e697 platform/mellanox: Group create/destroy with attribute functions
Move the mlxreg_hotplug_device_create and _destroy functions up with the
related attribute functions. No functional changes.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
[dvhart: refactored commit into smaller functional changes]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-01-31 10:36:49 -08:00
Vadim Pasternak
3d838f5514 platform/mellanox: Rename i2c bus to nr
Use Linux convention of nr instead of bus for i2c adapter number.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
[dvhart: refactored commit into smaller functional changes]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-01-31 10:36:49 -08:00
Vadim Pasternak
4abdbfa733 platform/mellanox: mlxreg-hotplug: Remove unused wait.h include
The driver does not make use of anything defined in wait.h.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
[dvhart: refactor into smaller functional changes, leave spinlock.h]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-01-31 10:36:49 -08:00
Vadim Pasternak
1f976f6978 platform/x86: Move Mellanox platform hotplug driver to platform/mellanox
In preparation for making the hotplug driver build for different
architectures, move mlxcpld-hotplug.c to platform/mellanox and the
header to include/linux/platform_data as mlxreg.h to reflect the new
interface changes to come.

Replace references to CPLD with REG throughout the files, consistent
with the new name.

Signed-off-by: Vadim Pasternak <vadimp@mellanox.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
[dvhart: update copyright, rewrite commit message]
Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
2018-01-31 10:36:48 -08:00