diff options
author | K. Y. Srinivasan <kys@microsoft.com> | 2014-08-28 21:29:53 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-09-24 02:31:21 -0400 |
commit | 2115b5617adf2eecca49e78f3810f359ddc5c396 (patch) | |
tree | 78deae37a3debee67b4cd30b54d948ad3cc1c8ab /drivers/hv | |
parent | b29ef3546aecb253a5552b198cef23750d56e1e4 (diff) |
Drivers: hv: vmbus: Properly protect calls to smp_processor_id()
Disable preemption when sampling current processor ID when preemption
is otherwise possible.
Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r-- | drivers/hv/channel.c | 7 | ||||
-rw-r--r-- | drivers/hv/channel_mgmt.c | 21 |
2 files changed, 20 insertions, 8 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c index 19bad59073e6..433f72a1c006 100644 --- a/drivers/hv/channel.c +++ b/drivers/hv/channel.c | |||
@@ -486,11 +486,14 @@ static int vmbus_close_internal(struct vmbus_channel *channel) | |||
486 | channel->state = CHANNEL_OPEN_STATE; | 486 | channel->state = CHANNEL_OPEN_STATE; |
487 | channel->sc_creation_callback = NULL; | 487 | channel->sc_creation_callback = NULL; |
488 | /* Stop callback and cancel the timer asap */ | 488 | /* Stop callback and cancel the timer asap */ |
489 | if (channel->target_cpu != smp_processor_id()) | 489 | if (channel->target_cpu != get_cpu()) { |
490 | put_cpu(); | ||
490 | smp_call_function_single(channel->target_cpu, reset_channel_cb, | 491 | smp_call_function_single(channel->target_cpu, reset_channel_cb, |
491 | channel, true); | 492 | channel, true); |
492 | else | 493 | } else { |
493 | reset_channel_cb(channel); | 494 | reset_channel_cb(channel); |
495 | put_cpu(); | ||
496 | } | ||
494 | 497 | ||
495 | /* Send a closing message */ | 498 | /* Send a closing message */ |
496 | 499 | ||
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index ed9350d42764..a2d1a9612c86 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c | |||
@@ -224,11 +224,14 @@ static void vmbus_process_rescind_offer(struct work_struct *work) | |||
224 | msg.header.msgtype = CHANNELMSG_RELID_RELEASED; | 224 | msg.header.msgtype = CHANNELMSG_RELID_RELEASED; |
225 | vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); | 225 | vmbus_post_msg(&msg, sizeof(struct vmbus_channel_relid_released)); |
226 | 226 | ||
227 | if (channel->target_cpu != smp_processor_id()) | 227 | if (channel->target_cpu != get_cpu()) { |
228 | put_cpu(); | ||
228 | smp_call_function_single(channel->target_cpu, | 229 | smp_call_function_single(channel->target_cpu, |
229 | percpu_channel_deq, channel, true); | 230 | percpu_channel_deq, channel, true); |
230 | else | 231 | } else { |
231 | percpu_channel_deq(channel); | 232 | percpu_channel_deq(channel); |
233 | put_cpu(); | ||
234 | } | ||
232 | 235 | ||
233 | if (channel->primary_channel == NULL) { | 236 | if (channel->primary_channel == NULL) { |
234 | spin_lock_irqsave(&vmbus_connection.channel_lock, flags); | 237 | spin_lock_irqsave(&vmbus_connection.channel_lock, flags); |
@@ -294,12 +297,15 @@ static void vmbus_process_offer(struct work_struct *work) | |||
294 | spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); | 297 | spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags); |
295 | 298 | ||
296 | if (enq) { | 299 | if (enq) { |
297 | if (newchannel->target_cpu != smp_processor_id()) | 300 | if (newchannel->target_cpu != get_cpu()) { |
301 | put_cpu(); | ||
298 | smp_call_function_single(newchannel->target_cpu, | 302 | smp_call_function_single(newchannel->target_cpu, |
299 | percpu_channel_enq, | 303 | percpu_channel_enq, |
300 | newchannel, true); | 304 | newchannel, true); |
301 | else | 305 | } else { |
302 | percpu_channel_enq(newchannel); | 306 | percpu_channel_enq(newchannel); |
307 | put_cpu(); | ||
308 | } | ||
303 | } | 309 | } |
304 | if (!fnew) { | 310 | if (!fnew) { |
305 | /* | 311 | /* |
@@ -314,12 +320,15 @@ static void vmbus_process_offer(struct work_struct *work) | |||
314 | list_add_tail(&newchannel->sc_list, &channel->sc_list); | 320 | list_add_tail(&newchannel->sc_list, &channel->sc_list); |
315 | spin_unlock_irqrestore(&channel->sc_lock, flags); | 321 | spin_unlock_irqrestore(&channel->sc_lock, flags); |
316 | 322 | ||
317 | if (newchannel->target_cpu != smp_processor_id()) | 323 | if (newchannel->target_cpu != get_cpu()) { |
324 | put_cpu(); | ||
318 | smp_call_function_single(newchannel->target_cpu, | 325 | smp_call_function_single(newchannel->target_cpu, |
319 | percpu_channel_enq, | 326 | percpu_channel_enq, |
320 | newchannel, true); | 327 | newchannel, true); |
321 | else | 328 | } else { |
322 | percpu_channel_enq(newchannel); | 329 | percpu_channel_enq(newchannel); |
330 | put_cpu(); | ||
331 | } | ||
323 | 332 | ||
324 | newchannel->state = CHANNEL_OPEN_STATE; | 333 | newchannel->state = CHANNEL_OPEN_STATE; |
325 | if (channel->sc_creation_callback != NULL) | 334 | if (channel->sc_creation_callback != NULL) |