diff options
author | Shani Michaeli <shanim@mellanox.com> | 2013-02-06 11:19:10 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2013-02-25 13:44:31 -0500 |
commit | cc1ade94eeaa235b28fb139d4ba20b697be36768 (patch) | |
tree | eec68d01eacf570003af591581b8445d2bfde66d | |
parent | c89d127128dba62458e956388fef7e5d728e1ded (diff) |
mlx4_core: Disable memory windows for virtual functions
Do not enable memory windows allocation for virtual functions.
In addition, add a few safety checks, such as:
* Verifying the PD of a new MPT matches the VF.
* Making sure binding memory window isn't enabled for FMRs, and
that new memory windows are not FMR themselves.
Signed-off-by: Haggai Eran <haggaie@mellanox.com>
Signed-off-by: Shani Michaeli <shanim@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/fw.c | 11 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4.h | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mr.c | 14 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 49 |
4 files changed, 75 insertions, 15 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 8b3d0512a46b..a389612f8a4a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c | |||
@@ -757,15 +757,19 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
757 | u64 flags; | 757 | u64 flags; |
758 | int err = 0; | 758 | int err = 0; |
759 | u8 field; | 759 | u8 field; |
760 | u32 bmme_flags; | ||
760 | 761 | ||
761 | err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, | 762 | err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP, |
762 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); | 763 | MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE); |
763 | if (err) | 764 | if (err) |
764 | return err; | 765 | return err; |
765 | 766 | ||
766 | /* add port mng change event capability unconditionally to slaves */ | 767 | /* add port mng change event capability and disable mw type 1 |
768 | * unconditionally to slaves | ||
769 | */ | ||
767 | MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); | 770 | MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); |
768 | flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV; | 771 | flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV; |
772 | flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW; | ||
769 | MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); | 773 | MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET); |
770 | 774 | ||
771 | /* For guests, report Blueflame disabled */ | 775 | /* For guests, report Blueflame disabled */ |
@@ -773,6 +777,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, | |||
773 | field &= 0x7f; | 777 | field &= 0x7f; |
774 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET); | 778 | MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET); |
775 | 779 | ||
780 | /* For guests, disable mw type 2 */ | ||
781 | MLX4_GET(bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); | ||
782 | bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; | ||
783 | MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); | ||
784 | |||
776 | return 0; | 785 | return 0; |
777 | } | 786 | } |
778 | 787 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 5075236a140d..539212b1c8dc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -268,6 +268,22 @@ struct mlx4_icm_table { | |||
268 | struct mlx4_icm **icm; | 268 | struct mlx4_icm **icm; |
269 | }; | 269 | }; |
270 | 270 | ||
271 | #define MLX4_MPT_FLAG_SW_OWNS (0xfUL << 28) | ||
272 | #define MLX4_MPT_FLAG_FREE (0x3UL << 28) | ||
273 | #define MLX4_MPT_FLAG_MIO (1 << 17) | ||
274 | #define MLX4_MPT_FLAG_BIND_ENABLE (1 << 15) | ||
275 | #define MLX4_MPT_FLAG_PHYSICAL (1 << 9) | ||
276 | #define MLX4_MPT_FLAG_REGION (1 << 8) | ||
277 | |||
278 | #define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27) | ||
279 | #define MLX4_MPT_PD_FLAG_RAE (1 << 28) | ||
280 | #define MLX4_MPT_PD_FLAG_EN_INV (3 << 24) | ||
281 | |||
282 | #define MLX4_MPT_QP_FLAG_BOUND_QP (1 << 7) | ||
283 | |||
284 | #define MLX4_MPT_STATUS_SW 0xF0 | ||
285 | #define MLX4_MPT_STATUS_HW 0x00 | ||
286 | |||
271 | /* | 287 | /* |
272 | * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits. | 288 | * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits. |
273 | */ | 289 | */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 06b16e4ace80..5e785bdcc694 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -44,20 +44,6 @@ | |||
44 | #include "mlx4.h" | 44 | #include "mlx4.h" |
45 | #include "icm.h" | 45 | #include "icm.h" |
46 | 46 | ||
47 | #define MLX4_MPT_FLAG_SW_OWNS (0xfUL << 28) | ||
48 | #define MLX4_MPT_FLAG_FREE (0x3UL << 28) | ||
49 | #define MLX4_MPT_FLAG_MIO (1 << 17) | ||
50 | #define MLX4_MPT_FLAG_BIND_ENABLE (1 << 15) | ||
51 | #define MLX4_MPT_FLAG_PHYSICAL (1 << 9) | ||
52 | #define MLX4_MPT_FLAG_REGION (1 << 8) | ||
53 | |||
54 | #define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27) | ||
55 | #define MLX4_MPT_PD_FLAG_RAE (1 << 28) | ||
56 | #define MLX4_MPT_PD_FLAG_EN_INV (3 << 24) | ||
57 | |||
58 | #define MLX4_MPT_STATUS_SW 0xF0 | ||
59 | #define MLX4_MPT_STATUS_HW 0x00 | ||
60 | |||
61 | static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order) | 47 | static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order) |
62 | { | 48 | { |
63 | int o; | 49 | int o; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 2287dfda6212..9185e2eef8fa 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -1796,6 +1796,26 @@ static int mr_get_mtt_size(struct mlx4_mpt_entry *mpt) | |||
1796 | return be32_to_cpu(mpt->mtt_sz); | 1796 | return be32_to_cpu(mpt->mtt_sz); |
1797 | } | 1797 | } |
1798 | 1798 | ||
1799 | static u32 mr_get_pd(struct mlx4_mpt_entry *mpt) | ||
1800 | { | ||
1801 | return be32_to_cpu(mpt->pd_flags) & 0x00ffffff; | ||
1802 | } | ||
1803 | |||
1804 | static int mr_is_fmr(struct mlx4_mpt_entry *mpt) | ||
1805 | { | ||
1806 | return be32_to_cpu(mpt->pd_flags) & MLX4_MPT_PD_FLAG_FAST_REG; | ||
1807 | } | ||
1808 | |||
1809 | static int mr_is_bind_enabled(struct mlx4_mpt_entry *mpt) | ||
1810 | { | ||
1811 | return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_BIND_ENABLE; | ||
1812 | } | ||
1813 | |||
1814 | static int mr_is_region(struct mlx4_mpt_entry *mpt) | ||
1815 | { | ||
1816 | return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_REGION; | ||
1817 | } | ||
1818 | |||
1799 | static int qp_get_mtt_addr(struct mlx4_qp_context *qpc) | 1819 | static int qp_get_mtt_addr(struct mlx4_qp_context *qpc) |
1800 | { | 1820 | { |
1801 | return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8; | 1821 | return be32_to_cpu(qpc->mtt_base_addr_l) & 0xfffffff8; |
@@ -1856,12 +1876,41 @@ int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev *dev, int slave, | |||
1856 | int mtt_base = mr_get_mtt_addr(inbox->buf) / dev->caps.mtt_entry_sz; | 1876 | int mtt_base = mr_get_mtt_addr(inbox->buf) / dev->caps.mtt_entry_sz; |
1857 | int phys; | 1877 | int phys; |
1858 | int id; | 1878 | int id; |
1879 | u32 pd; | ||
1880 | int pd_slave; | ||
1859 | 1881 | ||
1860 | id = index & mpt_mask(dev); | 1882 | id = index & mpt_mask(dev); |
1861 | err = mr_res_start_move_to(dev, slave, id, RES_MPT_HW, &mpt); | 1883 | err = mr_res_start_move_to(dev, slave, id, RES_MPT_HW, &mpt); |
1862 | if (err) | 1884 | if (err) |
1863 | return err; | 1885 | return err; |
1864 | 1886 | ||
1887 | /* Disable memory windows for VFs. */ | ||
1888 | if (!mr_is_region(inbox->buf)) { | ||
1889 | err = -EPERM; | ||
1890 | goto ex_abort; | ||
1891 | } | ||
1892 | |||
1893 | /* Make sure that the PD bits related to the slave id are zeros. */ | ||
1894 | pd = mr_get_pd(inbox->buf); | ||
1895 | pd_slave = (pd >> 17) & 0x7f; | ||
1896 | if (pd_slave != 0 && pd_slave != slave) { | ||
1897 | err = -EPERM; | ||
1898 | goto ex_abort; | ||
1899 | } | ||
1900 | |||
1901 | if (mr_is_fmr(inbox->buf)) { | ||
1902 | /* FMR and Bind Enable are forbidden in slave devices. */ | ||
1903 | if (mr_is_bind_enabled(inbox->buf)) { | ||
1904 | err = -EPERM; | ||
1905 | goto ex_abort; | ||
1906 | } | ||
1907 | /* FMR and Memory Windows are also forbidden. */ | ||
1908 | if (!mr_is_region(inbox->buf)) { | ||
1909 | err = -EPERM; | ||
1910 | goto ex_abort; | ||
1911 | } | ||
1912 | } | ||
1913 | |||
1865 | phys = mr_phys_mpt(inbox->buf); | 1914 | phys = mr_phys_mpt(inbox->buf); |
1866 | if (!phys) { | 1915 | if (!phys) { |
1867 | err = get_res(dev, slave, mtt_base, RES_MTT, &mtt); | 1916 | err = get_res(dev, slave, mtt_base, RES_MTT, &mtt); |