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

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>

authored by

K. Y. Srinivasan and committed by
Greg Kroah-Hartman
74198eb4 0c38cda6

+20 -12
+20 -3
drivers/hv/channel.c
··· 676 676 * NOTE: in this case, the hvsock channel is an exception, because 677 677 * it looks the host side's hvsock implementation has a throttling 678 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) || 682 - (ret && !is_hvsock_channel(channel))) 690 + if (((ret == 0) && signal)) 683 691 vmbus_setevent(channel); 684 692 685 693 return ret; ··· 794 786 * If we cannot write to the ring-buffer; signal the host 795 787 * even if we may not have written anything. This is a rare 796 788 * enough condition that it should not matter. 789 + * 790 + * KYS: Oct. 30, 2016: 791 + * It looks like Windows hosts have logic to deal with DOS attacks that 792 + * can be triggered if it receives interrupts when it is not expecting 793 + * the interrupt. The host expects interrupts only when the ring 794 + * transitions from empty to non-empty (or full to non full on the guest 795 + * to host ring). 796 + * So, base the signaling decision solely on the ring state until the 797 + * host logic is fixed. 797 798 */ 798 799 799 - if (((ret == 0) && kick_q && signal) || (ret)) 800 + if (((ret == 0) && signal)) 800 801 vmbus_setevent(channel); 801 802 802 803 return ret;
-2
drivers/hv/channel_mgmt.c
··· 447 447 } 448 448 449 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 451 init_vp_index(newchannel, dev_type); 454 452
-7
drivers/hv/ring_buffer.c
··· 75 75 if (READ_ONCE(rbi->ring_buffer->interrupt_mask)) 76 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 78 /* check interrupt_mask before read_index */ 86 79 virt_rmb(); 87 80 /*