Commit fe5cdef2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -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;
+17 −2
Original line number Original line Diff line number Diff line
@@ -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,
	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,
	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);
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)
+2 −0
Original line number Original line Diff line number Diff line
@@ -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') {