summaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_msghandler.c
Commit message (Collapse)AuthorAgeFilesLines
* ipmi: msghandler: Add and use pr_fmt and dev_fmt, remove PFXJoe Perches2018-09-181-27/+24
| | | | | | | | | | | | | | | Standardize the prefixing of output messages using the pr_fmt and dev_fmt mechanisms instead of a separate #define PFX Miscellanea: o Because this message prefix is very long, use a non-standard define of #define pr_fmt(fmt) "%s" fmt, "IPMI message handler: " which removes ~170 bytes of object code in an x86-64 defconfig with ipmi (with even more object code reduction on 32 bit compilations) Signed-off-by: Joe Perches <joe@perches.com> Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Rework SMI registration failureCorey Minyard2018-08-311-23/+30
| | | | | | | | | | | | | | | | | | | | There were certain situations where ipmi_register_smi() would return a failure, but the interface would still be registered and would need to be unregistered. This is obviously a bad design and resulted in an oops in certain failure cases. If the interface is started up in ipmi_register_smi(), then an error occurs, shut down the interface there so the cleanup can be done properly. Fix the various smi users, too. Signed-off-by: Corey Minyard <cminyard@mvista.com> Reported-by: Justin Ernst <justin.ernst@hpe.com> Tested-by: Justin Ernst <justin.ernst@hpe.com> Cc: Andrew Banman <abanman@hpe.com> Cc: Russ Anderson <russ.anderson@hpe.com> Cc: <stable@vger.kernel.org> # 4.18.x
* ipmi: Properly release srcu locks on error conditionsCorey Minyard2018-05-241-18/+25
| | | | | | | When SRCU was added for handling hotplug, some error conditions were not handled properly. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Remove the proc interfaceCorey Minyard2018-05-091-264/+0
| | | | | | It has been deprecated long enough, get rid of it. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: ipmi_unregister_smi() cannot fail, have it return voidCorey Minyard2018-04-181-3/+1
| | | | Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Remove condition on interface shutdownCorey Minyard2018-04-181-2/+1
| | | | | | | Now that the interfaces have shutdown handlers, this no longer needs to be conditional. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Rework locking and shutdown for hot removeCorey Minyard2018-04-181-210/+280
| | | | | | | | | To handle hot remove of interfaces, a lot of rework had to be done to the locking. Several things were switched over to srcu and shutdown for users and interfaces was added for cleaner shutdown. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Fix some counter issuesCorey Minyard2018-04-181-31/+45
| | | | | | | | Counters would not be pegged properly on some errors. Have deliver_response() return an error so the counters can be incremented properly. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Change ipmi_smi_t to struct ipmi_smi *Corey Minyard2018-04-181-87/+91
| | | | | | | Get rid of this coding style violation in the user files. Include files will come later. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Rename ipmi_user_t to struct ipmi_user *Corey Minyard2018-04-181-27/+27
| | | | | | | Get rid of that non-compliance in the user files. Include files will come later. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Clean up some style issues in the message handlerCorey Minyard2018-04-181-48/+35
| | | | Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Break up i_ipmi_requestCorey Minyard2018-04-181-310/+344
| | | | | | It was huge, and easily broken into pieces. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Clean up some debug codeCorey Minyard2018-04-181-33/+25
| | | | | | Replace ifdefs in the code with a simple function. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Add a panic handler for IPMI usersCorey Minyard2018-04-181-110/+104
| | | | | | | | | | | | | | Users of the IPMI code had their own panic handlers, but the order was not necessarily right, the base IPMI code would need to handle the panic first, and the user had no way to know if the IPMI interface could run at panic time. Add a panic handler to the user interface, it is called if non-NULL and the interface the user is on is capable of panic handling. It also cleans up the panic log handling a bit to reuse the existing interface loop in the main panic handler. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Add a maintenance mode for IPMB messagesCorey Minyard2018-04-181-0/+28
| | | | | | | If you send a command to another BMC that might take some extra time, increase the timeouts temporarily. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Add a way to tune some timeoutsCorey Minyard2018-04-181-32/+48
| | | | | | | | | | | | | | | | | | By default the retry timeout is 1 second. Allow that to be modified, primarily for slow operations, like firmware writes. Also, the timeout was driven by a 1 second timer, so 1 second really meant between 0 and 1 second. Set the default to 2 seconds so it means between 1 and 2 seconds. Also allow the time the interface automatically stays in mainenance mode to be modified from it's default 30 seconds. Also consolidate some of the timeout and retry setup. Signed-off-by: Corey Minyard <cminyard@mvista.com> more
* ipmi: Add or fix SPDX-License-Identifier in all filesCorey Minyard2018-02-271-21/+1
| | | | | | | | | | | And get rid of the license text that is no longer necessary. Signed-off-by: Corey Minyard <cminyard@mvista.com> Cc: Kees Cook <keescook@chromium.org> Cc: Alistair Popple <alistair@popple.id.au> Cc: Jeremy Kerr <jk@ozlabs.org> Cc: Joel Stanley <joel@jms.id.au> Cc: Rocky Craig <rocky.craig@hp.com>
* Merge tag 'driver-core-4.16-rc1' of ↵Linus Torvalds2018-02-011-9/+8
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core Pull driver core updates from Greg KH: "Here is the set of "big" driver core patches for 4.16-rc1. The majority of the work here is in the firmware subsystem, with reworks to try to attempt to make the code easier to handle in the long run, but no functional change. There's also some tree-wide sysfs attribute fixups with lots of acks from the various subsystem maintainers, as well as a handful of other normal fixes and changes. And finally, some license cleanups for the driver core and sysfs code. All have been in linux-next for a while with no reported issues" * tag 'driver-core-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (48 commits) device property: Define type of PROPERTY_ENRTY_*() macros device property: Reuse property_entry_free_data() device property: Move property_entry_free_data() upper firmware: Fix up docs referring to FIRMWARE_IN_KERNEL firmware: Drop FIRMWARE_IN_KERNEL Kconfig option USB: serial: keyspan: Drop firmware Kconfig options sysfs: remove DEBUG defines sysfs: use SPDX identifiers drivers: base: add coredump driver ops sysfs: add attribute specification for /sysfs/devices/.../coredump test_firmware: fix missing unlock on error in config_num_requests_store() test_firmware: make local symbol test_fw_config static sysfs: turn WARN() into pr_warn() firmware: Fix a typo in fallback-mechanisms.rst treewide: Use DEVICE_ATTR_WO treewide: Use DEVICE_ATTR_RO treewide: Use DEVICE_ATTR_RW sysfs.h: Use octal permissions component: add debugfs support bus: simple-pm-bus: convert bool SIMPLE_PM_BUS to tristate ...
| * treewide: Use DEVICE_ATTR_ROJoe Perches2018-01-091-9/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Convert DEVICE_ATTR uses to DEVICE_ATTR_RO where possible. Done with perl script: $ git grep -w --name-only DEVICE_ATTR | \ xargs perl -i -e 'local $/; while (<>) { s/\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?(?:\s*S_IRUGO\s*|\s*0444\s*)\)?\s*,\s*\1_show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(\1)/g; print;}' Signed-off-by: Joe Perches <joe@perches.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Robert Jarzmik <robert.jarzmik@free.fr> Acked-by: Sagi Grimberg <sagi@grimberg.me> Acked-by: Zhang Rui <rui.zhang@intel.com> Acked-by: Harald Freudenberger <freude@linux.vnet.ibm.com> Acked-by: Jani Nikula <jani.nikula@intel.com> Acked-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
* | ipmi: use correct string lengthXiongfeng Wang2018-01-081-1/+1
|/ | | | | | | | | | | | | | | | | | | gcc-8 reports drivers/char/ipmi/ipmi_msghandler.c: In function 'panic_op_write_handler': ./include/linux/string.h:245:9: warning: '__builtin_strncpy' specified bound 16 equals destination size [-Wstringop-truncation] drivers/char/ipmi/ipmi_watchdog.c: In function 'set_param_str': ./include/linux/string.h:245:9: warning: '__builtin_strncpy' specified bound 16 equals destination size [-Wstringop-truncation] We need one less byte or call strlcpy() to make it a nul-terminated string. Signed-off-by: Xiongfeng Wang <xiongfeng.wang@linaro.org> Signed-off-by: Corey Minyard <cminyard@mvista.com>
* treewide: setup_timer() -> timer_setup()Kees Cook2017-11-211-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This converts all remaining cases of the old setup_timer() API into using timer_setup(), where the callback argument is the structure already holding the struct timer_list. These should have no behavioral changes, since they just change which pointer is passed into the callback with the same available pointers after conversion. It handles the following examples, in addition to some other variations. Casting from unsigned long: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... setup_timer(&ptr->my_timer, my_callback, ptr); and forced object casts: void my_callback(struct something *ptr) { ... } ... setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr); become: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... timer_setup(&ptr->my_timer, my_callback, 0); Direct function assignments: void my_callback(unsigned long data) { struct something *ptr = (struct something *)data; ... } ... ptr->my_timer.function = my_callback; have a temporary cast added, along with converting the args: void my_callback(struct timer_list *t) { struct something *ptr = from_timer(ptr, t, my_timer); ... } ... ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback; And finally, callbacks without a data assignment: void my_callback(unsigned long data) { ... } ... setup_timer(&ptr->my_timer, my_callback, 0); have their argument renamed to verify they're unused during conversion: void my_callback(struct timer_list *unused) { ... } ... timer_setup(&ptr->my_timer, my_callback, 0); The conversion is done with the following Coccinelle script: spatch --very-quiet --all-includes --include-headers \ -I ./arch/x86/include -I ./arch/x86/include/generated \ -I ./include -I ./arch/x86/include/uapi \ -I ./arch/x86/include/generated/uapi -I ./include/uapi \ -I ./include/generated/uapi --include ./include/linux/kconfig.h \ --dir . \ --cocci-file ~/src/data/timer_setup.cocci @fix_address_of@ expression e; @@ setup_timer( -&(e) +&e , ...) // Update any raw setup_timer() usages that have a NULL callback, but // would otherwise match change_timer_function_usage, since the latter // will update all function assignments done in the face of a NULL // function initialization in setup_timer(). @change_timer_function_usage_NULL@ expression _E; identifier _timer; type _cast_data; @@ ( -setup_timer(&_E->_timer, NULL, _E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E->_timer, NULL, (_cast_data)_E); +timer_setup(&_E->_timer, NULL, 0); | -setup_timer(&_E._timer, NULL, &_E); +timer_setup(&_E._timer, NULL, 0); | -setup_timer(&_E._timer, NULL, (_cast_data)&_E); +timer_setup(&_E._timer, NULL, 0); ) @change_timer_function_usage@ expression _E; identifier _timer; struct timer_list _stl; identifier _callback; type _cast_func, _cast_data; @@ ( -setup_timer(&_E->_timer, _callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, &_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, _E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, &_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E); +timer_setup(&_E._timer, _callback, 0); | _E->_timer@_stl.function = _callback; | _E->_timer@_stl.function = &_callback; | _E->_timer@_stl.function = (_cast_func)_callback; | _E->_timer@_stl.function = (_cast_func)&_callback; | _E._timer@_stl.function = _callback; | _E._timer@_stl.function = &_callback; | _E._timer@_stl.function = (_cast_func)_callback; | _E._timer@_stl.function = (_cast_func)&_callback; ) // callback(unsigned long arg) @change_callback_handle_cast depends on change_timer_function_usage@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; identifier _handle; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { ( ... when != _origarg _handletype *_handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(_handletype *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg | ... when != _origarg _handletype *_handle; ... when != _handle _handle = -(void *)_origarg; +from_timer(_handle, t, _timer); ... when != _origarg ) } // callback(unsigned long arg) without existing variable @change_callback_handle_cast_no_arg depends on change_timer_function_usage && !change_callback_handle_cast@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _origtype; identifier _origarg; type _handletype; @@ void _callback( -_origtype _origarg +struct timer_list *t ) { + _handletype *_origarg = from_timer(_origarg, t, _timer); + ... when != _origarg - (_handletype *)_origarg + _origarg ... when != _origarg } // Avoid already converted callbacks. @match_callback_converted depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier t; @@ void _callback(struct timer_list *t) { ... } // callback(struct something *handle) @change_callback_handle_arg depends on change_timer_function_usage && !match_callback_converted && !change_callback_handle_cast && !change_callback_handle_cast_no_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; @@ void _callback( -_handletype *_handle +struct timer_list *t ) { + _handletype *_handle = from_timer(_handle, t, _timer); ... } // If change_callback_handle_arg ran on an empty function, remove // the added handler. @unchange_callback_handle_arg depends on change_timer_function_usage && change_callback_handle_arg@ identifier change_timer_function_usage._callback; identifier change_timer_function_usage._timer; type _handletype; identifier _handle; identifier t; @@ void _callback(struct timer_list *t) { - _handletype *_handle = from_timer(_handle, t, _timer); } // We only want to refactor the setup_timer() data argument if we've found // the matching callback. This undoes changes in change_timer_function_usage. @unchange_timer_function_usage depends on change_timer_function_usage && !change_callback_handle_cast && !change_callback_handle_cast_no_arg && !change_callback_handle_arg@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type change_timer_function_usage._cast_data; @@ ( -timer_setup(&_E->_timer, _callback, 0); +setup_timer(&_E->_timer, _callback, (_cast_data)_E); | -timer_setup(&_E._timer, _callback, 0); +setup_timer(&_E._timer, _callback, (_cast_data)&_E); ) // If we fixed a callback from a .function assignment, fix the // assignment cast now. @change_timer_function_assignment depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression change_timer_function_usage._E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_func; typedef TIMER_FUNC_TYPE; @@ ( _E->_timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -&_callback +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)_callback; +(TIMER_FUNC_TYPE)_callback ; | _E->_timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -&_callback; +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)_callback +(TIMER_FUNC_TYPE)_callback ; | _E._timer.function = -(_cast_func)&_callback +(TIMER_FUNC_TYPE)_callback ; ) // Sometimes timer functions are called directly. Replace matched args. @change_timer_function_calls depends on change_timer_function_usage && (change_callback_handle_cast || change_callback_handle_cast_no_arg || change_callback_handle_arg)@ expression _E; identifier change_timer_function_usage._timer; identifier change_timer_function_usage._callback; type _cast_data; @@ _callback( ( -(_cast_data)_E +&_E->_timer | -(_cast_data)&_E +&_E._timer | -_E +&_E->_timer ) ) // If a timer has been configured without a data argument, it can be // converted without regard to the callback argument, since it is unused. @match_timer_function_unused_data@ expression _E; identifier _timer; identifier _callback; @@ ( -setup_timer(&_E->_timer, _callback, 0); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0L); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E->_timer, _callback, 0UL); +timer_setup(&_E->_timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0L); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_E._timer, _callback, 0UL); +timer_setup(&_E._timer, _callback, 0); | -setup_timer(&_timer, _callback, 0); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0L); +timer_setup(&_timer, _callback, 0); | -setup_timer(&_timer, _callback, 0UL); +timer_setup(&_timer, _callback, 0); | -setup_timer(_timer, _callback, 0); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0L); +timer_setup(_timer, _callback, 0); | -setup_timer(_timer, _callback, 0UL); +timer_setup(_timer, _callback, 0); ) @change_callback_unused_data depends on match_timer_function_unused_data@ identifier match_timer_function_unused_data._callback; type _origtype; identifier _origarg; @@ void _callback( -_origtype _origarg +struct timer_list *unused ) { ... when != _origarg } Signed-off-by: Kees Cook <keescook@chromium.org>
* ipmi: remove redundant initialization of bmcColin Ian King2017-09-281-1/+1
| | | | | | | | | | | The pointer bmc is being initialized and this initialized value is never being read, so this is assignment redundant and can be removed. Cleans up clang warning: warning: Value stored to 'bmc' during its initialization is never read Signed-off-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Clean up some print operationsCorey Minyard2017-09-281-56/+45
| | | | | | | Get rid of all printfs, using dev_xxx() if a device is available, pr_xxx() otherwise, and format long strings properly. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Make the DMI probe into a generic platform probeCorey Minyard2017-09-281-1/+1
| | | | | | | | | Rework the DMI probe function to be a generic platform probe, and then rework the DMI code (and a few other things) to use the more generic information. This is so other things can declare platform IPMI devices. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Make the IPMI proc interface configurableCorey Minyard2017-09-281-21/+22
| | | | | | So we can remove it later. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Convert IPMI GUID over to Linux guid_tCorey Minyard2017-09-271-27/+23
| | | | Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Rescan channel list on BMC changesCorey Minyard2017-09-271-58/+111
| | | | | | | If the BMC changes versions or a change is otherwise detected, rescan the channels on the BMC. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Move lun and address out of channel structCorey Minyard2017-09-271-22/+25
| | | | | | | Put it in it's own struct, getting ready for channel information being dynamically changed. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Retry BMC registration on a failureCorey Minyard2017-09-271-1/+23
| | | | | | If the BMC fails to register, just set up to retry periodically. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Rework device id and guid handling to catch changing BMCsCorey Minyard2017-09-271-73/+167
| | | | | | | | A BMC's guid or device id info may change dynamically, this could result in a different configuration that needs to be done. Adjust the BMCs dynamically. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Use a temporary BMC for an interfaceCorey Minyard2017-09-271-9/+13
| | | | | | | This is getting ready for the ability to redo the BMC if it's information changes, we need a fallback mechanism. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Dynamically fetch GUID periodicallyCorey Minyard2017-09-271-19/+42
| | | | | | This will catch if the GUID changes. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Always fetch the guid through ipmi_get_device_id()Corey Minyard2017-09-271-28/+65
| | | | | | | This is in preparation for making ipmi_get_device_id() dynamically return the guid and device id. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Remove the device id from ipmi_register_smi()Corey Minyard2017-09-271-1/+0
| | | | | | It's no longer used, dynamic device id handling is in place now. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: allow dynamic BMC version informationJeremy Kerr2017-09-271-15/+190
| | | | | | | | | | | | | | | | | | | | | | | | Currently, it's up to the IPMI SMIs to provide the product & version details of BMCs behind registered IPMI SMI interfaces. This device ID is provided on SMI regsitration, and kept around for all future queries. However, this version information isn't always static. For example, a BMC may be upgraded at runtime, making the old version information stale. This change allows querying the BMC device ID & version information dynamically. If no static device_id argument is provided to ipmi_register_smi, then the IPMI core code will perform a Get Device ID IPMI command to query the version information when needed. We keep a short-term cache of this information so we don't need to re-query for every attribute access. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> I basically rewrote this, I fixed some locking issues and simplified things. Same functional change, though. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Don't use BMC product/dev ids in the BMC nameCorey Minyard2017-09-271-35/+10
| | | | | | | | | | | | | There are a lot of bad things that a set of BMCs could do that would really confuse the IPMI driver; it's possible for BMCs with different GUIDs to have the same product/devid (though that's not technically legal), which would result in platform device namespace collisions. Fixing it would involve either using the GUID in the BMC name, which resulted in huge names, or just using an ida for numbering the BMCs. The latter approach was chosen to avoid the huge names. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Add a reference from BMC devices to their interfacesJeremy Kerr2017-09-271-0/+11
| | | | | | | | | | | In an upcoming change, we'll want to grab a reference to the ipmi_smi_t from a struct bmc_device. This change adds a pointer to allow this. Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Reworked to support multiple interfaces on a BMC. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Get the device id through a functionCorey Minyard2017-09-271-36/+119
| | | | | | | This makes getting the device id consistent, and make it possible to add a function to fetch it dynamically later. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Fix printing the BMC guidCorey Minyard2017-09-271-3/+6
| | | | | | It was just wrong. Make it print according to the guid spec. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Rework BMC registrationCorey Minyard2017-09-271-23/+45
| | | | | | | | | There was a certain error case where the BMC wouldn't be deregistered like it should be. Rework the BMC registration to make calling ipmi_bmc_unregister() ok even if it's not registered and to clean up the error handling for ipmi_bmc_register(). Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Fix issues with BMC refcountsCorey Minyard2017-09-271-16/+35
| | | | | | | | | | BMC device refcounts were not being decremented after fetching from driver_find_device(). Also, document the use of ipmidriver_mutex and tighten it's span some by incrementing the BMC's usecount in the BMC find routines and not later. This will be important for future changes where a long mutex hold area will complicate things. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Check that the device type is BMC when scanning deviceCorey Minyard2017-09-271-3/+9
| | | | | | Just an added safety check. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Move bmc find routing to below bmc device typeCorey Minyard2017-09-271-50/+51
| | | | | | | No functional change, this is for a later change that uses the bmc device type. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Fix getting the GUID dataCorey Minyard2017-09-271-1/+1
| | | | | | It was off by one. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: Make IPMI panic strings always availableCorey Minyard2017-09-271-13/+78
| | | | | | | | They were set by config items, but people complained that they were never turned on. So have them always available and enabled by a module parameter. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: fix unsigned long underflowCorey Minyard2017-09-271-4/+6
| | | | | | | | | | | | | | | | | | | When I set the timeout to a specific value such as 500ms, the timeout event will not happen in time due to the overflow in function check_msg_timeout: ... ent->timeout -= timeout_period; if (ent->timeout > 0) return; ... The type of timeout_period is long, but ent->timeout is unsigned long. This patch makes the type consistent. Reported-by: Weilong Chen <chenweilong@huawei.com> Signed-off-by: Corey Minyard <cminyard@mvista.com> Tested-by: Weilong Chen <chenweilong@huawei.com> Cc: <stable@vger.kernel.org> # 3.16.x
* char: ipmi: constify bmc_dev_attr_group and bmc_device_typeArvind Yadav2017-06-281-2/+2
| | | | | | | | | | | | | File size before: text data bss dec hex filename 25678 1024 92 26794 68aa drivers/char/ipmi/ipmi_msghandler.o File size After adding 'const': text data bss dec hex filename 25806 896 92 26794 68aa drivers/char/ipmi/ipmi_msghandler.o Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com> Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: use rcu lock around call to intf->handlers->sender()Tony Camuso2017-06-191-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A vendor with a system having more than 128 CPUs occasionally encounters the following crash during shutdown. This is not an easily reproduceable event, but the vendor was able to provide the following analysis of the crash, which exhibits the same footprint each time. crash> bt PID: 0 TASK: ffff88017c70ce70 CPU: 5 COMMAND: "swapper/5" #0 [ffff88085c143ac8] machine_kexec at ffffffff81059c8b #1 [ffff88085c143b28] __crash_kexec at ffffffff811052e2 #2 [ffff88085c143bf8] crash_kexec at ffffffff811053d0 #3 [ffff88085c143c10] oops_end at ffffffff8168ef88 #4 [ffff88085c143c38] no_context at ffffffff8167ebb3 #5 [ffff88085c143c88] __bad_area_nosemaphore at ffffffff8167ec49 #6 [ffff88085c143cd0] bad_area_nosemaphore at ffffffff8167edb3 #7 [ffff88085c143ce0] __do_page_fault at ffffffff81691d1e #8 [ffff88085c143d40] do_page_fault at ffffffff81691ec5 #9 [ffff88085c143d70] page_fault at ffffffff8168e188 [exception RIP: unknown or invalid address] RIP: ffffffffa053c800 RSP: ffff88085c143e28 RFLAGS: 00010206 RAX: ffff88017c72bfd8 RBX: ffff88017a8dc000 RCX: ffff8810588b5ac8 RDX: ffff8810588b5a00 RSI: ffffffffa053c800 RDI: ffff8810588b5a00 RBP: ffff88085c143e58 R8: ffff88017c70d408 R9: ffff88017a8dc000 R10: 0000000000000002 R11: ffff88085c143da0 R12: ffff8810588b5ac8 R13: 0000000000000100 R14: ffffffffa053c800 R15: ffff8810588b5a00 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 <IRQ stack> [exception RIP: cpuidle_enter_state+82] RIP: ffffffff81514192 RSP: ffff88017c72be50 RFLAGS: 00000202 RAX: 0000001e4c3c6f16 RBX: 000000000000f8a0 RCX: 0000000000000018 RDX: 0000000225c17d03 RSI: ffff88017c72bfd8 RDI: 0000001e4c3c6f16 RBP: ffff88017c72be78 R8: 000000000000237e R9: 0000000000000018 R10: 0000000000002494 R11: 0000000000000001 R12: ffff88017c72be20 R13: ffff88085c14f8e0 R14: 0000000000000082 R15: 0000001e4c3bb400 ORIG_RAX: ffffffffffffff10 CS: 0010 SS: 0018 This is the corresponding stack trace It has crashed because the area pointed with RIP extracted from timer element is already removed during a shutdown process. The function is smi_timeout(). And we think ffff8810588b5a00 in RDX is a parameter struct smi_info crash> rd ffff8810588b5a00 20 ffff8810588b5a00: ffff8810588b6000 0000000000000000 .`.X............ ffff8810588b5a10: ffff880853264400 ffffffffa05417e0 .D&S......T..... ffff8810588b5a20: 24a024a000000000 0000000000000000 .....$.$........ ffff8810588b5a30: 0000000000000000 0000000000000000 ................ ffff8810588b5a30: 0000000000000000 0000000000000000 ................ ffff8810588b5a40: ffffffffa053a040 ffffffffa053a060 @.S.....`.S..... ffff8810588b5a50: 0000000000000000 0000000100000001 ................ ffff8810588b5a60: 0000000000000000 0000000000000e00 ................ ffff8810588b5a70: ffffffffa053a580 ffffffffa053a6e0 ..S.......S..... ffff8810588b5a80: ffffffffa053a4a0 ffffffffa053a250 ..S.....P.S..... ffff8810588b5a90: 0000000500000002 0000000000000000 ................ Unfortunately the top of this area is already detroyed by someone. But because of two reasonns we think this is struct smi_info 1) The address included in between ffff8810588b5a70 and ffff8810588b5a80: are inside of ipmi_si_intf.c see crash> module ffff88085779d2c0 2) We've found the area which point this. It is offset 0x68 of ffff880859df4000 crash> rd ffff880859df4000 100 ffff880859df4000: 0000000000000000 0000000000000001 ................ ffff880859df4010: ffffffffa0535290 dead000000000200 .RS............. ffff880859df4020: ffff880859df4020 ffff880859df4020 @.Y.... @.Y.... ffff880859df4030: 0000000000000002 0000000000100010 ................ ffff880859df4040: ffff880859df4040 ffff880859df4040 @@.Y....@@.Y.... ffff880859df4050: 0000000000000000 0000000000000000 ................ ffff880859df4060: 0000000000000000 ffff8810588b5a00 .........Z.X.... ffff880859df4070: 0000000000000001 ffff880859df4078 ........x@.Y.... If we regards it as struct ipmi_smi in shutdown process it looks consistent. The remedy for this apparent race is affixed below. Signed-off-by: Tony Camuso <tcamuso@redhat.com> Cc: stable@vger.kernel.org # 3.19 This was first introduced in 7ea0ed2b5be817 ipmi: Make the message handler easier to use for SMI interfaces where some code was moved outside of the rcu_read_lock() and the lock was not added. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: make ipmi_usr_hndl constCorey Minyard2017-01-051-2/+2
| | | | | | It's only function pointers. Signed-off-by: Corey Minyard <cminyard@mvista.com>
* ipmi: create hardware-independent softdep for ipmi_devintfMartin Wilck2016-12-121-0/+1
| | | | | | | | | | | | | | | | | | | | When a computer has an IPMI system interface, the device interface is most probably also desired. Autoloading of ipmi_devintf currently works only if ipmi_si has allocated a platform device. That doesn't happen if the SI interface was detected e.g. via ACPI. But ACPI detection is preferred these days, see e.g. kernel.org bug 46741. This patch introduces a softdep in place of the existing modalias for ipmi_devintf. Signed-off-by: Martin Wilck <mwilck@suse.com> Suggested-by: Takashi Iwai <tiwai@suse.com> I moved this to ipmi_msghandler.c, so it works for all IPMI interfaces. Retested by Martin. Tested-by: Martin Wilck <mwilck@suse.com> Signed-off-by: Corey Minyard <cminyard@mvista.com>
OpenPOWER on IntegriCloud