1 // SPDX-License-Identifier: GPL-2.0+
5 * Linux device interface for the IPMI message handler.
7 * Author: MontaVista Software, Inc.
11 * Copyright 2002 MontaVista Software Inc.
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/errno.h>
17 #include <linux/poll.h>
18 #include <linux/sched.h>
19 #include <linux/spinlock.h>
20 #include <linux/slab.h>
21 #include <linux/ipmi.h>
22 #include <linux/mutex.h>
23 #include <linux/init.h>
24 #include <linux/device.h>
25 #include <linux/compat.h>
27 struct ipmi_file_private
29 struct ipmi_user *user;
30 spinlock_t recv_msg_lock;
31 struct list_head recv_msgs;
32 struct fasync_struct *fasync_queue;
33 wait_queue_head_t wait;
34 struct mutex recv_mutex;
36 unsigned int default_retry_time_ms;
39 static void file_receive_handler(struct ipmi_recv_msg *msg,
42 struct ipmi_file_private *priv = handler_data;
46 spin_lock_irqsave(&priv->recv_msg_lock, flags);
47 was_empty = list_empty(&priv->recv_msgs);
48 list_add_tail(&msg->link, &priv->recv_msgs);
49 spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
52 wake_up_interruptible(&priv->wait);
53 kill_fasync(&priv->fasync_queue, SIGIO, POLL_IN);
57 static __poll_t ipmi_poll(struct file *file, poll_table *wait)
59 struct ipmi_file_private *priv = file->private_data;
63 poll_wait(file, &priv->wait, wait);
65 spin_lock_irqsave(&priv->recv_msg_lock, flags);
67 if (!list_empty(&priv->recv_msgs))
68 mask |= (EPOLLIN | EPOLLRDNORM);
70 spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
75 static int ipmi_fasync(int fd, struct file *file, int on)
77 struct ipmi_file_private *priv = file->private_data;
79 return fasync_helper(fd, file, on, &priv->fasync_queue);
82 static const struct ipmi_user_hndl ipmi_hndlrs =
84 .ipmi_recv_hndl = file_receive_handler,
87 static int ipmi_open(struct inode *inode, struct file *file)
89 int if_num = iminor(inode);
91 struct ipmi_file_private *priv;
93 priv = kmalloc(sizeof(*priv), GFP_KERNEL);
97 rv = ipmi_create_user(if_num,
106 file->private_data = priv;
108 spin_lock_init(&priv->recv_msg_lock);
109 INIT_LIST_HEAD(&priv->recv_msgs);
110 init_waitqueue_head(&priv->wait);
111 priv->fasync_queue = NULL;
112 mutex_init(&priv->recv_mutex);
114 /* Use the low-level defaults. */
115 priv->default_retries = -1;
116 priv->default_retry_time_ms = 0;
122 static int ipmi_release(struct inode *inode, struct file *file)
124 struct ipmi_file_private *priv = file->private_data;
126 struct ipmi_recv_msg *msg, *next;
128 rv = ipmi_destroy_user(priv->user);
132 list_for_each_entry_safe(msg, next, &priv->recv_msgs, link)
133 ipmi_free_recv_msg(msg);
140 static int handle_send_req(struct ipmi_user *user,
141 struct ipmi_req *req,
143 unsigned int retry_time_ms)
146 struct ipmi_addr addr;
147 struct kernel_ipmi_msg msg;
149 if (req->addr_len > sizeof(struct ipmi_addr))
152 if (copy_from_user(&addr, req->addr, req->addr_len))
155 msg.netfn = req->msg.netfn;
156 msg.cmd = req->msg.cmd;
157 msg.data_len = req->msg.data_len;
158 msg.data = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL);
162 /* From here out we cannot return, we must jump to "out" for
163 error exits to free msgdata. */
165 rv = ipmi_validate_addr(&addr, req->addr_len);
169 if (req->msg.data != NULL) {
170 if (req->msg.data_len > IPMI_MAX_MSG_LENGTH) {
175 if (copy_from_user(msg.data,
177 req->msg.data_len)) {
185 rv = ipmi_request_settime(user,
198 static int handle_recv(struct ipmi_file_private *priv,
199 bool trunc, struct ipmi_recv *rsp,
200 int (*copyout)(struct ipmi_recv *, void __user *),
204 struct list_head *entry;
205 struct ipmi_recv_msg *msg;
209 /* We claim a mutex because we don't want two
210 users getting something from the queue at a time.
211 Since we have to release the spinlock before we can
212 copy the data to the user, it's possible another
213 user will grab something from the queue, too. Then
214 the messages might get out of order if something
215 fails and the message gets put back onto the
216 queue. This mutex prevents that problem. */
217 mutex_lock(&priv->recv_mutex);
219 /* Grab the message off the list. */
220 spin_lock_irqsave(&priv->recv_msg_lock, flags);
221 if (list_empty(&(priv->recv_msgs))) {
222 spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
226 entry = priv->recv_msgs.next;
227 msg = list_entry(entry, struct ipmi_recv_msg, link);
229 spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
231 addr_len = ipmi_addr_length(msg->addr.addr_type);
232 if (rsp->addr_len < addr_len) {
234 goto recv_putback_on_err;
237 if (copy_to_user(rsp->addr, &msg->addr, addr_len)) {
239 goto recv_putback_on_err;
241 rsp->addr_len = addr_len;
243 rsp->recv_type = msg->recv_type;
244 rsp->msgid = msg->msgid;
245 rsp->msg.netfn = msg->msg.netfn;
246 rsp->msg.cmd = msg->msg.cmd;
248 if (msg->msg.data_len > 0) {
249 if (rsp->msg.data_len < msg->msg.data_len) {
252 msg->msg.data_len = rsp->msg.data_len;
255 goto recv_putback_on_err;
259 if (copy_to_user(rsp->msg.data,
261 msg->msg.data_len)) {
263 goto recv_putback_on_err;
265 rsp->msg.data_len = msg->msg.data_len;
267 rsp->msg.data_len = 0;
270 rv = copyout(rsp, to);
272 goto recv_putback_on_err;
274 mutex_unlock(&priv->recv_mutex);
275 ipmi_free_recv_msg(msg);
279 /* If we got an error, put the message back onto
280 the head of the queue. */
281 spin_lock_irqsave(&priv->recv_msg_lock, flags);
282 list_add(entry, &priv->recv_msgs);
283 spin_unlock_irqrestore(&priv->recv_msg_lock, flags);
285 mutex_unlock(&priv->recv_mutex);
289 static int copyout_recv(struct ipmi_recv *rsp, void __user *to)
291 return copy_to_user(to, rsp, sizeof(struct ipmi_recv)) ? -EFAULT : 0;
294 static long ipmi_ioctl(struct file *file,
299 struct ipmi_file_private *priv = file->private_data;
300 void __user *arg = (void __user *)data;
304 case IPMICTL_SEND_COMMAND:
308 unsigned int retry_time_ms;
310 if (copy_from_user(&req, arg, sizeof(req))) {
315 mutex_lock(&priv->recv_mutex);
316 retries = priv->default_retries;
317 retry_time_ms = priv->default_retry_time_ms;
318 mutex_unlock(&priv->recv_mutex);
320 rv = handle_send_req(priv->user, &req, retries, retry_time_ms);
324 case IPMICTL_SEND_COMMAND_SETTIME:
326 struct ipmi_req_settime req;
328 if (copy_from_user(&req, arg, sizeof(req))) {
333 rv = handle_send_req(priv->user,
340 case IPMICTL_RECEIVE_MSG:
341 case IPMICTL_RECEIVE_MSG_TRUNC:
343 struct ipmi_recv rsp;
345 if (copy_from_user(&rsp, arg, sizeof(rsp)))
348 rv = handle_recv(priv, cmd == IPMICTL_RECEIVE_MSG_TRUNC,
349 &rsp, copyout_recv, arg);
353 case IPMICTL_REGISTER_FOR_CMD:
355 struct ipmi_cmdspec val;
357 if (copy_from_user(&val, arg, sizeof(val))) {
362 rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
367 case IPMICTL_UNREGISTER_FOR_CMD:
369 struct ipmi_cmdspec val;
371 if (copy_from_user(&val, arg, sizeof(val))) {
376 rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
381 case IPMICTL_REGISTER_FOR_CMD_CHANS:
383 struct ipmi_cmdspec_chans val;
385 if (copy_from_user(&val, arg, sizeof(val))) {
390 rv = ipmi_register_for_cmd(priv->user, val.netfn, val.cmd,
395 case IPMICTL_UNREGISTER_FOR_CMD_CHANS:
397 struct ipmi_cmdspec_chans val;
399 if (copy_from_user(&val, arg, sizeof(val))) {
404 rv = ipmi_unregister_for_cmd(priv->user, val.netfn, val.cmd,
409 case IPMICTL_SET_GETS_EVENTS_CMD:
413 if (copy_from_user(&val, arg, sizeof(val))) {
418 rv = ipmi_set_gets_events(priv->user, val);
422 /* The next four are legacy, not per-channel. */
423 case IPMICTL_SET_MY_ADDRESS_CMD:
427 if (copy_from_user(&val, arg, sizeof(val))) {
432 rv = ipmi_set_my_address(priv->user, 0, val);
436 case IPMICTL_GET_MY_ADDRESS_CMD:
441 rv = ipmi_get_my_address(priv->user, 0, &rval);
447 if (copy_to_user(arg, &val, sizeof(val))) {
454 case IPMICTL_SET_MY_LUN_CMD:
458 if (copy_from_user(&val, arg, sizeof(val))) {
463 rv = ipmi_set_my_LUN(priv->user, 0, val);
467 case IPMICTL_GET_MY_LUN_CMD:
472 rv = ipmi_get_my_LUN(priv->user, 0, &rval);
478 if (copy_to_user(arg, &val, sizeof(val))) {
485 case IPMICTL_SET_MY_CHANNEL_ADDRESS_CMD:
487 struct ipmi_channel_lun_address_set val;
489 if (copy_from_user(&val, arg, sizeof(val))) {
494 return ipmi_set_my_address(priv->user, val.channel, val.value);
497 case IPMICTL_GET_MY_CHANNEL_ADDRESS_CMD:
499 struct ipmi_channel_lun_address_set val;
501 if (copy_from_user(&val, arg, sizeof(val))) {
506 rv = ipmi_get_my_address(priv->user, val.channel, &val.value);
510 if (copy_to_user(arg, &val, sizeof(val))) {
517 case IPMICTL_SET_MY_CHANNEL_LUN_CMD:
519 struct ipmi_channel_lun_address_set val;
521 if (copy_from_user(&val, arg, sizeof(val))) {
526 rv = ipmi_set_my_LUN(priv->user, val.channel, val.value);
530 case IPMICTL_GET_MY_CHANNEL_LUN_CMD:
532 struct ipmi_channel_lun_address_set val;
534 if (copy_from_user(&val, arg, sizeof(val))) {
539 rv = ipmi_get_my_LUN(priv->user, val.channel, &val.value);
543 if (copy_to_user(arg, &val, sizeof(val))) {
550 case IPMICTL_SET_TIMING_PARMS_CMD:
552 struct ipmi_timing_parms parms;
554 if (copy_from_user(&parms, arg, sizeof(parms))) {
559 mutex_lock(&priv->recv_mutex);
560 priv->default_retries = parms.retries;
561 priv->default_retry_time_ms = parms.retry_time_ms;
562 mutex_unlock(&priv->recv_mutex);
567 case IPMICTL_GET_TIMING_PARMS_CMD:
569 struct ipmi_timing_parms parms;
571 mutex_lock(&priv->recv_mutex);
572 parms.retries = priv->default_retries;
573 parms.retry_time_ms = priv->default_retry_time_ms;
574 mutex_unlock(&priv->recv_mutex);
576 if (copy_to_user(arg, &parms, sizeof(parms))) {
585 case IPMICTL_GET_MAINTENANCE_MODE_CMD:
589 mode = ipmi_get_maintenance_mode(priv->user);
590 if (copy_to_user(arg, &mode, sizeof(mode))) {
598 case IPMICTL_SET_MAINTENANCE_MODE_CMD:
602 if (copy_from_user(&mode, arg, sizeof(mode))) {
606 rv = ipmi_set_maintenance_mode(priv->user, mode);
620 * The following code contains code for supporting 32-bit compatible
621 * ioctls on 64-bit kernels. This allows running 32-bit apps on the
624 #define COMPAT_IPMICTL_SEND_COMMAND \
625 _IOR(IPMI_IOC_MAGIC, 13, struct compat_ipmi_req)
626 #define COMPAT_IPMICTL_SEND_COMMAND_SETTIME \
627 _IOR(IPMI_IOC_MAGIC, 21, struct compat_ipmi_req_settime)
628 #define COMPAT_IPMICTL_RECEIVE_MSG \
629 _IOWR(IPMI_IOC_MAGIC, 12, struct compat_ipmi_recv)
630 #define COMPAT_IPMICTL_RECEIVE_MSG_TRUNC \
631 _IOWR(IPMI_IOC_MAGIC, 11, struct compat_ipmi_recv)
633 struct compat_ipmi_msg {
640 struct compat_ipmi_req {
642 compat_uint_t addr_len;
644 struct compat_ipmi_msg msg;
647 struct compat_ipmi_recv {
648 compat_int_t recv_type;
650 compat_uint_t addr_len;
652 struct compat_ipmi_msg msg;
655 struct compat_ipmi_req_settime {
656 struct compat_ipmi_req req;
657 compat_int_t retries;
658 compat_uint_t retry_time_ms;
662 * Define some helper functions for copying IPMI data
664 static void get_compat_ipmi_msg(struct ipmi_msg *p64,
665 struct compat_ipmi_msg *p32)
667 p64->netfn = p32->netfn;
669 p64->data_len = p32->data_len;
670 p64->data = compat_ptr(p32->data);
673 static void get_compat_ipmi_req(struct ipmi_req *p64,
674 struct compat_ipmi_req *p32)
676 p64->addr = compat_ptr(p32->addr);
677 p64->addr_len = p32->addr_len;
678 p64->msgid = p32->msgid;
679 get_compat_ipmi_msg(&p64->msg, &p32->msg);
682 static void get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
683 struct compat_ipmi_req_settime *p32)
685 get_compat_ipmi_req(&p64->req, &p32->req);
686 p64->retries = p32->retries;
687 p64->retry_time_ms = p32->retry_time_ms;
690 static void get_compat_ipmi_recv(struct ipmi_recv *p64,
691 struct compat_ipmi_recv *p32)
693 memset(p64, 0, sizeof(struct ipmi_recv));
694 p64->recv_type = p32->recv_type;
695 p64->addr = compat_ptr(p32->addr);
696 p64->addr_len = p32->addr_len;
697 p64->msgid = p32->msgid;
698 get_compat_ipmi_msg(&p64->msg, &p32->msg);
701 static int copyout_recv32(struct ipmi_recv *p64, void __user *to)
703 struct compat_ipmi_recv v32;
704 memset(&v32, 0, sizeof(struct compat_ipmi_recv));
705 v32.recv_type = p64->recv_type;
706 v32.addr = ptr_to_compat(p64->addr);
707 v32.addr_len = p64->addr_len;
708 v32.msgid = p64->msgid;
709 v32.msg.netfn = p64->msg.netfn;
710 v32.msg.cmd = p64->msg.cmd;
711 v32.msg.data_len = p64->msg.data_len;
712 v32.msg.data = ptr_to_compat(p64->msg.data);
713 return copy_to_user(to, &v32, sizeof(v32)) ? -EFAULT : 0;
717 * Handle compatibility ioctls
719 static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
722 struct ipmi_file_private *priv = filep->private_data;
725 case COMPAT_IPMICTL_SEND_COMMAND:
728 struct compat_ipmi_req r32;
730 unsigned int retry_time_ms;
732 if (copy_from_user(&r32, compat_ptr(arg), sizeof(r32)))
735 get_compat_ipmi_req(&rp, &r32);
737 mutex_lock(&priv->recv_mutex);
738 retries = priv->default_retries;
739 retry_time_ms = priv->default_retry_time_ms;
740 mutex_unlock(&priv->recv_mutex);
742 return handle_send_req(priv->user, &rp,
743 retries, retry_time_ms);
745 case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
747 struct ipmi_req_settime sp;
748 struct compat_ipmi_req_settime sp32;
750 if (copy_from_user(&sp32, compat_ptr(arg), sizeof(sp32)))
753 get_compat_ipmi_req_settime(&sp, &sp32);
755 return handle_send_req(priv->user, &sp.req,
756 sp.retries, sp.retry_time_ms);
758 case COMPAT_IPMICTL_RECEIVE_MSG:
759 case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
761 struct ipmi_recv recv64;
762 struct compat_ipmi_recv recv32;
764 if (copy_from_user(&recv32, compat_ptr(arg), sizeof(recv32)))
767 get_compat_ipmi_recv(&recv64, &recv32);
769 return handle_recv(priv,
770 cmd == COMPAT_IPMICTL_RECEIVE_MSG_TRUNC,
771 &recv64, copyout_recv32, compat_ptr(arg));
774 return ipmi_ioctl(filep, cmd, arg);
779 static const struct file_operations ipmi_fops = {
780 .owner = THIS_MODULE,
781 .unlocked_ioctl = ipmi_ioctl,
783 .compat_ioctl = compat_ipmi_ioctl,
786 .release = ipmi_release,
787 .fasync = ipmi_fasync,
789 .llseek = noop_llseek,
792 #define DEVICE_NAME "ipmidev"
794 static int ipmi_major;
795 module_param(ipmi_major, int, 0);
796 MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By"
797 " default, or if you set it to zero, it will choose the next"
798 " available device. Setting it to -1 will disable the"
799 " interface. Other values will set the major device number"
802 /* Keep track of the devices that are registered. */
803 struct ipmi_reg_list {
805 struct list_head link;
807 static LIST_HEAD(reg_list);
808 static DEFINE_MUTEX(reg_list_mutex);
810 static struct class *ipmi_class;
812 static void ipmi_new_smi(int if_num, struct device *device)
814 dev_t dev = MKDEV(ipmi_major, if_num);
815 struct ipmi_reg_list *entry;
817 entry = kmalloc(sizeof(*entry), GFP_KERNEL);
819 pr_err("ipmi_devintf: Unable to create the ipmi class device link\n");
824 mutex_lock(®_list_mutex);
825 device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
826 list_add(&entry->link, ®_list);
827 mutex_unlock(®_list_mutex);
830 static void ipmi_smi_gone(int if_num)
832 dev_t dev = MKDEV(ipmi_major, if_num);
833 struct ipmi_reg_list *entry;
835 mutex_lock(®_list_mutex);
836 list_for_each_entry(entry, ®_list, link) {
837 if (entry->dev == dev) {
838 list_del(&entry->link);
843 device_destroy(ipmi_class, dev);
844 mutex_unlock(®_list_mutex);
847 static struct ipmi_smi_watcher smi_watcher =
849 .owner = THIS_MODULE,
850 .new_smi = ipmi_new_smi,
851 .smi_gone = ipmi_smi_gone,
854 static int __init init_ipmi_devintf(void)
861 pr_info("ipmi device interface\n");
863 ipmi_class = class_create(THIS_MODULE, "ipmi");
864 if (IS_ERR(ipmi_class)) {
865 pr_err("ipmi: can't register device class\n");
866 return PTR_ERR(ipmi_class);
869 rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
871 class_destroy(ipmi_class);
872 pr_err("ipmi: can't get major %d\n", ipmi_major);
876 if (ipmi_major == 0) {
880 rv = ipmi_smi_watcher_register(&smi_watcher);
882 unregister_chrdev(ipmi_major, DEVICE_NAME);
883 class_destroy(ipmi_class);
884 pr_warn("ipmi: can't register smi watcher\n");
890 module_init(init_ipmi_devintf);
892 static void __exit cleanup_ipmi(void)
894 struct ipmi_reg_list *entry, *entry2;
895 mutex_lock(®_list_mutex);
896 list_for_each_entry_safe(entry, entry2, ®_list, link) {
897 list_del(&entry->link);
898 device_destroy(ipmi_class, entry->dev);
901 mutex_unlock(®_list_mutex);
902 class_destroy(ipmi_class);
903 ipmi_smi_watcher_unregister(&smi_watcher);
904 unregister_chrdev(ipmi_major, DEVICE_NAME);
906 module_exit(cleanup_ipmi);
908 MODULE_LICENSE("GPL");
910 MODULE_DESCRIPTION("Linux device interface for the IPMI message handler.");