Merge bbc66abcd2
("drm/amd/display: Fix slab-use-after-free in hdcp") into android15-6.6-lts
Steps on the way to 6.6.90 Change-Id: I1cdfae78d043d58b4948644ae3b04a945df25e4c Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -42,16 +42,13 @@ int module_add_driver(struct module *mod, struct device_driver *drv)
|
|||||||
if (mod)
|
if (mod)
|
||||||
mk = &mod->mkobj;
|
mk = &mod->mkobj;
|
||||||
else if (drv->mod_name) {
|
else if (drv->mod_name) {
|
||||||
struct kobject *mkobj;
|
/* Lookup or create built-in module entry in /sys/modules */
|
||||||
|
mk = lookup_or_create_module_kobject(drv->mod_name);
|
||||||
/* Lookup built-in module entry in /sys/modules */
|
if (mk) {
|
||||||
mkobj = kset_find_obj(module_kset, drv->mod_name);
|
|
||||||
if (mkobj) {
|
|
||||||
mk = container_of(mkobj, struct module_kobject, kobj);
|
|
||||||
/* remember our module structure */
|
/* remember our module structure */
|
||||||
drv->p->mkobj = mk;
|
drv->p->mkobj = mk;
|
||||||
/* kset_find_obj took a reference */
|
/* lookup_or_create_module_kobject took a reference */
|
||||||
kobject_put(mkobj);
|
kobject_put(&mk->kobj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -172,7 +172,10 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
|
|||||||
struct mod_hdcp_display_adjustment display_adjust;
|
struct mod_hdcp_display_adjustment display_adjust;
|
||||||
unsigned int conn_index = aconnector->base.index;
|
unsigned int conn_index = aconnector->base.index;
|
||||||
|
|
||||||
mutex_lock(&hdcp_w->mutex);
|
guard(mutex)(&hdcp_w->mutex);
|
||||||
|
drm_connector_get(&aconnector->base);
|
||||||
|
if (hdcp_w->aconnector[conn_index])
|
||||||
|
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||||
hdcp_w->aconnector[conn_index] = aconnector;
|
hdcp_w->aconnector[conn_index] = aconnector;
|
||||||
|
|
||||||
memset(&link_adjust, 0, sizeof(link_adjust));
|
memset(&link_adjust, 0, sizeof(link_adjust));
|
||||||
@@ -209,7 +212,6 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
|
|||||||
mod_hdcp_update_display(&hdcp_w->hdcp, conn_index, &link_adjust, &display_adjust, &hdcp_w->output);
|
mod_hdcp_update_display(&hdcp_w->hdcp, conn_index, &link_adjust, &display_adjust, &hdcp_w->output);
|
||||||
|
|
||||||
process_output(hdcp_w);
|
process_output(hdcp_w);
|
||||||
mutex_unlock(&hdcp_w->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
|
static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
|
||||||
@@ -220,8 +222,7 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
|
|||||||
struct drm_connector_state *conn_state = aconnector->base.state;
|
struct drm_connector_state *conn_state = aconnector->base.state;
|
||||||
unsigned int conn_index = aconnector->base.index;
|
unsigned int conn_index = aconnector->base.index;
|
||||||
|
|
||||||
mutex_lock(&hdcp_w->mutex);
|
guard(mutex)(&hdcp_w->mutex);
|
||||||
hdcp_w->aconnector[conn_index] = aconnector;
|
|
||||||
|
|
||||||
/* the removal of display will invoke auth reset -> hdcp destroy and
|
/* the removal of display will invoke auth reset -> hdcp destroy and
|
||||||
* we'd expect the Content Protection (CP) property changed back to
|
* we'd expect the Content Protection (CP) property changed back to
|
||||||
@@ -237,9 +238,11 @@ static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
|
mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
|
||||||
|
if (hdcp_w->aconnector[conn_index]) {
|
||||||
|
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||||
|
hdcp_w->aconnector[conn_index] = NULL;
|
||||||
|
}
|
||||||
process_output(hdcp_w);
|
process_output(hdcp_w);
|
||||||
mutex_unlock(&hdcp_w->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
|
void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
|
||||||
@@ -247,7 +250,7 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde
|
|||||||
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
|
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
|
||||||
unsigned int conn_index;
|
unsigned int conn_index;
|
||||||
|
|
||||||
mutex_lock(&hdcp_w->mutex);
|
guard(mutex)(&hdcp_w->mutex);
|
||||||
|
|
||||||
mod_hdcp_reset_connection(&hdcp_w->hdcp, &hdcp_w->output);
|
mod_hdcp_reset_connection(&hdcp_w->hdcp, &hdcp_w->output);
|
||||||
|
|
||||||
@@ -256,11 +259,13 @@ void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_inde
|
|||||||
for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) {
|
for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX; conn_index++) {
|
||||||
hdcp_w->encryption_status[conn_index] =
|
hdcp_w->encryption_status[conn_index] =
|
||||||
MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
|
MOD_HDCP_ENCRYPTION_STATUS_HDCP_OFF;
|
||||||
|
if (hdcp_w->aconnector[conn_index]) {
|
||||||
|
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||||
|
hdcp_w->aconnector[conn_index] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
process_output(hdcp_w);
|
process_output(hdcp_w);
|
||||||
|
|
||||||
mutex_unlock(&hdcp_w->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
|
void hdcp_handle_cpirq(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
|
||||||
@@ -277,7 +282,7 @@ static void event_callback(struct work_struct *work)
|
|||||||
hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue,
|
hdcp_work = container_of(to_delayed_work(work), struct hdcp_workqueue,
|
||||||
callback_dwork);
|
callback_dwork);
|
||||||
|
|
||||||
mutex_lock(&hdcp_work->mutex);
|
guard(mutex)(&hdcp_work->mutex);
|
||||||
|
|
||||||
cancel_delayed_work(&hdcp_work->callback_dwork);
|
cancel_delayed_work(&hdcp_work->callback_dwork);
|
||||||
|
|
||||||
@@ -285,8 +290,6 @@ static void event_callback(struct work_struct *work)
|
|||||||
&hdcp_work->output);
|
&hdcp_work->output);
|
||||||
|
|
||||||
process_output(hdcp_work);
|
process_output(hdcp_work);
|
||||||
|
|
||||||
mutex_unlock(&hdcp_work->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void event_property_update(struct work_struct *work)
|
static void event_property_update(struct work_struct *work)
|
||||||
@@ -323,7 +326,7 @@ static void event_property_update(struct work_struct *work)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
|
||||||
mutex_lock(&hdcp_work->mutex);
|
guard(mutex)(&hdcp_work->mutex);
|
||||||
|
|
||||||
if (conn_state->commit) {
|
if (conn_state->commit) {
|
||||||
ret = wait_for_completion_interruptible_timeout(&conn_state->commit->hw_done,
|
ret = wait_for_completion_interruptible_timeout(&conn_state->commit->hw_done,
|
||||||
@@ -355,7 +358,6 @@ static void event_property_update(struct work_struct *work)
|
|||||||
drm_hdcp_update_content_protection(connector,
|
drm_hdcp_update_content_protection(connector,
|
||||||
DRM_MODE_CONTENT_PROTECTION_DESIRED);
|
DRM_MODE_CONTENT_PROTECTION_DESIRED);
|
||||||
}
|
}
|
||||||
mutex_unlock(&hdcp_work->mutex);
|
|
||||||
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
drm_modeset_unlock(&dev->mode_config.connection_mutex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,7 +370,7 @@ static void event_property_validate(struct work_struct *work)
|
|||||||
struct amdgpu_dm_connector *aconnector;
|
struct amdgpu_dm_connector *aconnector;
|
||||||
unsigned int conn_index;
|
unsigned int conn_index;
|
||||||
|
|
||||||
mutex_lock(&hdcp_work->mutex);
|
guard(mutex)(&hdcp_work->mutex);
|
||||||
|
|
||||||
for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX;
|
for (conn_index = 0; conn_index < AMDGPU_DM_MAX_DISPLAY_INDEX;
|
||||||
conn_index++) {
|
conn_index++) {
|
||||||
@@ -408,8 +410,6 @@ static void event_property_validate(struct work_struct *work)
|
|||||||
schedule_work(&hdcp_work->property_update_work);
|
schedule_work(&hdcp_work->property_update_work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&hdcp_work->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void event_watchdog_timer(struct work_struct *work)
|
static void event_watchdog_timer(struct work_struct *work)
|
||||||
@@ -420,7 +420,7 @@ static void event_watchdog_timer(struct work_struct *work)
|
|||||||
struct hdcp_workqueue,
|
struct hdcp_workqueue,
|
||||||
watchdog_timer_dwork);
|
watchdog_timer_dwork);
|
||||||
|
|
||||||
mutex_lock(&hdcp_work->mutex);
|
guard(mutex)(&hdcp_work->mutex);
|
||||||
|
|
||||||
cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
|
cancel_delayed_work(&hdcp_work->watchdog_timer_dwork);
|
||||||
|
|
||||||
@@ -429,8 +429,6 @@ static void event_watchdog_timer(struct work_struct *work)
|
|||||||
&hdcp_work->output);
|
&hdcp_work->output);
|
||||||
|
|
||||||
process_output(hdcp_work);
|
process_output(hdcp_work);
|
||||||
|
|
||||||
mutex_unlock(&hdcp_work->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void event_cpirq(struct work_struct *work)
|
static void event_cpirq(struct work_struct *work)
|
||||||
@@ -439,13 +437,11 @@ static void event_cpirq(struct work_struct *work)
|
|||||||
|
|
||||||
hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work);
|
hdcp_work = container_of(work, struct hdcp_workqueue, cpirq_work);
|
||||||
|
|
||||||
mutex_lock(&hdcp_work->mutex);
|
guard(mutex)(&hdcp_work->mutex);
|
||||||
|
|
||||||
mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output);
|
mod_hdcp_process_event(&hdcp_work->hdcp, MOD_HDCP_EVENT_CPIRQ, &hdcp_work->output);
|
||||||
|
|
||||||
process_output(hdcp_work);
|
process_output(hdcp_work);
|
||||||
|
|
||||||
mutex_unlock(&hdcp_work->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
|
void hdcp_destroy(struct kobject *kobj, struct hdcp_workqueue *hdcp_work)
|
||||||
@@ -479,7 +475,7 @@ static bool enable_assr(void *handle, struct dc_link *link)
|
|||||||
|
|
||||||
dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
|
dtm_cmd = (struct ta_dtm_shared_memory *)psp->dtm_context.context.mem_context.shared_buf;
|
||||||
|
|
||||||
mutex_lock(&psp->dtm_context.mutex);
|
guard(mutex)(&psp->dtm_context.mutex);
|
||||||
memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
|
memset(dtm_cmd, 0, sizeof(struct ta_dtm_shared_memory));
|
||||||
|
|
||||||
dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE;
|
dtm_cmd->cmd_id = TA_DTM_COMMAND__TOPOLOGY_ASSR_ENABLE;
|
||||||
@@ -494,8 +490,6 @@ static bool enable_assr(void *handle, struct dc_link *link)
|
|||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&psp->dtm_context.mutex);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,6 +498,7 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
|
|||||||
struct hdcp_workqueue *hdcp_work = handle;
|
struct hdcp_workqueue *hdcp_work = handle;
|
||||||
struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx;
|
struct amdgpu_dm_connector *aconnector = config->dm_stream_ctx;
|
||||||
int link_index = aconnector->dc_link->link_index;
|
int link_index = aconnector->dc_link->link_index;
|
||||||
|
unsigned int conn_index = aconnector->base.index;
|
||||||
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
|
struct mod_hdcp_display *display = &hdcp_work[link_index].display;
|
||||||
struct mod_hdcp_link *link = &hdcp_work[link_index].link;
|
struct mod_hdcp_link *link = &hdcp_work[link_index].link;
|
||||||
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
|
struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
|
||||||
@@ -557,13 +552,14 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
|
|||||||
(!!aconnector->base.state) ?
|
(!!aconnector->base.state) ?
|
||||||
aconnector->base.state->hdcp_content_type : -1);
|
aconnector->base.state->hdcp_content_type : -1);
|
||||||
|
|
||||||
mutex_lock(&hdcp_w->mutex);
|
guard(mutex)(&hdcp_w->mutex);
|
||||||
|
|
||||||
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
|
mod_hdcp_add_display(&hdcp_w->hdcp, link, display, &hdcp_w->output);
|
||||||
|
drm_connector_get(&aconnector->base);
|
||||||
|
if (hdcp_w->aconnector[conn_index])
|
||||||
|
drm_connector_put(&hdcp_w->aconnector[conn_index]->base);
|
||||||
|
hdcp_w->aconnector[conn_index] = aconnector;
|
||||||
process_output(hdcp_w);
|
process_output(hdcp_w);
|
||||||
mutex_unlock(&hdcp_w->mutex);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1231,26 +1231,37 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int arm_smmu_streams_cmp_key(const void *lhs, const struct rb_node *rhs)
|
||||||
|
{
|
||||||
|
struct arm_smmu_stream *stream_rhs =
|
||||||
|
rb_entry(rhs, struct arm_smmu_stream, node);
|
||||||
|
const u32 *sid_lhs = lhs;
|
||||||
|
|
||||||
|
if (*sid_lhs < stream_rhs->id)
|
||||||
|
return -1;
|
||||||
|
if (*sid_lhs > stream_rhs->id)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int arm_smmu_streams_cmp_node(struct rb_node *lhs,
|
||||||
|
const struct rb_node *rhs)
|
||||||
|
{
|
||||||
|
return arm_smmu_streams_cmp_key(
|
||||||
|
&rb_entry(lhs, struct arm_smmu_stream, node)->id, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
static struct arm_smmu_master *
|
static struct arm_smmu_master *
|
||||||
arm_smmu_find_master(struct arm_smmu_device *smmu, u32 sid)
|
arm_smmu_find_master(struct arm_smmu_device *smmu, u32 sid)
|
||||||
{
|
{
|
||||||
struct rb_node *node;
|
struct rb_node *node;
|
||||||
struct arm_smmu_stream *stream;
|
|
||||||
|
|
||||||
lockdep_assert_held(&smmu->streams_mutex);
|
lockdep_assert_held(&smmu->streams_mutex);
|
||||||
|
|
||||||
node = smmu->streams.rb_node;
|
node = rb_find(&sid, &smmu->streams, arm_smmu_streams_cmp_key);
|
||||||
while (node) {
|
if (!node)
|
||||||
stream = rb_entry(node, struct arm_smmu_stream, node);
|
return NULL;
|
||||||
if (stream->id < sid)
|
return rb_entry(node, struct arm_smmu_stream, node)->master;
|
||||||
node = node->rb_right;
|
|
||||||
else if (stream->id > sid)
|
|
||||||
node = node->rb_left;
|
|
||||||
else
|
|
||||||
return stream->master;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IRQ and event handlers */
|
/* IRQ and event handlers */
|
||||||
@@ -2345,8 +2356,6 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
struct arm_smmu_stream *new_stream, *cur_stream;
|
|
||||||
struct rb_node **new_node, *parent_node = NULL;
|
|
||||||
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
|
struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
|
||||||
|
|
||||||
master->streams = kcalloc(fwspec->num_ids, sizeof(*master->streams),
|
master->streams = kcalloc(fwspec->num_ids, sizeof(*master->streams),
|
||||||
@@ -2357,9 +2366,10 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
|||||||
|
|
||||||
mutex_lock(&smmu->streams_mutex);
|
mutex_lock(&smmu->streams_mutex);
|
||||||
for (i = 0; i < fwspec->num_ids; i++) {
|
for (i = 0; i < fwspec->num_ids; i++) {
|
||||||
|
struct arm_smmu_stream *new_stream = &master->streams[i];
|
||||||
|
struct rb_node *existing;
|
||||||
u32 sid = fwspec->ids[i];
|
u32 sid = fwspec->ids[i];
|
||||||
|
|
||||||
new_stream = &master->streams[i];
|
|
||||||
new_stream->id = sid;
|
new_stream->id = sid;
|
||||||
new_stream->master = master;
|
new_stream->master = master;
|
||||||
|
|
||||||
@@ -2368,28 +2378,23 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Insert into SID tree */
|
/* Insert into SID tree */
|
||||||
new_node = &(smmu->streams.rb_node);
|
existing = rb_find_add(&new_stream->node, &smmu->streams,
|
||||||
while (*new_node) {
|
arm_smmu_streams_cmp_node);
|
||||||
cur_stream = rb_entry(*new_node, struct arm_smmu_stream,
|
if (existing) {
|
||||||
node);
|
struct arm_smmu_master *existing_master =
|
||||||
parent_node = *new_node;
|
rb_entry(existing, struct arm_smmu_stream, node)
|
||||||
if (cur_stream->id > new_stream->id) {
|
->master;
|
||||||
new_node = &((*new_node)->rb_left);
|
|
||||||
} else if (cur_stream->id < new_stream->id) {
|
|
||||||
new_node = &((*new_node)->rb_right);
|
|
||||||
} else {
|
|
||||||
dev_warn(master->dev,
|
|
||||||
"stream %u already in tree\n",
|
|
||||||
cur_stream->id);
|
|
||||||
ret = -EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ret)
|
|
||||||
break;
|
|
||||||
|
|
||||||
rb_link_node(&new_stream->node, parent_node, new_node);
|
/* Bridged PCI devices may end up with duplicated IDs */
|
||||||
rb_insert_color(&new_stream->node, &smmu->streams);
|
if (existing_master == master)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dev_warn(master->dev,
|
||||||
|
"stream %u already in tree from dev %s\n", sid,
|
||||||
|
dev_name(existing_master->dev));
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@@ -163,6 +163,8 @@ extern void cleanup_module(void);
|
|||||||
#define __INITRODATA_OR_MODULE __INITRODATA
|
#define __INITRODATA_OR_MODULE __INITRODATA
|
||||||
#endif /*CONFIG_MODULES*/
|
#endif /*CONFIG_MODULES*/
|
||||||
|
|
||||||
|
struct module_kobject *lookup_or_create_module_kobject(const char *name);
|
||||||
|
|
||||||
/* Generic info of form tag = "info" */
|
/* Generic info of form tag = "info" */
|
||||||
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
|
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
|
||||||
|
|
||||||
|
@@ -759,7 +759,7 @@ void destroy_params(const struct kernel_param *params, unsigned num)
|
|||||||
params[i].ops->free(params[i].arg);
|
params[i].ops->free(params[i].arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct module_kobject * __init locate_module_kobject(const char *name)
|
struct module_kobject __modinit * lookup_or_create_module_kobject(const char *name)
|
||||||
{
|
{
|
||||||
struct module_kobject *mk;
|
struct module_kobject *mk;
|
||||||
struct kobject *kobj;
|
struct kobject *kobj;
|
||||||
@@ -801,7 +801,7 @@ static void __init kernel_add_sysfs_param(const char *name,
|
|||||||
struct module_kobject *mk;
|
struct module_kobject *mk;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mk = locate_module_kobject(name);
|
mk = lookup_or_create_module_kobject(name);
|
||||||
if (!mk)
|
if (!mk)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -872,7 +872,7 @@ static void __init version_sysfs_builtin(void)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
|
for (vattr = __start___modver; vattr < __stop___modver; vattr++) {
|
||||||
mk = locate_module_kobject(vattr->module_name);
|
mk = lookup_or_create_module_kobject(vattr->module_name);
|
||||||
if (mk) {
|
if (mk) {
|
||||||
err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
|
err = sysfs_create_file(&mk->kobj, &vattr->mattr.attr);
|
||||||
WARN_ON_ONCE(err);
|
WARN_ON_ONCE(err);
|
||||||
|
Reference in New Issue
Block a user