aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorK. Y. Srinivasan <kys@microsoft.com>2016-11-06 16:14:16 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-11-07 04:01:17 -0500
commit74198eb4a42c4a3c4fbef08fa01a291a282f7c2e (patch)
tree896b7e4abbabdafdd892bbcdfeaff3dbb0258e90
parent0c38cda64aecb4a821210bb2d3d04092c181c0ae (diff)
Drivers: hv: vmbus: Base host signaling strictly on the ring state
One of the factors that can result in the host concluding that a given guest in mounting a DOS attack is if the guest generates interrupts to the host when the host is not expecting it. If these "spurious" interrupts reach a certain rate, the host can throttle the guest to minimize the impact. The host computation of the "expected number of interrupts" is strictly based on the ring transitions. Until the host logic is fixed, base the guest logic to interrupt solely on the ring state. Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/hv/channel.c23
-rw-r--r--drivers/hv/channel_mgmt.c2
-rw-r--r--drivers/hv/ring_buffer.c7
3 files changed, 20 insertions, 12 deletions
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 16f91c8490fe..5e482d7f60cb 100644
--- a/drivers/hv/channel.c
+++ b/drivers/hv/channel.c
@@ -676,10 +676,18 @@ int vmbus_sendpacket_ctl(struct vmbus_channel *channel, void *buffer,
676 * NOTE: in this case, the hvsock channel is an exception, because 676 * NOTE: in this case, the hvsock channel is an exception, because
677 * it looks the host side's hvsock implementation has a throttling 677 * it looks the host side's hvsock implementation has a throttling
678 * mechanism which can hurt the performance otherwise. 678 * mechanism which can hurt the performance otherwise.
679 *
680 * KYS: Oct. 30, 2016:
681 * It looks like Windows hosts have logic to deal with DOS attacks that
682 * can be triggered if it receives interrupts when it is not expecting
683 * the interrupt. The host expects interrupts only when the ring
684 * transitions from empty to non-empty (or full to non full on the guest
685 * to host ring).
686 * So, base the signaling decision solely on the ring state until the
687 * host logic is fixed.
679 */ 688 */
680 689
681 if (((ret == 0) && kick_q && signal) || 690 if (((ret == 0) && signal))
682 (ret && !is_hvsock_channel(channel)))
683 vmbus_setevent(channel); 691 vmbus_setevent(channel);
684 692
685 return ret; 693 return ret;
@@ -786,9 +794,18 @@ int vmbus_sendpacket_pagebuffer_ctl(struct vmbus_channel *channel,
786 * If we cannot write to the ring-buffer; signal the host 794 * If we cannot write to the ring-buffer; signal the host
787 * even if we may not have written anything. This is a rare 795 * even if we may not have written anything. This is a rare
788 * enough condition that it should not matter. 796 * enough condition that it should not matter.
797 *
798 * KYS: Oct. 30, 2016:
799 * It looks like Windows hosts have logic to deal with DOS attacks that
800 * can be triggered if it receives interrupts when it is not expecting
801 * the interrupt. The host expects interrupts only when the ring
802 * transitions from empty to non-empty (or full to non full on the guest
803 * to host ring).
804 * So, base the signaling decision solely on the ring state until the
805 * host logic is fixed.
789 */ 806 */
790 807
791 if (((ret == 0) && kick_q && signal) || (ret)) 808 if (((ret == 0) && signal))
792 vmbus_setevent(channel); 809 vmbus_setevent(channel);
793 810
794 return ret; 811 return ret;
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 96a85cd39580..cbb96f2f0d1a 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -447,8 +447,6 @@ static void vmbus_process_offer(struct vmbus_channel *newchannel)
447 } 447 }
448 448
449 dev_type = hv_get_dev_type(newchannel); 449 dev_type = hv_get_dev_type(newchannel);
450 if (dev_type == HV_NIC)
451 set_channel_signal_state(newchannel, HV_SIGNAL_POLICY_EXPLICIT);
452 450
453 init_vp_index(newchannel, dev_type); 451 init_vp_index(newchannel, dev_type);
454 452
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 08043da1a61c..5d11d93eedf4 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -75,13 +75,6 @@ static bool hv_need_to_signal(u32 old_write, struct hv_ring_buffer_info *rbi,
75 if (READ_ONCE(rbi->ring_buffer->interrupt_mask)) 75 if (READ_ONCE(rbi->ring_buffer->interrupt_mask))
76 return false; 76 return false;
77 77
78 /*
79 * When the client wants to control signaling,
80 * we only honour the host interrupt mask.
81 */
82 if (policy == HV_SIGNAL_POLICY_EXPLICIT)
83 return true;
84
85 /* check interrupt_mask before read_index */ 78 /* check interrupt_mask before read_index */
86 virt_rmb(); 79 virt_rmb();
87 /* 80 /*