Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc1ade94 authored by Shani Michaeli's avatar Shani Michaeli Committed by Roland Dreier
Browse files

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: default avatarHaggai Eran <haggaie@mellanox.com>
Signed-off-by: default avatarShani Michaeli <shanim@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
parent c89d1271
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -757,15 +757,19 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
	u64	flags;
	int	err = 0;
	u8	field;
	u32	bmme_flags;

	err = mlx4_cmd_box(dev, 0, outbox->dma, 0, 0, MLX4_CMD_QUERY_DEV_CAP,
			   MLX4_CMD_TIME_CLASS_A, MLX4_CMD_NATIVE);
	if (err)
		return err;

	/* add port mng change event capability unconditionally to slaves */
	/* add port mng change event capability and disable mw type 1
	 * unconditionally to slaves
	 */
	MLX4_GET(flags, outbox->buf, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);
	flags |= MLX4_DEV_CAP_FLAG_PORT_MNG_CHG_EV;
	flags &= ~MLX4_DEV_CAP_FLAG_MEM_WINDOW;
	MLX4_PUT(outbox->buf, flags, QUERY_DEV_CAP_EXT_FLAGS_OFFSET);

	/* For guests, report Blueflame disabled */
@@ -773,6 +777,11 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave,
	field &= 0x7f;
	MLX4_PUT(outbox->buf, field, QUERY_DEV_CAP_BF_OFFSET);

	/* For guests, disable mw type 2 */
	MLX4_GET(bmme_flags, outbox, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);
	bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN;
	MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET);

	return 0;
}

+16 −0
Original line number Diff line number Diff line
@@ -268,6 +268,22 @@ struct mlx4_icm_table {
	struct mlx4_icm	      **icm;
};

#define MLX4_MPT_FLAG_SW_OWNS	    (0xfUL << 28)
#define MLX4_MPT_FLAG_FREE	    (0x3UL << 28)
#define MLX4_MPT_FLAG_MIO	    (1 << 17)
#define MLX4_MPT_FLAG_BIND_ENABLE   (1 << 15)
#define MLX4_MPT_FLAG_PHYSICAL	    (1 <<  9)
#define MLX4_MPT_FLAG_REGION	    (1 <<  8)

#define MLX4_MPT_PD_FLAG_FAST_REG   (1 << 27)
#define MLX4_MPT_PD_FLAG_RAE	    (1 << 28)
#define MLX4_MPT_PD_FLAG_EN_INV	    (3 << 24)

#define MLX4_MPT_QP_FLAG_BOUND_QP   (1 << 7)

#define MLX4_MPT_STATUS_SW		0xF0
#define MLX4_MPT_STATUS_HW		0x00

/*
 * Must be packed because mtt_seg is 64 bits but only aligned to 32 bits.
 */
+0 −14
Original line number Diff line number Diff line
@@ -44,20 +44,6 @@
#include "mlx4.h"
#include "icm.h"

#define MLX4_MPT_FLAG_SW_OWNS	    (0xfUL << 28)
#define MLX4_MPT_FLAG_FREE	    (0x3UL << 28)
#define MLX4_MPT_FLAG_MIO	    (1 << 17)
#define MLX4_MPT_FLAG_BIND_ENABLE   (1 << 15)
#define MLX4_MPT_FLAG_PHYSICAL	    (1 <<  9)
#define MLX4_MPT_FLAG_REGION	    (1 <<  8)

#define MLX4_MPT_PD_FLAG_FAST_REG   (1 << 27)
#define MLX4_MPT_PD_FLAG_RAE	    (1 << 28)
#define MLX4_MPT_PD_FLAG_EN_INV	    (3 << 24)

#define MLX4_MPT_STATUS_SW		0xF0
#define MLX4_MPT_STATUS_HW		0x00

static u32 mlx4_buddy_alloc(struct mlx4_buddy *buddy, int order)
{
	int o;
+49 −0
Original line number Diff line number Diff line
@@ -1796,6 +1796,26 @@ static int mr_get_mtt_size(struct mlx4_mpt_entry *mpt)
	return be32_to_cpu(mpt->mtt_sz);
}

static u32 mr_get_pd(struct mlx4_mpt_entry *mpt)
{
	return be32_to_cpu(mpt->pd_flags) & 0x00ffffff;
}

static int mr_is_fmr(struct mlx4_mpt_entry *mpt)
{
	return be32_to_cpu(mpt->pd_flags) & MLX4_MPT_PD_FLAG_FAST_REG;
}

static int mr_is_bind_enabled(struct mlx4_mpt_entry *mpt)
{
	return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_BIND_ENABLE;
}

static int mr_is_region(struct mlx4_mpt_entry *mpt)
{
	return be32_to_cpu(mpt->flags) & MLX4_MPT_FLAG_REGION;
}

static int qp_get_mtt_addr(struct mlx4_qp_context *qpc)
{
	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,
	int mtt_base = mr_get_mtt_addr(inbox->buf) / dev->caps.mtt_entry_sz;
	int phys;
	int id;
	u32 pd;
	int pd_slave;

	id = index & mpt_mask(dev);
	err = mr_res_start_move_to(dev, slave, id, RES_MPT_HW, &mpt);
	if (err)
		return err;

	/* Disable memory windows for VFs. */
	if (!mr_is_region(inbox->buf)) {
		err = -EPERM;
		goto ex_abort;
	}

	/* Make sure that the PD bits related to the slave id are zeros. */
	pd = mr_get_pd(inbox->buf);
	pd_slave = (pd >> 17) & 0x7f;
	if (pd_slave != 0 && pd_slave != slave) {
		err = -EPERM;
		goto ex_abort;
	}

	if (mr_is_fmr(inbox->buf)) {
		/* FMR and Bind Enable are forbidden in slave devices. */
		if (mr_is_bind_enabled(inbox->buf)) {
			err = -EPERM;
			goto ex_abort;
		}
		/* FMR and Memory Windows are also forbidden. */
		if (!mr_is_region(inbox->buf)) {
			err = -EPERM;
			goto ex_abort;
		}
	}

	phys = mr_phys_mpt(inbox->buf);
	if (!phys) {
		err = get_res(dev, slave, mtt_base, RES_MTT, &mtt);