Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dongxiao Xu and committed by
Greg Kroah-Hartman
afcf462a 8d1c50e9

+26 -6
+7 -2
drivers/staging/heci/heci_init.c
··· 998 998 if ((!dev) || (!file_ext)) 999 999 return -ENODEV; 1000 1000 1001 - if (file_ext->state != HECI_FILE_DISCONNECTING) 1001 + spin_lock_bh(&dev->device_lock); 1002 + if (file_ext->state != HECI_FILE_DISCONNECTING) { 1003 + spin_unlock_bh(&dev->device_lock); 1002 1004 return 0; 1005 + } 1006 + spin_unlock_bh(&dev->device_lock); 1003 1007 1004 1008 priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); 1005 1009 if (!priv_cb) ··· 1035 1031 err = wait_event_timeout(dev->wait_recvd_msg, 1036 1032 (HECI_FILE_DISCONNECTED == file_ext->state), 1037 1033 timeout * HZ); 1034 + 1035 + spin_lock_bh(&dev->device_lock); 1038 1036 if (HECI_FILE_DISCONNECTED == file_ext->state) { 1039 1037 rets = 0; 1040 1038 DBG("successfully disconnected from fw client.\n"); ··· 1051 1045 DBG("failed to disconnect from fw client.\n"); 1052 1046 } 1053 1047 1054 - spin_lock_bh(&dev->device_lock); 1055 1048 heci_flush_list(&dev->ctrl_rd_list, file_ext); 1056 1049 heci_flush_list(&dev->ctrl_wr_list, file_ext); 1057 1050 spin_unlock_bh(&dev->device_lock);
+12 -3
drivers/staging/heci/heci_main.c
··· 751 751 (1 << (file_ext->host_client_id % 8)); 752 752 spin_unlock_bh(&dev->device_lock); 753 753 spin_lock(&file_ext->file_lock); 754 + spin_lock_bh(&dev->device_lock); 754 755 file_ext->state = HECI_FILE_INITIALIZING; 756 + spin_unlock_bh(&dev->device_lock); 755 757 file_ext->sm_state = 0; 756 758 757 759 file->private_data = file_ext; ··· 787 785 788 786 if (file_ext != &dev->iamthif_file_ext) { 789 787 spin_lock(&file_ext->file_lock); 788 + spin_lock_bh(&dev->device_lock); 790 789 if (file_ext->state == HECI_FILE_CONNECTED) { 791 790 file_ext->state = HECI_FILE_DISCONNECTING; 791 + spin_unlock_bh(&dev->device_lock); 792 792 spin_unlock(&file_ext->file_lock); 793 793 DBG("disconnecting client host client = %d, " 794 794 "ME client = %d\n", ··· 798 794 file_ext->me_client_id); 799 795 rets = heci_disconnect_host_client(dev, file_ext); 800 796 spin_lock(&file_ext->file_lock); 797 + spin_lock_bh(&dev->device_lock); 801 798 } 802 - spin_lock_bh(&dev->device_lock); 803 799 heci_flush_queues(dev, file_ext); 804 800 DBG("remove client host client = %d, ME client = %d\n", 805 801 file_ext->host_client_id, ··· 987 983 return -ERESTARTSYS; 988 984 } 989 985 986 + spin_lock_bh(&dev->device_lock); 990 987 if (HECI_FILE_INITIALIZING == file_ext->state || 991 988 HECI_FILE_DISCONNECTED == file_ext->state || 992 989 HECI_FILE_DISCONNECTING == file_ext->state) { 990 + spin_unlock_bh(&dev->device_lock); 993 991 rets = -EBUSY; 994 992 goto out; 995 993 } 994 + spin_unlock_bh(&dev->device_lock); 996 995 spin_lock_bh(&file_ext->read_io_lock); 997 996 } 998 997 ··· 1232 1225 priv_write_cb->request_buffer.size = length; 1233 1226 1234 1227 spin_lock(&file_ext->write_io_lock); 1228 + spin_lock_bh(&dev->device_lock); 1235 1229 DBG("host client = %d, ME client = %d\n", 1236 1230 file_ext->host_client_id, file_ext->me_client_id); 1237 1231 if (file_ext->state != HECI_FILE_CONNECTED) { ··· 1240 1232 DBG("host client = %d, is not connected to ME client = %d", 1241 1233 file_ext->host_client_id, 1242 1234 file_ext->me_client_id); 1243 - 1235 + spin_unlock_bh(&dev->device_lock); 1244 1236 goto unlock; 1245 1237 } 1246 1238 for (i = 0; i < dev->num_heci_me_clients; i++) { ··· 1251 1243 BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); 1252 1244 if (i == dev->num_heci_me_clients) { 1253 1245 rets = -ENODEV; 1246 + spin_unlock_bh(&dev->device_lock); 1254 1247 goto unlock; 1255 1248 } 1256 1249 if (length > dev->me_clients[i].props.max_msg_length || length <= 0) { 1257 1250 rets = -EINVAL; 1251 + spin_unlock_bh(&dev->device_lock); 1258 1252 goto unlock; 1259 1253 } 1260 1254 priv_write_cb->file_private = file_ext; 1261 1255 1262 - spin_lock_bh(&dev->device_lock); 1263 1256 if (flow_ctrl_creds(dev, file_ext) && 1264 1257 dev->host_buffer_is_empty) { 1265 1258 spin_unlock_bh(&dev->device_lock);
+7 -1
drivers/staging/heci/io_heci.c
··· 297 297 if (!heci_connect(dev, file_ext)) { 298 298 rets = -ENODEV; 299 299 spin_unlock_bh(&dev->device_lock); 300 + spin_unlock(&file_ext->file_lock); 300 301 goto end; 301 302 } else { 302 303 file_ext->timer_count = HECI_CONNECT_TIMEOUT; ··· 321 320 || HECI_FILE_DISCONNECTED == file_ext->state), 322 321 timeout * HZ); 323 322 323 + spin_lock_bh(&dev->device_lock); 324 324 if (HECI_FILE_CONNECTED == file_ext->state) { 325 + spin_unlock_bh(&dev->device_lock); 325 326 DBG("successfully connected to FW client.\n"); 326 327 rets = file_ext->status; 327 328 /* now copy the data to user space */ ··· 340 337 } else { 341 338 DBG("failed to connect to FW client.file_ext->state = %d.\n", 342 339 file_ext->state); 340 + spin_unlock_bh(&dev->device_lock); 343 341 if (!err) { 344 342 DBG("wait_event_interruptible_timeout failed on client" 345 343 " connect message fw response message.\n"); ··· 641 637 DBG("received wrong function input param.\n"); 642 638 return -ENODEV; 643 639 } 640 + 641 + spin_lock_bh(&dev->device_lock); 644 642 if (file_ext->state != HECI_FILE_CONNECTED) { 643 + spin_unlock_bh(&dev->device_lock); 645 644 return -ENODEV; 646 645 } 647 646 648 - spin_lock_bh(&dev->device_lock); 649 647 if (dev->heci_state != HECI_ENABLED) { 650 648 spin_unlock_bh(&dev->device_lock); 651 649 return -ENODEV;