Commit fe5cdef2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-linus-5.1-2' of git://github.com/cminyard/linux-ipmi

Pull IPMI fixes from Corey Minyard:
 "Fixes for some bugs cause by recent changes. One crash if you feed bad
  data to the module parameters, one BUG that sometimes occurs when a
  user closes the connection, and one bug that cause the driver to not
  work if the configuration information only comes in from SMBIOS"

* tag 'for-linus-5.1-2' of git://github.com/cminyard/linux-ipmi:
  ipmi: fix sleep-in-atomic in free_user at cleanup SRCU user->release_barrier
  ipmi: ipmi_si_hardcode.c: init si_type array to fix a crash
  ipmi: Fix failure on SMBIOS specified devices
parents 2a3a028f 3b9a9072
...@@ -66,7 +66,6 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr, ...@@ -66,7 +66,6 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr,
return; return;
} }
memset(&p, 0, sizeof(p));
p.addr = base_addr; p.addr = base_addr;
p.space = space; p.space = space;
p.regspacing = offset; p.regspacing = offset;
......
...@@ -214,6 +214,9 @@ struct ipmi_user { ...@@ -214,6 +214,9 @@ struct ipmi_user {
/* Does this interface receive IPMI events? */ /* Does this interface receive IPMI events? */
bool gets_events; bool gets_events;
/* Free must run in process context for RCU cleanup. */
struct work_struct remove_work;
}; };
static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index) static struct ipmi_user *acquire_ipmi_user(struct ipmi_user *user, int *index)
...@@ -1157,6 +1160,15 @@ static int intf_err_seq(struct ipmi_smi *intf, ...@@ -1157,6 +1160,15 @@ static int intf_err_seq(struct ipmi_smi *intf,
return rv; return rv;
} }
static void free_user_work(struct work_struct *work)
{
struct ipmi_user *user = container_of(work, struct ipmi_user,
remove_work);
cleanup_srcu_struct(&user->release_barrier);
kfree(user);
}
int ipmi_create_user(unsigned int if_num, int ipmi_create_user(unsigned int if_num,
const struct ipmi_user_hndl *handler, const struct ipmi_user_hndl *handler,
void *handler_data, void *handler_data,
...@@ -1200,6 +1212,8 @@ int ipmi_create_user(unsigned int if_num, ...@@ -1200,6 +1212,8 @@ int ipmi_create_user(unsigned int if_num,
goto out_kfree; goto out_kfree;
found: found:
INIT_WORK(&new_user->remove_work, free_user_work);
rv = init_srcu_struct(&new_user->release_barrier); rv = init_srcu_struct(&new_user->release_barrier);
if (rv) if (rv)
goto out_kfree; goto out_kfree;
...@@ -1260,8 +1274,9 @@ EXPORT_SYMBOL(ipmi_get_smi_info); ...@@ -1260,8 +1274,9 @@ EXPORT_SYMBOL(ipmi_get_smi_info);
static void free_user(struct kref *ref) static void free_user(struct kref *ref)
{ {
struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount);
cleanup_srcu_struct(&user->release_barrier);
kfree(user); /* SRCU cleanup must happen in task context. */
schedule_work(&user->remove_work);
} }
static void _ipmi_destroy_user(struct ipmi_user *user) static void _ipmi_destroy_user(struct ipmi_user *user)
......
...@@ -118,6 +118,8 @@ void __init ipmi_hardcode_init(void) ...@@ -118,6 +118,8 @@ void __init ipmi_hardcode_init(void)
char *str; char *str;
char *si_type[SI_MAX_PARMS]; char *si_type[SI_MAX_PARMS];
memset(si_type, 0, sizeof(si_type));
/* Parse out the si_type string into its components. */ /* Parse out the si_type string into its components. */
str = si_type_str; str = si_type_str;
if (*str != '\0') { if (*str != '\0') {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment