Commit Graph

256 Commits

Author SHA1 Message Date
Corey Minyard
fac56b7dde ipmi: Check error code before processing BMC response
In case an error did occur, print out useful information.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2021-10-05 06:54:16 -05:00
Corey Minyard
b36eb5e7b7 ipmi: Disable some operations during a panic
Don't do kfree or other risky things when oops_in_progress is set.
It's easy enough to avoid doing them

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2021-10-05 06:54:16 -05:00
Andy Shevchenko
f39650de68 kernel.h: split out panic and oops helpers
kernel.h is being used as a dump for all kinds of stuff for a long time.
Here is the attempt to start cleaning it up by splitting out panic and
oops helpers.

There are several purposes of doing this:
- dropping dependency in bug.h
- dropping a loop by moving out panic_notifier.h
- unload kernel.h from something which has its own domain

At the same time convert users tree-wide to use new headers, although for
the time being include new header back to kernel.h to avoid twisted
indirected includes for existing users.

[akpm@linux-foundation.org: thread_info.h needs limits.h]
[andriy.shevchenko@linux.intel.com: ia64 fix]
  Link: https://lkml.kernel.org/r/20210520130557.55277-1-andriy.shevchenko@linux.intel.com

Link: https://lkml.kernel.org/r/20210511074137.33666-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Co-developed-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Acked-by: Corey Minyard <cminyard@mvista.com>
Acked-by: Christian Brauner <christian.brauner@ubuntu.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Kees Cook <keescook@chromium.org>
Acked-by: Wei Liu <wei.liu@kernel.org>
Acked-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Sebastian Reichel <sre@kernel.org>
Acked-by: Luis Chamberlain <mcgrof@kernel.org>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Acked-by: Helge Deller <deller@gmx.de> # parisc
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2021-07-01 11:06:04 -07:00
Andy Shevchenko
07cbd87b04 ipmi_si: Join string literals back
For easy grepping on debug purposes join string literals back in
the messages.

No functional change.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Message-Id: <20210402174334.13466-11-andriy.shevchenko@linux.intel.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2021-04-02 12:53:42 -05:00
Andy Shevchenko
649a7d46d0 ipmi_si: Introduce ipmi_panic_event_str[] array
Instead of repeating twice the constant literals, introduce
ipmi_panic_event_str[] array. It allows to simplify the code
with help of match_string() API.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Message-Id: <20210402174334.13466-6-andriy.shevchenko@linux.intel.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2021-04-02 12:53:28 -05:00
Terry Duncan
c6ddd5f1c3 ipmi: Refine retry conditions for getting device id
Rarely but still failures are observed while getting BMC device ID
so this commit changes the condition to retry to get device id
when cc is not IPMI_CC_NO_ERROR.

Signed-off-by: Terry Duncan <terry.s.duncan@intel.com>
Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
Message-Id: <20210225045027.9344-1-jae.hyun.yoo@linux.intel.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2021-03-10 19:00:02 -06:00
Qinglang Miao
368ffd9adc ipmi: msghandler: Suppress suspicious RCU usage warning
while running ipmi, ipmi_smi_watcher_register() caused
a suspicious RCU usage warning.

-----

=============================
WARNING: suspicious RCU usage
5.10.0-rc3+ #1 Not tainted
-----------------------------
drivers/char/ipmi/ipmi_msghandler.c:750 RCU-list traversed in non-reader section!!
other info that might help us debug this:
rcu_scheduler_active = 2, debug_locks = 1
2 locks held by syz-executor.0/4254:
stack backtrace:
CPU: 0 PID: 4254 Comm: syz-executor.0 Not tainted 5.10.0-rc3+ #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1 04/ 01/2014
Call Trace:
dump_stack+0x19d/0x200
ipmi_smi_watcher_register+0x2d3/0x340 [ipmi_msghandler]
acpi_ipmi_init+0xb1/0x1000 [acpi_ipmi]
do_one_initcall+0x149/0x7e0
do_init_module+0x1ef/0x700
load_module+0x3467/0x4140
__do_sys_finit_module+0x10d/0x1a0
do_syscall_64+0x34/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x468ded

-----

It is safe because smi_watchers_mutex is locked and srcu_read_lock
has been used, so simply pass lockdep_is_held() to the
list_for_each_entry_rcu() to suppress this warning.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: Qinglang Miao <miaoqinglang@huawei.com>
Message-Id: <20201119070839.381-1-miaoqinglang@huawei.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-11-19 06:36:28 -06:00
Dan Carpenter
c011410d91 ipmi: msghandler: Fix a signedness bug
The type for the completion codes should be unsigned char instead of
char.  If it is declared as a normal char then the conditions in
__get_device_id() are impossible because the IPMI_DEVICE_IN_FW_UPDATE_ERR
error codes are higher than 127.

    drivers/char/ipmi/ipmi_msghandler.c:2449 __get_device_id()
    warn: impossible condition '(bmc->cc == 209) => ((-128)-127 == 209)'

Fixes: f8910ffa81 ("ipmi:msghandler: retry to get device id on an error")
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Message-Id: <20200918142756.GB909725@mwanda>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-09-18 16:34:52 -05:00
Xianting Tian
42d8a346c5 ipmi: add retry in try_get_dev_id()
Use a retry machanism to give the BMC more opportunities to correctly
respond when we receive specific completion codes.

This is similar to what is done in __get_device_id().

Signed-off-by: Xianting Tian <tian.xianting@h3c.com>
Message-Id: <20200916062129.26129-1-tian.xianting@h3c.com>
[Moved GET_DEVICE_ID_MAX_RETRY to include/linux/ipmi.h, reworded some
 text.]
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-09-16 08:54:53 -05:00
Xianting Tian
f8910ffa81 ipmi:msghandler: retry to get device id on an error
We fail to get the BMCS's device id with low probability when loading
the ipmi driver and it causes BMC device registration failed. When this
issue occurs we got below kernel prints:

  [Wed Sep  9 19:52:03 2020] ipmi_si IPI0001:00: IPMI message handler:
     device id demangle failed: -22
  [Wed Sep  9 19:52:03 2020] IPMI BT: using default values
  [Wed Sep  9 19:52:03 2020] IPMI BT: req2rsp=5 secs retries=2
  [Wed Sep  9 19:52:03 2020] ipmi_si IPI0001:00: Unable to get the
     device id: -5
  [Wed Sep  9 19:52:04 2020] ipmi_si IPI0001:00: Unable to register
     device: error -5

When this issue happens, we want to manually unload the driver and try to
load it again, but it can't be unloaded by 'rmmod' as it is already 'in
use'.

We add a print in handle_one_recv_msg(), when this issue happens,
the msg we received is "Recv: 1c 01 d5", which means the data_len is 1,
data[0] is 0xd5 (completion code), which means "bmc cannot execute
command.  Command, or request parameter(s), not supported in present
state".  Debug code:
	static int handle_one_recv_msg(struct ipmi_smi *intf,
                               struct ipmi_smi_msg *msg) {
        	printk("Recv: %*ph\n", msg->rsp_size, msg->rsp);
		... ...
	}
Then in ipmi_demangle_device_id(), it returned '-EINVAL' as 'data_len < 7'
and 'data[0] != 0'.

We created this patch to retry the get device id when this error
happens.  We reproduced this issue again and the retry succeed on the
first retry, we finally got the correct msg and then all is ok:
Recv: 1c 01 00 01 81 05 84 02 af db 07 00 01 00 b9 00 10 00

So use a retry machanism in this patch to give bmc more opportunity to
correctly response kernel when we received specific completion codes.

Signed-off-by: Xianting Tian <tian.xianting@h3c.com>
Message-Id: <20200915071817.4484-1-tian.xianting@h3c.com>
[Cleaned up the verbage a bit in the header and prints.]
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-09-15 09:57:45 -05:00
Markus Boehme
81e7571ea3 ipmi: Reset response handler when failing to send the command
When failing to send a command we don't expect a response. Clear the
`null_user_handler` like is done in the success path.

Signed-off-by: Markus Boehme <markubo@amazon.com>
Message-Id: <1599495937-10654-1-git-send-email-markubo@amazon.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-09-15 08:52:27 -05:00
Xiongfeng Wang
8a00e56a14 ipmi: add a newline when printing parameter 'panic_op' by sysfs
When I cat ipmi_msghandler parameter 'panic_op' by sysfs, it displays as
follows. It's better to add a newline for easy reading.

root@(none):/# cat /sys/module/ipmi_msghandler/parameters/panic_op
noneroot@(none):/#

Signed-off-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
Message-Id: <1599130873-2402-1-git-send-email-wangxiongfeng2@huawei.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-09-03 13:34:35 -05:00
Allen Pais
83dea12856 char: ipmi: convert tasklets to use new tasklet_setup() API
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.

Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
Message-Id: <20200817091617.28119-3-allen.cryptic@gmail.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-08-18 06:04:11 -05:00
Jing Xiangfeng
a7f0f92aa8 ipmi: remve duplicate code in __ipmi_bmc_register()
__ipmi_bmc_register() jumps to the label 'out_free_my_dev_name' in an
error path. So we can remove duplicate code in the if (rv).

Signed-off-by: Jing Xiangfeng <jingxiangfeng@huawei.com>
Message-Id: <20200720080838.148737-1-jingxiangfeng@huawei.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-07-20 06:31:50 -05:00
Andy Shevchenko
878caa9659 ipmi: Replace guid_copy() with import_guid() where it makes sense
There is a specific API to treat raw data as GUID, i.e. import_guid().
Use it instead of guid_copy() with explicit casting.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Message-Id: <20200422130348.38749-1-andriy.shevchenko@linux.intel.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-05-18 06:32:02 -05:00
Feng Tang
7c47a219b9 ipmi: use vzalloc instead of kmalloc for user creation
We met mulitple times of failure of staring bmc-watchdog,
due to the runtime memory allocation failure of order 4.

     bmc-watchdog: page allocation failure: order:4, mode:0x40cc0(GFP_KERNEL|__GFP_COMP), nodemask=(null),cpuset=/,mems_allowed=0-1
     CPU: 1 PID: 2571 Comm: bmc-watchdog Not tainted 5.5.0-00045-g7d6bb61d6188c #1
     Hardware name: Intel Corporation S2600WFT/S2600WFT, BIOS SE5C620.86B.00.01.0015.110720180833 11/07/2018
     Call Trace:
      dump_stack+0x66/0x8b
      warn_alloc+0xfe/0x160
      __alloc_pages_slowpath+0xd3e/0xd80
      __alloc_pages_nodemask+0x2f0/0x340
      kmalloc_order+0x18/0x70
      kmalloc_order_trace+0x1d/0xb0
      ipmi_create_user+0x55/0x2c0 [ipmi_msghandler]
      ipmi_open+0x72/0x110 [ipmi_devintf]
      chrdev_open+0xcb/0x1e0
      do_dentry_open+0x1ce/0x380
      path_openat+0x305/0x14f0
      do_filp_open+0x9b/0x110
      do_sys_open+0x1bd/0x250
      do_syscall_64+0x5b/0x1f0
      entry_SYSCALL_64_after_hwframe+0x44/0xa9

Using vzalloc/vfree for creating ipmi_user heals the
problem

Thanks to Stephen Rothwell for finding the vmalloc.h
inclusion issue.

Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-05-18 06:32:02 -05:00
Wen Yang
32830a0534 ipmi: fix hung processes in __get_guid()
The wait_event() function is used to detect command completion.
When send_guid_cmd() returns an error, smi_send() has not been
called to send data. Therefore, wait_event() should not be used
on the error path, otherwise it will cause the following warning:

[ 1361.588808] systemd-udevd   D    0  1501   1436 0x00000004
[ 1361.588813]  ffff883f4b1298c0 0000000000000000 ffff883f4b188000 ffff887f7e3d9f40
[ 1361.677952]  ffff887f64bd4280 ffffc90037297a68 ffffffff8173ca3b ffffc90000000010
[ 1361.767077]  00ffc90037297ad0 ffff887f7e3d9f40 0000000000000286 ffff883f4b188000
[ 1361.856199] Call Trace:
[ 1361.885578]  [<ffffffff8173ca3b>] ? __schedule+0x23b/0x780
[ 1361.951406]  [<ffffffff8173cfb6>] schedule+0x36/0x80
[ 1362.010979]  [<ffffffffa071f178>] get_guid+0x118/0x150 [ipmi_msghandler]
[ 1362.091281]  [<ffffffff810d5350>] ? prepare_to_wait_event+0x100/0x100
[ 1362.168533]  [<ffffffffa071f755>] ipmi_register_smi+0x405/0x940 [ipmi_msghandler]
[ 1362.258337]  [<ffffffffa0230ae9>] try_smi_init+0x529/0x950 [ipmi_si]
[ 1362.334521]  [<ffffffffa022f350>] ? std_irq_setup+0xd0/0xd0 [ipmi_si]
[ 1362.411701]  [<ffffffffa0232bd2>] init_ipmi_si+0x492/0x9e0 [ipmi_si]
[ 1362.487917]  [<ffffffffa0232740>] ? ipmi_pci_probe+0x280/0x280 [ipmi_si]
[ 1362.568219]  [<ffffffff810021a0>] do_one_initcall+0x50/0x180
[ 1362.636109]  [<ffffffff812231b2>] ? kmem_cache_alloc_trace+0x142/0x190
[ 1362.714330]  [<ffffffff811b2ae1>] do_init_module+0x5f/0x200
[ 1362.781208]  [<ffffffff81123ca8>] load_module+0x1898/0x1de0
[ 1362.848069]  [<ffffffff811202e0>] ? __symbol_put+0x60/0x60
[ 1362.913886]  [<ffffffff8130696b>] ? security_kernel_post_read_file+0x6b/0x80
[ 1362.998514]  [<ffffffff81124465>] SYSC_finit_module+0xe5/0x120
[ 1363.068463]  [<ffffffff81124465>] ? SYSC_finit_module+0xe5/0x120
[ 1363.140513]  [<ffffffff811244be>] SyS_finit_module+0xe/0x10
[ 1363.207364]  [<ffffffff81003c04>] do_syscall_64+0x74/0x180

Fixes: 50c812b2b9 ("[PATCH] ipmi: add full sysfs support")
Signed-off-by: Wen Yang <wenyang@linux.alibaba.com>
Cc: Corey Minyard <minyard@acm.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: openipmi-developer@lists.sourceforge.net
Cc: linux-kernel@vger.kernel.org
Cc: stable@vger.kernel.org # 2.6.17-
Message-Id: <20200403090408.58745-1-wenyang@linux.alibaba.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-04-03 07:59:10 -05:00
Amol Grover
4f1885a7b3 drivers: char: ipmi: ipmi_msghandler: Pass lockdep expression to RCU lists
intf->cmd_rcvrs is traversed with list_for_each_entry_rcu
outside an RCU read-side critical section but under the
protection of intf->cmd_rcvrs_mutex.

ipmi_interfaces is traversed using list_for_each_entry_rcu
outside an RCU read-side critical section but under the protection
of ipmi_interfaces_mutex.

Hence, add the corresponding lockdep expression to the list traversal
primitive to silence false-positive lockdep warnings, and
harden RCU lists.

Add macro for the corresponding lockdep expression to make the code
clean and concise.

Signed-off-by: Amol Grover <frextrite@gmail.com>
Message-Id: <20200117132521.31020-1-frextrite@gmail.com>
Acked-by: Paul E. McKenney <paulmck@kernel.org>
Tested-by: John Garry <john.garry@huawei.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2020-03-12 14:56:00 -05:00
Navid Emamdoost
4aa7afb0ee ipmi: Fix memory leak in __ipmi_bmc_register
In the impelementation of __ipmi_bmc_register() the allocated memory for
bmc should be released in case ida_simple_get() fails.

Fixes: 68e7e50f19 ("ipmi: Don't use BMC product/dev ids in the BMC name")
Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
Message-Id: <20191021200649.1511-1-navid.emamdoost@gmail.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-10-22 14:42:34 -05:00
Andy Shevchenko
8ee7b485bb ipmi: use %*ph to print small buffer
Use %*ph format to print small buffer as hex string.

The change is safe since the specifier can handle up to 64 bytes and taking
into account the buffer size of 100 bytes on stack the function has never been
used to dump more than 32 bytes. Note, this also avoids potential buffer
overflow if the length of the input buffer is bigger.

This completely eliminates ipmi_debug_msg() in favour of Dynamic Debug.

Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Message-Id: <20191011155036.36748-1-andriy.shevchenko@linux.intel.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-10-22 14:42:34 -05:00
Corey Minyard
cbb79863fc ipmi: Don't allow device module unload when in use
If something has the IPMI driver open, don't allow the device
module to be unloaded.  Before it would unload and the user would
get errors on use.

This change is made on user request, and it makes it consistent
with the I2C driver, which has the same behavior.

It does change things a little bit with respect to kernel users.
If the ACPI or IPMI watchdog (or any other kernel user) has
created a user, then the device module cannot be unloaded.  Before
it could be unloaded,

This does not affect hot-plug.  If the device goes away (it's on
something removable that is removed or is hot-removed via sysfs)
then it still behaves as it did before.

Reported-by: tony camuso <tcamuso@redhat.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Tested-by: tony camuso <tcamuso@redhat.com>
2019-10-22 14:42:34 -05:00
Tony Camuso
383035211c ipmi: move message error checking to avoid deadlock
V1->V2: in handle_one_rcv_msg, if data_size > 2, set requeue to zero and
        goto out instead of calling ipmi_free_msg.
        Kosuke Tatsukawa <tatsu@ab.jp.nec.com>

In the source stack trace below, function set_need_watch tries to
take out the same si_lock that was taken earlier by ipmi_thread.

ipmi_thread() [drivers/char/ipmi/ipmi_si_intf.c:995]
 smi_event_handler() [drivers/char/ipmi/ipmi_si_intf.c:765]
  handle_transaction_done() [drivers/char/ipmi/ipmi_si_intf.c:555]
   deliver_recv_msg() [drivers/char/ipmi/ipmi_si_intf.c:283]
    ipmi_smi_msg_received() [drivers/char/ipmi/ipmi_msghandler.c:4503]
     intf_err_seq() [drivers/char/ipmi/ipmi_msghandler.c:1149]
      smi_remove_watch() [drivers/char/ipmi/ipmi_msghandler.c:999]
       set_need_watch() [drivers/char/ipmi/ipmi_si_intf.c:1066]

Upstream commit e1891cffd4 adds code to
ipmi_smi_msg_received() to call smi_remove_watch() via intf_err_seq()
and this seems to be causing the deadlock.

commit e1891cffd4
Author: Corey Minyard <cminyard@mvista.com>
Date:   Wed Oct 24 15:17:04 2018 -0500
    ipmi: Make the smi watcher be disabled immediately when not needed

The fix is to put all messages in the queue and move the message
checking code out of ipmi_smi_msg_received and into handle_one_recv_msg,
which processes the message checking after ipmi_thread releases its
locks.

Additionally,Kosuke Tatsukawa <tatsu@ab.jp.nec.com> reported that
handle_new_recv_msgs calls ipmi_free_msg when handle_one_rcv_msg returns
zero, so that the call to ipmi_free_msg in handle_one_rcv_msg introduced
another panic when "ipmitool sensor list" was run in a loop. He
submitted this part of the patch.

+free_msg:
+               requeue = 0;
+               goto out;

Reported by: Osamu Samukawa <osa-samukawa@tg.jp.nec.com>
Characterized by: Kosuke Tatsukawa <tatsu@ab.jp.nec.com>
Signed-off-by: Tony Camuso <tcamuso@redhat.com>
Fixes: e1891cffd4 ("ipmi: Make the smi watcher be disabled immediately when not needed")
Cc: stable@vger.kernel.org # 5.1
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-08-22 11:08:13 -05:00
Corey Minyard
2033f68589 ipmi: Free receive messages when in an oops
If the driver handles a response in an oops, it was just ignoring
the message.  However, the IPMI watchdog timer was counting on the
free happening to know when panic-time messages were complete.  So
free it in all cases.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-08-16 16:18:18 -05:00
Suzuki K Poulose
92ce7e83b4 driver_find_device: Unify the match function with class_find_device()
The driver_find_device() accepts a match function pointer to
filter the devices for lookup, similar to bus/class_find_device().
However, there is a minor difference in the prototype for the
match parameter for driver_find_device() with the now unified
version accepted by {bus/class}_find_device(), where it doesn't
accept a "const" qualifier for the data argument. This prevents
us from reusing the generic match functions for driver_find_device().

For this reason, change the prototype of the driver_find_device() to
make the "match" parameter in line with {bus/class}_find_device()
and adjust its callers to use the const qualifier. Also, we could
now promote the "data" parameter to const as we pass it down
as a const parameter to the match functions.

Cc: Corey Minyard <minyard@acm.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Peter Oberparleiter <oberpar@linux.ibm.com>
Cc: Sebastian Ott <sebott@linux.ibm.com>
Cc: David Airlie <airlied@linux.ie>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Nehal Shah <nehal-bakulchandra.shah@amd.com>
Cc: Shyam Sundar S K <shyam-sundar.s-k@amd.com>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-06-24 05:22:31 +02:00
Arnd Bergmann
9a75bd18a8 ipmi: avoid atomic_inc in exit function
This causes a link failure on ARM in certain configurations,
when we reference each atomic operation from .alt.smp.init in
order to patch out atomics on non-SMP systems:

`.exit.text' referenced in section `.alt.smp.init' of drivers/char/ipmi/ipmi_msghandler.o: defined in discarded section `.exit.text' of drivers/char/ipmi/ipmi_msghandler.o

In this case, we can trivially replace the atomic_inc() with
an atomic_set() that has the same effect and does not require
a fixup.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Message-Id: <20190415155509.3565087-1-arnd@arndb.de>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-04-17 13:14:25 -05:00
YueHaibing
794a3b6b9f ipmi: Make ipmi_interfaces_srcu variable static
Fix sparse warning:

drivers/char/ipmi/ipmi_msghandler.c:635:20: warning:
 symbol 'ipmi_interfaces_srcu' was not declared. Should it be static?

Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Message-Id: <20190320133505.21984-1-yuehaibing@huawei.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-04-17 13:14:25 -05:00
Corey Minyard
3b9a907223 ipmi: fix sleep-in-atomic in free_user at cleanup SRCU user->release_barrier
free_user() could be called in atomic context.

This patch pushed the free operation off into a workqueue.

Example:

 BUG: sleeping function called from invalid context at kernel/workqueue.c:2856
 in_atomic(): 1, irqs_disabled(): 0, pid: 177, name: ksoftirqd/27
 CPU: 27 PID: 177 Comm: ksoftirqd/27 Not tainted 4.19.25-3 #1
 Hardware name: AIC 1S-HV26-08/MB-DPSB04-06, BIOS IVYBV060 10/21/2015
 Call Trace:
  dump_stack+0x5c/0x7b
  ___might_sleep+0xec/0x110
  __flush_work+0x48/0x1f0
  ? try_to_del_timer_sync+0x4d/0x80
  _cleanup_srcu_struct+0x104/0x140
  free_user+0x18/0x30 [ipmi_msghandler]
  ipmi_free_recv_msg+0x3a/0x50 [ipmi_msghandler]
  deliver_response+0xbd/0xd0 [ipmi_msghandler]
  deliver_local_response+0xe/0x30 [ipmi_msghandler]
  handle_one_recv_msg+0x163/0xc80 [ipmi_msghandler]
  ? dequeue_entity+0xa0/0x960
  handle_new_recv_msgs+0x15c/0x1f0 [ipmi_msghandler]
  tasklet_action_common.isra.22+0x103/0x120
  __do_softirq+0xf8/0x2d7
  run_ksoftirqd+0x26/0x50
  smpboot_thread_fn+0x11d/0x1e0
  kthread+0x103/0x140
  ? sort_range+0x20/0x20
  ? kthread_destroy_worker+0x40/0x40
  ret_from_fork+0x1f/0x40

Fixes: 77f8269606 ("ipmi: fix use-after-free of user->release_barrier.rda")

Reported-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: stable@vger.kernel.org # 5.0
Cc: Yang Yingliang <yangyingliang@huawei.com>
2019-04-17 10:29:27 -05:00
Andy Shevchenko
f32043901a ipmi: Use dedicated API for copying a UUID
Use guid_copy() instead of memcpy() to hide guid_t implementation details and
to show we expect guid_t in a raw buffer.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-02-09 19:48:43 -06:00
Andy Shevchenko
16ccdb552e ipmi: Use defined constant for UUID representation
Instead of magic number use pre-defined constant for UUID binary and
string representations.

While here, drop the implementation details of guid_t type.

Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[Also converted a "17" in the error string to UUID_SIZE + 1]
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-02-09 19:48:43 -06:00
Corey Minyard
e1891cffd4 ipmi: Make the smi watcher be disabled immediately when not needed
The code to tell the lower layer to enable or disable watching for
certain things was lazy in disabling, it waited until a timer tick
to see if a disable was necessary.  Not a really big deal, but it
could be improved.

Modify the code to enable and disable watching immediately and don't
do it from the background timer any more.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Tested-by: Kamlakant Patel <kamlakant.patel@cavium.com>
2019-02-09 19:48:42 -06:00
Corey Minyard
c65ea99659 ipmi: Fix how the lower layers are told to watch for messages
The IPMI driver has a mechanism to tell the lower layers it needs
to watch for messages, commands, and watchdogs (so it doesn't
needlessly poll).  However, it needed some extensions, it needed
a way to tell what is being waited for so it could set the timeout
appropriately.

The update to the lower layer was also being done once a second
at best because it was done in the main timeout handler.  However,
if a command is sent and a response message is coming back,
it needed to be started immediately.  So modify the code to
update immediately if it needs to be enabled.  Disable is still
lazy.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Tested-by: Kamlakant Patel <kamlakant.patel@cavium.com>
2019-02-09 19:48:42 -06:00
Corey Minyard
913a89f009 ipmi: Don't initialize anything in the core until something uses it
The IPMI driver was recently modified to use SRCU, but it turns out
this uses a chunk of percpu memory, even if IPMI is never used.

So modify thing to on initialize on the first use.  There was already
code to sort of handle this for handling init races, so piggy back
on top of that, and simplify it in the process.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
Reported-by: Tejun Heo <tj@kernel.org>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Reviewed-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: stable@vger.kernel.org # 4.18
2019-01-23 11:09:32 -06:00
Yang Yingliang
77f8269606 ipmi: fix use-after-free of user->release_barrier.rda
When we do the following test, we got oops in ipmi_msghandler driver
while((1))
do
	service ipmievd restart & service ipmievd restart
done

---------------------------------------------------------------
[  294.230186] Unable to handle kernel paging request at virtual address 0000803fea6ea008
[  294.230188] Mem abort info:
[  294.230190]   ESR = 0x96000004
[  294.230191]   Exception class = DABT (current EL), IL = 32 bits
[  294.230193]   SET = 0, FnV = 0
[  294.230194]   EA = 0, S1PTW = 0
[  294.230195] Data abort info:
[  294.230196]   ISV = 0, ISS = 0x00000004
[  294.230197]   CM = 0, WnR = 0
[  294.230199] user pgtable: 4k pages, 48-bit VAs, pgdp = 00000000a1c1b75a
[  294.230201] [0000803fea6ea008] pgd=0000000000000000
[  294.230204] Internal error: Oops: 96000004 [#1] SMP
[  294.235211] Modules linked in: nls_utf8 isofs rpcrdma ib_iser ib_srpt target_core_mod ib_srp scsi_transport_srp ib_ipoib rdma_ucm ib_umad rdma_cm ib_cm iw_cm dm_mirror dm_region_hash dm_log dm_mod aes_ce_blk crypto_simd cryptd aes_ce_cipher ghash_ce sha2_ce ses sha256_arm64 sha1_ce hibmc_drm hisi_sas_v2_hw enclosure sg hisi_sas_main sbsa_gwdt ip_tables mlx5_ib ib_uverbs marvell ib_core mlx5_core ixgbe ipmi_si mdio hns_dsaf ipmi_devintf ipmi_msghandler hns_enet_drv hns_mdio
[  294.277745] CPU: 3 PID: 0 Comm: swapper/3 Kdump: loaded Not tainted 5.0.0-rc2+ #113
[  294.285511] Hardware name: Huawei TaiShan 2280 /BC11SPCD, BIOS 1.37 11/21/2017
[  294.292835] pstate: 80000005 (Nzcv daif -PAN -UAO)
[  294.297695] pc : __srcu_read_lock+0x38/0x58
[  294.301940] lr : acquire_ipmi_user+0x2c/0x70 [ipmi_msghandler]
[  294.307853] sp : ffff00001001bc80
[  294.311208] x29: ffff00001001bc80 x28: ffff0000117e5000
[  294.316594] x27: 0000000000000000 x26: dead000000000100
[  294.321980] x25: dead000000000200 x24: ffff803f6bd06800
[  294.327366] x23: 0000000000000000 x22: 0000000000000000
[  294.332752] x21: ffff00001001bd04 x20: ffff80df33d19018
[  294.338137] x19: ffff80df33d19018 x18: 0000000000000000
[  294.343523] x17: 0000000000000000 x16: 0000000000000000
[  294.348908] x15: 0000000000000000 x14: 0000000000000002
[  294.354293] x13: 0000000000000000 x12: 0000000000000000
[  294.359679] x11: 0000000000000000 x10: 0000000000100000
[  294.365065] x9 : 0000000000000000 x8 : 0000000000000004
[  294.370451] x7 : 0000000000000000 x6 : ffff80df34558678
[  294.375836] x5 : 000000000000000c x4 : 0000000000000000
[  294.381221] x3 : 0000000000000001 x2 : 0000803fea6ea000
[  294.386607] x1 : 0000803fea6ea008 x0 : 0000000000000001
[  294.391994] Process swapper/3 (pid: 0, stack limit = 0x0000000083087293)
[  294.398791] Call trace:
[  294.401266]  __srcu_read_lock+0x38/0x58
[  294.405154]  acquire_ipmi_user+0x2c/0x70 [ipmi_msghandler]
[  294.410716]  deliver_response+0x80/0xf8 [ipmi_msghandler]
[  294.416189]  deliver_local_response+0x28/0x68 [ipmi_msghandler]
[  294.422193]  handle_one_recv_msg+0x158/0xcf8 [ipmi_msghandler]
[  294.432050]  handle_new_recv_msgs+0xc0/0x210 [ipmi_msghandler]
[  294.441984]  smi_recv_tasklet+0x8c/0x158 [ipmi_msghandler]
[  294.451618]  tasklet_action_common.isra.5+0x88/0x138
[  294.460661]  tasklet_action+0x2c/0x38
[  294.468191]  __do_softirq+0x120/0x2f8
[  294.475561]  irq_exit+0x134/0x140
[  294.482445]  __handle_domain_irq+0x6c/0xc0
[  294.489954]  gic_handle_irq+0xb8/0x178
[  294.497037]  el1_irq+0xb0/0x140
[  294.503381]  arch_cpu_idle+0x34/0x1a8
[  294.510096]  do_idle+0x1d4/0x290
[  294.516322]  cpu_startup_entry+0x28/0x30
[  294.523230]  secondary_start_kernel+0x184/0x1d0
[  294.530657] Code: d538d082 d2800023 8b010c81 8b020021 (c85f7c25)
[  294.539746] ---[ end trace 8a7a880dee570b29 ]---
[  294.547341] Kernel panic - not syncing: Fatal exception in interrupt
[  294.556837] SMP: stopping secondary CPUs
[  294.563996] Kernel Offset: disabled
[  294.570515] CPU features: 0x002,21006008
[  294.577638] Memory Limit: none
[  294.587178] Starting crashdump kernel...
[  294.594314] Bye!

Because the user->release_barrier.rda is freed in ipmi_destroy_user(), but
the refcount is not zero, when acquire_ipmi_user() uses user->release_barrier.rda
in __srcu_read_lock(), it causes oops.
Fix this by calling cleanup_srcu_struct() when the refcount is zero.

Fixes: e86ee2d44b ("ipmi: Rework locking and shutdown for hot remove")
Cc: stable@vger.kernel.org # 4.18
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-01-23 10:44:23 -06:00
Fred Klassen
479d6b39b9 ipmi: Prevent use-after-free in deliver_response
Some IPMI modules (e.g. ibmpex_msg_handler()) will have ipmi_usr_hdlr
handlers that call ipmi_free_recv_msg() directly. This will essentially
kfree(msg), leading to use-after-free.

This does not happen in the ipmi_devintf module, which will queue the
message and run ipmi_free_recv_msg() later.

BUG: KASAN: use-after-free in deliver_response+0x12f/0x1b0
Read of size 8 at addr ffff888a7bf20018 by task ksoftirqd/3/27
CPU: 3 PID: 27 Comm: ksoftirqd/3 Tainted: G           O      4.19.11-amd64-ani99-debug #12.0.1.601133+pv
Hardware name: AppNeta r1000/X11SPW-TF, BIOS 2.1a-AP 09/17/2018
Call Trace:
dump_stack+0x92/0xeb
print_address_description+0x73/0x290
kasan_report+0x258/0x380
deliver_response+0x12f/0x1b0
? ipmi_free_recv_msg+0x50/0x50
deliver_local_response+0xe/0x50
handle_one_recv_msg+0x37a/0x21d0
handle_new_recv_msgs+0x1ce/0x440
...

Allocated by task 9885:
kasan_kmalloc+0xa0/0xd0
kmem_cache_alloc_trace+0x116/0x290
ipmi_alloc_recv_msg+0x28/0x70
i_ipmi_request+0xb4a/0x1640
ipmi_request_settime+0x1b8/0x1e0
...

Freed by task 27:
__kasan_slab_free+0x12e/0x180
kfree+0xe9/0x280
deliver_response+0x122/0x1b0
deliver_local_response+0xe/0x50
handle_one_recv_msg+0x37a/0x21d0
handle_new_recv_msgs+0x1ce/0x440
tasklet_action_common.isra.19+0xc4/0x250
__do_softirq+0x11f/0x51f

Fixes: e86ee2d44b ("ipmi: Rework locking and shutdown for hot remove")
Cc: stable@vger.kernel.org # 4.18
Signed-off-by: Fred Klassen <fklassen@appneta.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-01-23 10:44:45 -06:00
Gustavo A. R. Silva
a7102c7461 ipmi: msghandler: Fix potential Spectre v1 vulnerabilities
channel and addr->channel are indirectly controlled by user-space,
hence leading to a potential exploitation of the Spectre variant 1
vulnerability.

These issues were detected with the help of Smatch:

drivers/char/ipmi/ipmi_msghandler.c:1381 ipmi_set_my_address() warn: potential spectre issue 'user->intf->addrinfo' [w] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:1401 ipmi_get_my_address() warn: potential spectre issue 'user->intf->addrinfo' [r] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:1421 ipmi_set_my_LUN() warn: potential spectre issue 'user->intf->addrinfo' [w] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:1441 ipmi_get_my_LUN() warn: potential spectre issue 'user->intf->addrinfo' [r] (local cap)
drivers/char/ipmi/ipmi_msghandler.c:2260 check_addr() warn: potential spectre issue 'intf->addrinfo' [r] (local cap)

Fix this by sanitizing channel and addr->channel before using them to
index user->intf->addrinfo and intf->addrinfo, correspondingly.

Notice that given that speculation windows are large, the policy is
to kill the speculation on the first load and not worry if it can be
completed with a dependent load/store [1].

[1] https://lore.kernel.org/lkml/20180423164740.GY17484@dhcp22.suse.cz/

Cc: stable@vger.kernel.org
Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2019-01-23 10:44:23 -06:00
YueHaibing
060e8fb53f ipmi: fix return value of ipmi_set_my_LUN
Fixes gcc '-Wunused-but-set-variable' warning:

drivers/char/ipmi/ipmi_msghandler.c: In function 'ipmi_set_my_LUN':
drivers/char/ipmi/ipmi_msghandler.c:1335:13: warning:
 variable 'rv' set but not used [-Wunused-but-set-variable]
  int index, rv = 0;

'rv' should be the correct return value.

Fixes: 048f7c3e35 ("ipmi: Properly release srcu locks on error conditions")
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-09-18 16:15:33 -05:00
Joe Perches
445e2cbda9 ipmi: msghandler: Add and use pr_fmt and dev_fmt, remove PFX
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>
2018-09-18 16:15:33 -05:00
Corey Minyard
2512e40e48 ipmi: Rework SMI registration failure
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
2018-08-31 08:42:29 -05:00
Corey Minyard
048f7c3e35 ipmi: Properly release srcu locks on error conditions
When SRCU was added for handling hotplug, some error conditions
were not handled properly.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-05-24 15:08:30 -05:00
Corey Minyard
163475ebf9 ipmi: Remove the proc interface
It has been deprecated long enough, get rid of it.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-05-09 12:21:46 -05:00
Corey Minyard
6a0d23ed33 ipmi: ipmi_unregister_smi() cannot fail, have it return void
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-04-18 10:23:05 -05:00
Corey Minyard
8d17929ad5 ipmi: Remove condition on interface shutdown
Now that the interfaces have shutdown handlers, this no longer
needs to be conditional.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-04-18 10:23:01 -05:00
Corey Minyard
e86ee2d44b ipmi: Rework locking and shutdown for hot remove
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>
2018-04-18 10:22:58 -05:00
Corey Minyard
ac93bd0c9e ipmi: Fix some counter issues
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>
2018-04-18 10:22:57 -05:00
Corey Minyard
a567b62300 ipmi: Change ipmi_smi_t to struct ipmi_smi *
Get rid of this coding style violation in the user files.  Include
files will come later.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-04-18 10:22:56 -05:00
Corey Minyard
2911c9886c ipmi: Rename ipmi_user_t to struct ipmi_user *
Get rid of that non-compliance in the user files.  Include files
will come later.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-04-18 10:22:55 -05:00
Corey Minyard
aa7a8f9e1b ipmi: Clean up some style issues in the message handler
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-04-18 10:22:52 -05:00
Corey Minyard
42c2dc7e66 ipmi: Break up i_ipmi_request
It was huge, and easily broken into pieces.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-04-18 10:22:51 -05:00
Corey Minyard
f41382ae57 ipmi: Clean up some debug code
Replace ifdefs in the code with a simple function.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2018-04-18 10:22:48 -05:00
Corey Minyard
91e2dd0a47 ipmi: Add a panic handler for IPMI users
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>
2018-04-18 10:22:47 -05:00
Corey Minyard
252e30c1e7 ipmi: Add a maintenance mode for IPMB messages
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>
2018-04-18 10:22:43 -05:00
Corey Minyard
ce7fa1c38d ipmi: Add a way to tune some timeouts
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
2018-04-18 10:22:42 -05:00
Corey Minyard
243ac21035 ipmi: Add or fix SPDX-License-Identifier in all files
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>
2018-02-27 07:42:51 -06:00
Linus Torvalds
47fcc0360c Driver Core updates for 4.16-rc1
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.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWnLvPw8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+ynNzACgkzjPoBytJWbpWFt6SR6L33/u4kEAnRFvVCGL
 s6ygQPQhZIjKk2Lxa2hC
 =Zihy
 -----END PGP SIGNATURE-----

Merge tag 'driver-core-4.16-rc1' of 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
  ...
2018-02-01 10:00:28 -08:00
Joe Perches
c828a89203 treewide: Use DEVICE_ATTR_RO
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>
2018-01-09 16:34:34 +01:00
Xiongfeng Wang
1b4254cee0 ipmi: use correct string length
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>
2018-01-08 20:02:47 -06:00
Kees Cook
e99e88a9d2 treewide: setup_timer() -> timer_setup()
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>
2017-11-21 15:57:07 -08:00
Colin Ian King
b79bba15b3 ipmi: remove redundant initialization of bmc
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>
2017-09-28 12:29:44 -05:00
Corey Minyard
106a846102 ipmi: Clean up some print operations
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>
2017-09-28 12:26:04 -05:00
Corey Minyard
95e300c052 ipmi: Make the DMI probe into a generic platform probe
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>
2017-09-28 12:26:03 -05:00
Corey Minyard
55f91cb6f1 ipmi: Make the IPMI proc interface configurable
So we can remove it later.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-28 12:26:03 -05:00
Corey Minyard
3fd32f9ec8 ipmi: Convert IPMI GUID over to Linux guid_t
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
31b0b0730a ipmi: Rescan channel list on BMC changes
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
5fdb1fb2ab ipmi: Move lun and address out of channel struct
Put it in it's own struct, getting ready for channel information
being dynamically changed.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
c0734bd594 ipmi: Retry BMC registration on a failure
If the BMC fails to register, just set up to retry periodically.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
b2cfd8ab4a ipmi: Rework device id and guid handling to catch changing BMCs
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
c659ff34f6 ipmi: Use a temporary BMC for an interface
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
28f26ac7a9 ipmi: Dynamically fetch GUID periodically
This will catch if the GUID changes.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
39d3fb4560 ipmi: Always fetch the guid through ipmi_get_device_id()
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
1e5058ea21 ipmi: Remove the device id from ipmi_register_smi()
It's no longer used, dynamic device id handling is in place now.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Jeremy Kerr
aa9c9ab244 ipmi: allow dynamic BMC version information
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
68e7e50f19 ipmi: Don't use BMC product/dev ids in the BMC name
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>
2017-09-27 16:03:45 -05:00
Jeremy Kerr
a9137c3dfa ipmi: Add a reference from BMC devices to their interfaces
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
511d57dc71 ipmi: Get the device id through a function
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
9b64a8ba90 ipmi: Fix printing the BMC guid
It was just wrong.  Make it print according to the guid spec.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
a2cb600fa2 ipmi: Rework BMC registration
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
9ca15af316 ipmi: Fix issues with BMC refcounts
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
eae4a36a68 ipmi: Check that the device type is BMC when scanning device
Just an added safety check.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
f33e4df83e ipmi: Move bmc find routing to below bmc device type
No functional change, this is for a later change that uses the
bmc device type.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
72630d9a01 ipmi: Fix getting the GUID data
It was off by one.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-09-27 16:03:45 -05:00
Corey Minyard
1c9f98d1bf ipmi: Make IPMI panic strings always available
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>
2017-09-27 16:03:45 -05:00
Corey Minyard
392a17b10e ipmi: fix unsigned long underflow
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
2017-09-27 16:03:45 -05:00
Arvind Yadav
1e7a75f74a char: ipmi: constify bmc_dev_attr_group and bmc_device_type
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>
2017-06-28 20:56:36 -05:00
Tony Camuso
cdea46566b ipmi: use rcu lock around call to intf->handlers->sender()
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 7ea0ed2b5b 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>
2017-06-19 12:49:34 -05:00
Corey Minyard
210af2a5f1 ipmi: make ipmi_usr_hndl const
It's only function pointers.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2017-01-05 15:01:55 -06:00
Martin Wilck
070cbd1d42 ipmi: create hardware-independent softdep for ipmi_devintf
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>
2016-12-12 14:26:29 -06:00
Corey Minyard
a24b5dd5ed ipmi: Fix sequence number handling
The IPMI message handler uses a message id that the lower-layer
preserved to track the sequence number of the message.  The macros
that handled these sequence numbers were somewhat broken as they
could result in sequence number truncation and they were not
doing an "and" of the proper number of bits.

I think this actually is not a problem, because the truncation
should be harmless and the improper "and" didn't hurt anything
because sequence number generation used the same improper "and"
and wouldn't generate a sequence number that would get
truncated wrong.  However, it should be fixed.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2016-11-24 18:09:49 -06:00
Xie XiuQi
bd85f4b37d ipmi: fix crash on reading version from proc after unregisted bmc
I meet a crash, which could be reproduce:
1) while true; do cat /proc/ipmi/0/version; done
2) modprobe -rv ipmi_si ipmi_msghandler ipmi_devintf

[82761.021137] IPMI BT: req2rsp=5 secs retries=2
[82761.034524] ipmi device interface
[82761.222218] ipmi_si ipmi_si.0: Found new BMC (man_id: 0x0007db, prod_id: 0x0001, dev_id: 0x01)
[82761.222230] ipmi_si ipmi_si.0: IPMI bt interface initialized
[82903.922740] BUG: unable to handle kernel NULL pointer dereference at 00000000000002d4
[82903.930952] IP: [<ffffffffa030d9e8>] smi_version_proc_show+0x18/0x40 [ipmi_msghandler]
[82903.939220] PGD 86693a067 PUD 865304067 PMD 0
[82903.943893] Thread overran stack, or stack corrupted
[82903.949034] Oops: 0000 [#1] SMP
[82903.983091] Modules linked in: ipmi_si(-) ipmi_msghandler binfmt_misc ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter
...
[82904.057285]  pps_core scsi_transport_sas dm_mod vfio_iommu_type1 vfio xt_sctp nf_conntrack_proto_sctp nf_nat_proto_sctp
                nf_nat nf_conntrack sctp libcrc32c [last unloaded: ipmi_devintf]
[82904.073169] CPU: 37 PID: 28089 Comm: cat Tainted: GF          O   ---- -------   3.10.0-327.28.3.el7.x86_64 #1
[82904.083373] Hardware name: Huawei RH2288H V3/BC11HGSA0, BIOS 3.22 05/16/2016
[82904.090592] task: ffff880101cc2e00 ti: ffff880369c54000 task.ti: ffff880369c54000
[82904.098414] RIP: 0010:[<ffffffffa030d9e8>]  [<ffffffffa030d9e8>] smi_version_proc_show+0x18/0x40 [ipmi_msghandler]
[82904.109124] RSP: 0018:ffff880369c57e70  EFLAGS: 00010203
[82904.114608] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000024688470
[82904.121912] RDX: fffffffffffffff4 RSI: ffffffffa0313404 RDI: ffff8808670ce200
[82904.129218] RBP: ffff880369c57e70 R08: 0000000000019720 R09: ffffffff81204a27
[82904.136521] R10: ffff88046f803300 R11: 0000000000000246 R12: ffff880662399700
[82904.143828] R13: 0000000000000001 R14: ffff880369c57f48 R15: ffff8808670ce200
[82904.151128] FS:  00007fb70c9ca740(0000) GS:ffff88086e340000(0000) knlGS:0000000000000000
[82904.159557] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[82904.165473] CR2: 00000000000002d4 CR3: 0000000864c0c000 CR4: 00000000003407e0
[82904.172778] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[82904.180084] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[82904.187385] Stack:
[82904.189573]  ffff880369c57ee0 ffffffff81204f1a 00000000122a2427 0000000001426000
[82904.197392]  ffff8808670ce238 0000000000010000 0000000000000000 0000000000000fff
[82904.205198]  00000000122a2427 ffff880862079600 0000000001426000 ffff880369c57f48
[82904.212962] Call Trace:
[82904.219667]  [<ffffffff81204f1a>] seq_read+0xfa/0x3a0
[82904.224893]  [<ffffffff8124ce2d>] proc_reg_read+0x3d/0x80
[82904.230468]  [<ffffffff811e102c>] vfs_read+0x9c/0x170
[82904.235689]  [<ffffffff811e1b7f>] SyS_read+0x7f/0xe0
[82904.240816]  [<ffffffff81649209>] system_call_fastpath+0x16/0x1b
[82904.246991] Code: 30 a0 e8 0c 6f ef e0 5b 5d c3 66 0f 1f 84 00 00 00 00 00 0f 1f
               44 00 00 48 8b 47 78 55 48 c7 c6 04 34 31 a0 48 89 e5 48 8b 40 50 <0f>
	       b6 90 d4 02 00 00 31 c0 89 d1 83 e2 0f c0 e9 04 0f b6 c9 e8
[82904.267710] RIP  [<ffffffffa030d9e8>] smi_version_proc_show+0x18/0x40 [ipmi_msghandler]
[82904.276079]  RSP <ffff880369c57e70>
[82904.279734] CR2: 00000000000002d4
[82904.283731] ---[ end trace a69e4328b49dd7c4 ]---
[82904.328118] Kernel panic - not syncing: Fatal exception

Reading versin from /proc need bmc device struct available. So in this patch
we move add/remove_proc_entries between ipmi_bmc_register and ipmi_bmc_unregister.

Cc: Kefeng Wang <wangkefeng.wang@huawei.com>
Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2016-10-03 09:09:47 -05:00
Tony Camuso
b07b58a3e4 ipmi: remove trydefaults parameter and default init
Parameter trydefaults=1 causes the ipmi_init to initialize ipmi through
the legacy port io space that was designated for ipmi. Architectures
that do not map legacy port io can panic when trydefaults=1.

Rather than implement build-time conditional exceptions for each
architecture that does not map legacy port io, we have removed legacy
port io from the driver.

Parameter 'trydefaults' has been removed. Attempts to use it hereafter
will evoke the "Unknown symbol in module, or unknown parameter" message.

The patch was built against a number of architectures and tested for
regressions and functionality on x86_64 and ARM64.

Signed-off-by: Tony Camuso <tcamuso@redhat.com>

Removed the config entry and the address source entry for default,
since neither were used any more.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2016-07-27 10:24:38 -05:00
Junichi Nomura
ae4ea9a246 ipmi: Remove smi_msg from waiting_rcv_msgs list before handle_one_recv_msg()
Commit 7ea0ed2b5b ("ipmi: Make the message handler easier to use for
SMI interfaces") changed handle_new_recv_msgs() to call handle_one_recv_msg()
for a smi_msg while the smi_msg is still connected to waiting_rcv_msgs list.
That could lead to following list corruption problems:

1) low-level function treats smi_msg as not connected to list

  handle_one_recv_msg() could end up calling smi_send(), which
  assumes the msg is not connected to list.

  For example, the following sequence could corrupt list by
  doing list_add_tail() for the entry still connected to other list.

    handle_new_recv_msgs()
      msg = list_entry(waiting_rcv_msgs)
      handle_one_recv_msg(msg)
        handle_ipmb_get_msg_cmd(msg)
          smi_send(msg)
            spin_lock(xmit_msgs_lock)
            list_add_tail(msg)
            spin_unlock(xmit_msgs_lock)

2) race between multiple handle_new_recv_msgs() instances

  handle_new_recv_msgs() once releases waiting_rcv_msgs_lock before calling
  handle_one_recv_msg() then retakes the lock and list_del() it.

  If others call handle_new_recv_msgs() during the window shown below
  list_del() will be done twice for the same smi_msg.

  handle_new_recv_msgs()
    spin_lock(waiting_rcv_msgs_lock)
    msg = list_entry(waiting_rcv_msgs)
    spin_unlock(waiting_rcv_msgs_lock)
  |
  | handle_one_recv_msg(msg)
  |
    spin_lock(waiting_rcv_msgs_lock)
    list_del(msg)
    spin_unlock(waiting_rcv_msgs_lock)

Fixes: 7ea0ed2b5b ("ipmi: Make the message handler easier to use for SMI interfaces")
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
[Added a comment to describe why this works.]
Signed-off-by: Corey Minyard <cminyard@mvista.com>
Cc: stable@vger.kernel.org # 3.19
Tested-by: Ye Feng <yefeng.yl@alibaba-inc.com>
2016-06-13 08:56:28 -05:00
LABBE Corentin
99ee67351b ipmi: constify some struct and char arrays
Lots of char arrays could be set as const since they contain only literal
char arrays.
We could in the same time make const some struct members who are pointer
to those const char arrays.

Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2016-01-12 15:08:49 -06:00
Hidehiro Kawai
c49c097610 ipmi: Don't call receive handler in the panic context
Received handlers defined as ipmi_recv_hndl member of struct
ipmi_user_hndl can take a spinlock.  This means that if the kernel
panics while holding the lock, a deadlock may happen on the lock
while flushing queued messages in the panic context.

Calling the receive handler doesn't make much meanings in the panic
context, simply skip it to avoid possible deadlocks.

Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-09-03 15:02:29 -05:00
Hidehiro Kawai
06e5e345fe ipmi: Avoid touching possible corrupted lists in the panic context
When processing queued messages in the panic context, IPMI driver
tries to do it without any locking to avoid deadlocks.  However,
this means we can touch a corrupted list if the kernel panicked
while manipulating the list.  Fortunately, current `add-tail and
del-from-head' style implementation won't touch the corrupted part,
but it is inherently risky.

To get rid of the risk, this patch re-initializes the message lists
on panic if the related spinlock has already been acquired.  As the
result, we may lose queued messages, but it's not so painful.
Dropping messages on the received message list is also less
problematic because no one can respond the received messages.

Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>

Fixed a comment typo.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-09-03 15:02:29 -05:00
Hidehiro Kawai
82802f968b ipmi: Don't flush messages in sender() in run-to-completion mode
When flushing queued messages in run-to-completion mode,
smi_event_handler() is recursively called.

flush_messages()
 smi_event_handler()
  handle_transaction_done()
   deliver_recv_msg()
    ipmi_smi_msg_received()
     smi_recv_tasklet()
      sender()
       flush_messages()
        smi_event_handler()
         ...

The depth of the recursive call depends on the number of queued
messages, so it can cause a stack overflow if many messages have
been queued.

To solve this problem, this patch removes flush_messages()
from sender()@ipmi_si_intf.c.  Instead, add flush_messages() to
caller side of sender() if needed.  Additionally, to implement this,
add new handler flush_messages to struct ipmi_smi_handlers.

Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>

Fixed up a comment and some spacing issues.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-09-03 15:02:28 -05:00
Hidehiro Kawai
b0868dd5c1 ipmi: Remove unneeded set_run_to_completion call
send_panic_events() calls intf->handlers->set_run_to_completion(),
but it has already been done in the caller function panic_event().
Remove it from send_panic_events().

Signed-off-by: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-09-03 15:02:27 -05:00
Corey Minyard
81d02b7f8c ipmi: Make some data const that was only read
Several data structures were only used for reading, so make them
const.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-09-03 15:02:27 -05:00
Corey Minyard
b2234ee9fc ipmi: Add a comment in how messages are delivered from the lower layer
To avoid confusion in the future.

Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-09-03 15:02:24 -05:00
Joe Perches
5e33cd0c5a ipmi: Remove incorrect use of seq_has_overflowed
commit d6c5dc18d8 ("ipmi: Remove uses of return value of seq_printf")
incorrectly changed the return value of various proc_show functions
to use seq_has_overflowed().

These functions should return 0 on completion rather than 1/true
on overflow.  1 is the same as #define SEQ_SKIP which would cause
the output to not be emitted (skipped) instead.

This is a logical defect only as the length of these outputs are
all smaller than the initial allocation done by the seq filesystem.

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-05-05 14:24:46 -05:00
Joe Perches
d6c5dc18d8 ipmi: Remove uses of return value of seq_printf
The seq_printf like functions will soon be changed to return void.

Convert these uses to check seq_has_overflowed instead.

Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-02-19 20:58:41 -06:00
Takashi Iwai
2d06a0c9b3 ipmi: Use is_visible callback for conditional sysfs entries
Instead of manual calls of device_create_file() and
device_remove_file(), implement the condition in is_visible callback
for the attribute group and put these entries to the group, too.
This simplifies the code and avoids the possible races.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
2015-02-19 20:58:40 -06:00