Staging: heci: fix the problem that file_ext->state should be protected by device_lock
While access file_ext->state, we should use device_lock to protect it. The original codes miss this in some places. Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
Родитель
8d1c50e982
Коммит
afcf462a1f
|
@ -998,8 +998,12 @@ int heci_disconnect_host_client(struct iamt_heci_device *dev,
|
||||||
if ((!dev) || (!file_ext))
|
if ((!dev) || (!file_ext))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (file_ext->state != HECI_FILE_DISCONNECTING)
|
spin_lock_bh(&dev->device_lock);
|
||||||
|
if (file_ext->state != HECI_FILE_DISCONNECTING) {
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
|
|
||||||
priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
|
priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
|
||||||
if (!priv_cb)
|
if (!priv_cb)
|
||||||
|
@ -1031,6 +1035,8 @@ int heci_disconnect_host_client(struct iamt_heci_device *dev,
|
||||||
err = wait_event_timeout(dev->wait_recvd_msg,
|
err = wait_event_timeout(dev->wait_recvd_msg,
|
||||||
(HECI_FILE_DISCONNECTED == file_ext->state),
|
(HECI_FILE_DISCONNECTED == file_ext->state),
|
||||||
timeout * HZ);
|
timeout * HZ);
|
||||||
|
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
if (HECI_FILE_DISCONNECTED == file_ext->state) {
|
if (HECI_FILE_DISCONNECTED == file_ext->state) {
|
||||||
rets = 0;
|
rets = 0;
|
||||||
DBG("successfully disconnected from fw client.\n");
|
DBG("successfully disconnected from fw client.\n");
|
||||||
|
@ -1045,7 +1051,6 @@ int heci_disconnect_host_client(struct iamt_heci_device *dev,
|
||||||
DBG("failed to disconnect from fw client.\n");
|
DBG("failed to disconnect from fw client.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_bh(&dev->device_lock);
|
|
||||||
heci_flush_list(&dev->ctrl_rd_list, file_ext);
|
heci_flush_list(&dev->ctrl_rd_list, file_ext);
|
||||||
heci_flush_list(&dev->ctrl_wr_list, file_ext);
|
heci_flush_list(&dev->ctrl_wr_list, file_ext);
|
||||||
spin_unlock_bh(&dev->device_lock);
|
spin_unlock_bh(&dev->device_lock);
|
||||||
|
|
|
@ -751,7 +751,9 @@ static int heci_open(struct inode *inode, struct file *file)
|
||||||
(1 << (file_ext->host_client_id % 8));
|
(1 << (file_ext->host_client_id % 8));
|
||||||
spin_unlock_bh(&dev->device_lock);
|
spin_unlock_bh(&dev->device_lock);
|
||||||
spin_lock(&file_ext->file_lock);
|
spin_lock(&file_ext->file_lock);
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
file_ext->state = HECI_FILE_INITIALIZING;
|
file_ext->state = HECI_FILE_INITIALIZING;
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
file_ext->sm_state = 0;
|
file_ext->sm_state = 0;
|
||||||
|
|
||||||
file->private_data = file_ext;
|
file->private_data = file_ext;
|
||||||
|
@ -785,8 +787,10 @@ static int heci_release(struct inode *inode, struct file *file)
|
||||||
|
|
||||||
if (file_ext != &dev->iamthif_file_ext) {
|
if (file_ext != &dev->iamthif_file_ext) {
|
||||||
spin_lock(&file_ext->file_lock);
|
spin_lock(&file_ext->file_lock);
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
if (file_ext->state == HECI_FILE_CONNECTED) {
|
if (file_ext->state == HECI_FILE_CONNECTED) {
|
||||||
file_ext->state = HECI_FILE_DISCONNECTING;
|
file_ext->state = HECI_FILE_DISCONNECTING;
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
spin_unlock(&file_ext->file_lock);
|
spin_unlock(&file_ext->file_lock);
|
||||||
DBG("disconnecting client host client = %d, "
|
DBG("disconnecting client host client = %d, "
|
||||||
"ME client = %d\n",
|
"ME client = %d\n",
|
||||||
|
@ -794,8 +798,8 @@ static int heci_release(struct inode *inode, struct file *file)
|
||||||
file_ext->me_client_id);
|
file_ext->me_client_id);
|
||||||
rets = heci_disconnect_host_client(dev, file_ext);
|
rets = heci_disconnect_host_client(dev, file_ext);
|
||||||
spin_lock(&file_ext->file_lock);
|
spin_lock(&file_ext->file_lock);
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
}
|
}
|
||||||
spin_lock_bh(&dev->device_lock);
|
|
||||||
heci_flush_queues(dev, file_ext);
|
heci_flush_queues(dev, file_ext);
|
||||||
DBG("remove client host client = %d, ME client = %d\n",
|
DBG("remove client host client = %d, ME client = %d\n",
|
||||||
file_ext->host_client_id,
|
file_ext->host_client_id,
|
||||||
|
@ -983,12 +987,15 @@ static ssize_t heci_read(struct file *file, char __user *ubuf,
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
if (HECI_FILE_INITIALIZING == file_ext->state ||
|
if (HECI_FILE_INITIALIZING == file_ext->state ||
|
||||||
HECI_FILE_DISCONNECTED == file_ext->state ||
|
HECI_FILE_DISCONNECTED == file_ext->state ||
|
||||||
HECI_FILE_DISCONNECTING == file_ext->state) {
|
HECI_FILE_DISCONNECTING == file_ext->state) {
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
rets = -EBUSY;
|
rets = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
spin_lock_bh(&file_ext->read_io_lock);
|
spin_lock_bh(&file_ext->read_io_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1225,6 +1232,7 @@ static ssize_t heci_write(struct file *file, const char __user *ubuf,
|
||||||
priv_write_cb->request_buffer.size = length;
|
priv_write_cb->request_buffer.size = length;
|
||||||
|
|
||||||
spin_lock(&file_ext->write_io_lock);
|
spin_lock(&file_ext->write_io_lock);
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
DBG("host client = %d, ME client = %d\n",
|
DBG("host client = %d, ME client = %d\n",
|
||||||
file_ext->host_client_id, file_ext->me_client_id);
|
file_ext->host_client_id, file_ext->me_client_id);
|
||||||
if (file_ext->state != HECI_FILE_CONNECTED) {
|
if (file_ext->state != HECI_FILE_CONNECTED) {
|
||||||
|
@ -1232,7 +1240,7 @@ static ssize_t heci_write(struct file *file, const char __user *ubuf,
|
||||||
DBG("host client = %d, is not connected to ME client = %d",
|
DBG("host client = %d, is not connected to ME client = %d",
|
||||||
file_ext->host_client_id,
|
file_ext->host_client_id,
|
||||||
file_ext->me_client_id);
|
file_ext->me_client_id);
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
for (i = 0; i < dev->num_heci_me_clients; i++) {
|
for (i = 0; i < dev->num_heci_me_clients; i++) {
|
||||||
|
@ -1243,15 +1251,16 @@ static ssize_t heci_write(struct file *file, const char __user *ubuf,
|
||||||
BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
|
BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
|
||||||
if (i == dev->num_heci_me_clients) {
|
if (i == dev->num_heci_me_clients) {
|
||||||
rets = -ENODEV;
|
rets = -ENODEV;
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
|
if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
|
||||||
rets = -EINVAL;
|
rets = -EINVAL;
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
priv_write_cb->file_private = file_ext;
|
priv_write_cb->file_private = file_ext;
|
||||||
|
|
||||||
spin_lock_bh(&dev->device_lock);
|
|
||||||
if (flow_ctrl_creds(dev, file_ext) &&
|
if (flow_ctrl_creds(dev, file_ext) &&
|
||||||
dev->host_buffer_is_empty) {
|
dev->host_buffer_is_empty) {
|
||||||
spin_unlock_bh(&dev->device_lock);
|
spin_unlock_bh(&dev->device_lock);
|
||||||
|
|
|
@ -297,6 +297,7 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
|
||||||
if (!heci_connect(dev, file_ext)) {
|
if (!heci_connect(dev, file_ext)) {
|
||||||
rets = -ENODEV;
|
rets = -ENODEV;
|
||||||
spin_unlock_bh(&dev->device_lock);
|
spin_unlock_bh(&dev->device_lock);
|
||||||
|
spin_unlock(&file_ext->file_lock);
|
||||||
goto end;
|
goto end;
|
||||||
} else {
|
} else {
|
||||||
file_ext->timer_count = HECI_CONNECT_TIMEOUT;
|
file_ext->timer_count = HECI_CONNECT_TIMEOUT;
|
||||||
|
@ -320,7 +321,9 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
|
||||||
|| HECI_FILE_DISCONNECTED == file_ext->state),
|
|| HECI_FILE_DISCONNECTED == file_ext->state),
|
||||||
timeout * HZ);
|
timeout * HZ);
|
||||||
|
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
if (HECI_FILE_CONNECTED == file_ext->state) {
|
if (HECI_FILE_CONNECTED == file_ext->state) {
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
DBG("successfully connected to FW client.\n");
|
DBG("successfully connected to FW client.\n");
|
||||||
rets = file_ext->status;
|
rets = file_ext->status;
|
||||||
/* now copy the data to user space */
|
/* now copy the data to user space */
|
||||||
|
@ -337,6 +340,7 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
|
||||||
} else {
|
} else {
|
||||||
DBG("failed to connect to FW client.file_ext->state = %d.\n",
|
DBG("failed to connect to FW client.file_ext->state = %d.\n",
|
||||||
file_ext->state);
|
file_ext->state);
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
DBG("wait_event_interruptible_timeout failed on client"
|
DBG("wait_event_interruptible_timeout failed on client"
|
||||||
" connect message fw response message.\n");
|
" connect message fw response message.\n");
|
||||||
|
@ -637,11 +641,13 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num,
|
||||||
DBG("received wrong function input param.\n");
|
DBG("received wrong function input param.\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_lock_bh(&dev->device_lock);
|
||||||
if (file_ext->state != HECI_FILE_CONNECTED) {
|
if (file_ext->state != HECI_FILE_CONNECTED) {
|
||||||
|
spin_unlock_bh(&dev->device_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_bh(&dev->device_lock);
|
|
||||||
if (dev->heci_state != HECI_ENABLED) {
|
if (dev->heci_state != HECI_ENABLED) {
|
||||||
spin_unlock_bh(&dev->device_lock);
|
spin_unlock_bh(&dev->device_lock);
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче