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

ice: Add more validation in ice_vc_cfg_irq_map_msg

Add few checks to validate msg from iavf driver.

Test if we have got enough q_vectors allocated in VSI connected with VF.
Add masks for itr_indx and msix_indx to avoid writing to reserved fieldi
of QINT. Clear q_vector->num_ring_rx/tx, without it we can increment this
value every time we send irq map msg from VF. So after second call this
value will be incorrect.

Decrement num_vectors from msg, because last vector in iavf msg is misc
vector (we don't set map for it).

Signed-off-by: Michal Swiatkowski <michal.swiatkowski@intel.com>
Signed-off-by: Anirudh Venkataramanan <anirudh.venkataramanan@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Michal Swiatkowski and committed by
Jeff Kirsher
ba0db585 bb877b22

+36 -28
+2
drivers/net/ethernet/intel/ice/ice.h
··· 83 83 #define ICE_MAX_QS_PER_VF 256 84 84 #define ICE_MIN_QS_PER_VF 1 85 85 #define ICE_DFLT_QS_PER_VF 4 86 + #define ICE_NONQ_VECS_VF 1 87 + #define ICE_MAX_SCATTER_QS_PER_VF 16 86 88 #define ICE_MAX_BASE_QS_PER_VF 16 87 89 #define ICE_MAX_INTR_PER_VF 65 88 90 #define ICE_MIN_INTR_PER_VF (ICE_MIN_QS_PER_VF + 1)
+4
drivers/net/ethernet/intel/ice/ice_hw_autogen.h
··· 163 163 #define PFINT_OICR_ENA 0x0016C900 164 164 #define QINT_RQCTL(_QRX) (0x00150000 + ((_QRX) * 4)) 165 165 #define QINT_RQCTL_MSIX_INDX_S 0 166 + #define QINT_RQCTL_MSIX_INDX_M ICE_M(0x7FF, 0) 166 167 #define QINT_RQCTL_ITR_INDX_S 11 168 + #define QINT_RQCTL_ITR_INDX_M ICE_M(0x3, 11) 167 169 #define QINT_RQCTL_CAUSE_ENA_M BIT(30) 168 170 #define QINT_TQCTL(_DBQM) (0x00140000 + ((_DBQM) * 4)) 169 171 #define QINT_TQCTL_MSIX_INDX_S 0 172 + #define QINT_TQCTL_MSIX_INDX_M ICE_M(0x7FF, 0) 170 173 #define QINT_TQCTL_ITR_INDX_S 11 174 + #define QINT_TQCTL_ITR_INDX_M ICE_M(0x3, 11) 171 175 #define QINT_TQCTL_CAUSE_ENA_M BIT(30) 172 176 #define VPINT_ALLOC(_VF) (0x001D1000 + ((_VF) * 4)) 173 177 #define VPINT_ALLOC_FIRST_S 0
+18 -14
drivers/net/ethernet/intel/ice/ice_lib.c
··· 1879 1879 * tracked for this PF. 1880 1880 */ 1881 1881 for (q = 0; q < q_vector->num_ring_tx; q++) { 1882 - int itr_idx = q_vector->tx.itr_idx; 1882 + int itr_idx = (q_vector->tx.itr_idx << 1883 + QINT_TQCTL_ITR_INDX_S) & 1884 + QINT_TQCTL_ITR_INDX_M; 1883 1885 u32 val; 1884 1886 1885 1887 if (vsi->type == ICE_VSI_VF) 1886 - val = QINT_TQCTL_CAUSE_ENA_M | 1887 - (itr_idx << QINT_TQCTL_ITR_INDX_S) | 1888 - ((i + 1) << QINT_TQCTL_MSIX_INDX_S); 1888 + val = QINT_TQCTL_CAUSE_ENA_M | itr_idx | 1889 + (((i + 1) << QINT_TQCTL_MSIX_INDX_S) & 1890 + QINT_TQCTL_MSIX_INDX_M); 1889 1891 else 1890 - val = QINT_TQCTL_CAUSE_ENA_M | 1891 - (itr_idx << QINT_TQCTL_ITR_INDX_S) | 1892 - (reg_idx << QINT_TQCTL_MSIX_INDX_S); 1892 + val = QINT_TQCTL_CAUSE_ENA_M | itr_idx | 1893 + ((reg_idx << QINT_TQCTL_MSIX_INDX_S) & 1894 + QINT_TQCTL_MSIX_INDX_M); 1893 1895 wr32(hw, QINT_TQCTL(vsi->txq_map[txq]), val); 1894 1896 txq++; 1895 1897 } 1896 1898 1897 1899 for (q = 0; q < q_vector->num_ring_rx; q++) { 1898 - int itr_idx = q_vector->rx.itr_idx; 1900 + int itr_idx = (q_vector->rx.itr_idx << 1901 + QINT_RQCTL_ITR_INDX_S) & 1902 + QINT_RQCTL_ITR_INDX_M; 1899 1903 u32 val; 1900 1904 1901 1905 if (vsi->type == ICE_VSI_VF) 1902 - val = QINT_RQCTL_CAUSE_ENA_M | 1903 - (itr_idx << QINT_RQCTL_ITR_INDX_S) | 1904 - ((i + 1) << QINT_RQCTL_MSIX_INDX_S); 1906 + val = QINT_RQCTL_CAUSE_ENA_M | itr_idx | 1907 + (((i + 1) << QINT_RQCTL_MSIX_INDX_S) & 1908 + QINT_RQCTL_MSIX_INDX_M); 1905 1909 else 1906 - val = QINT_RQCTL_CAUSE_ENA_M | 1907 - (itr_idx << QINT_RQCTL_ITR_INDX_S) | 1908 - (reg_idx << QINT_RQCTL_MSIX_INDX_S); 1910 + val = QINT_RQCTL_CAUSE_ENA_M | itr_idx | 1911 + ((reg_idx << QINT_RQCTL_MSIX_INDX_S) & 1912 + QINT_RQCTL_MSIX_INDX_M); 1909 1913 wr32(hw, QINT_RQCTL(vsi->rxq_map[rxq]), val); 1910 1914 rxq++; 1911 1915 }
+12 -14
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
··· 1814 1814 struct ice_vsi *vsi = NULL; 1815 1815 struct ice_pf *pf = vf->pf; 1816 1816 unsigned long qmap; 1817 + u16 num_q_vectors; 1817 1818 int i; 1818 1819 1819 - if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states)) { 1820 + num_q_vectors = irqmap_info->num_vectors - ICE_NONQ_VECS_VF; 1821 + vsi = pf->vsi[vf->lan_vsi_idx]; 1822 + 1823 + if (!test_bit(ICE_VF_STATE_ACTIVE, vf->vf_states) || 1824 + !vsi || vsi->num_q_vectors < num_q_vectors || 1825 + irqmap_info->num_vectors == 0) { 1820 1826 v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1821 1827 goto error_param; 1822 1828 } 1823 1829 1824 - for (i = 0; i < irqmap_info->num_vectors; i++) { 1830 + for (i = 0; i < num_q_vectors; i++) { 1831 + struct ice_q_vector *q_vector = vsi->q_vectors[i]; 1832 + 1825 1833 map = &irqmap_info->vecmap[i]; 1826 1834 1827 1835 vector_id = map->vector_id; ··· 1841 1833 goto error_param; 1842 1834 } 1843 1835 1844 - vsi = pf->vsi[vf->lan_vsi_idx]; 1845 - if (!vsi) { 1846 - v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1847 - goto error_param; 1848 - } 1849 - 1850 1836 /* lookout for the invalid queue index */ 1851 1837 qmap = map->rxq_map; 1838 + q_vector->num_ring_rx = 0; 1852 1839 for_each_set_bit(vsi_q_id, &qmap, ICE_MAX_BASE_QS_PER_VF) { 1853 - struct ice_q_vector *q_vector; 1854 - 1855 1840 if (!ice_vc_isvalid_q_id(vf, vsi_id, vsi_q_id)) { 1856 1841 v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1857 1842 goto error_param; 1858 1843 } 1859 - q_vector = vsi->q_vectors[i]; 1860 1844 q_vector->num_ring_rx++; 1861 1845 q_vector->rx.itr_idx = map->rxitr_idx; 1862 1846 vsi->rx_rings[vsi_q_id]->q_vector = q_vector; 1863 1847 } 1864 1848 1865 1849 qmap = map->txq_map; 1850 + q_vector->num_ring_tx = 0; 1866 1851 for_each_set_bit(vsi_q_id, &qmap, ICE_MAX_BASE_QS_PER_VF) { 1867 - struct ice_q_vector *q_vector; 1868 - 1869 1852 if (!ice_vc_isvalid_q_id(vf, vsi_id, vsi_q_id)) { 1870 1853 v_ret = VIRTCHNL_STATUS_ERR_PARAM; 1871 1854 goto error_param; 1872 1855 } 1873 - q_vector = vsi->q_vectors[i]; 1874 1856 q_vector->num_ring_tx++; 1875 1857 q_vector->tx.itr_idx = map->txitr_idx; 1876 1858 vsi->tx_rings[vsi_q_id]->q_vector = q_vector;