aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShani Michaeli <shanim@mellanox.com>2013-02-06 11:19:10 -0500
committerRoland Dreier <roland@purestorage.com>2013-02-25 13:44:31 -0500
commitcc1ade94eeaa235b28fb139d4ba20b697be36768 (patch)
treeeec68d01eacf570003af591581b8445d2bfde66d
parentc89d127128dba62458e956388fef7e5d728e1ded (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.c11
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h16
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c14
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/resource_tracker.c49
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
61static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order) 47static 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
1799static u32 mr_get_pd(struct mlx4_mpt_entry *mpt)
1800{
1801 return be32_to_cpu(mpt->pd_flags) & 0x00ffffff;
1802}
1803
1804static 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
1809static 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
1814static int mr_is_region(struct mlx4_mpt_entry *mpt)
1815{
1816 return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_REGION;
1817}
1818
1799static int qp_get_mtt_addr(struct mlx4_qp_context *qpc) 1819static 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);