def test_reservered_qpn(self):
        """
        Alloc reserved qpn multiple times and then dealloc the qpns. In addition,
        the test includes bad flows where a fake qpn gets deallocated, and a
        real qpn gets deallocated twice.
        """
        try:
            # Alloc qp number multiple times.
            qpns = []
            for i in range(1000):
                qpns.append(Mlx5Context.reserved_qpn_alloc(self.ctx))
            for i in range(1000):
                Mlx5Context.reserved_qpn_dealloc(self.ctx, qpns[i])

            # Dealloc qp number that was not allocated.
            qpn = Mlx5Context.reserved_qpn_alloc(self.ctx)
            with self.assertRaises(PyverbsRDMAError) as ex:
                fake_qpn = qpn - 1
                Mlx5Context.reserved_qpn_dealloc(self.ctx, fake_qpn)
            self.assertEqual(ex.exception.error_code, errno.EINVAL)

            # Try to dealloc same qp number twice.
            Mlx5Context.reserved_qpn_dealloc(self.ctx, qpn)
            with self.assertRaises(PyverbsRDMAError) as ex:
                Mlx5Context.reserved_qpn_dealloc(self.ctx, qpn)
            self.assertEqual(ex.exception.error_code, errno.EINVAL)

        except PyverbsRDMAError as ex:
            if ex.error_code == errno.EOPNOTSUPP:
                raise unittest.SkipTest(
                    'Alloc reserved QP number is not supported')
            raise ex
예제 #2
0
    def test_mlx5_dek_management(self):
        """
        Test crypto login and DEK management APIs.
        The test checks also that invalid actions are not permited, e.g, create
        DEK not in login session.
        """
        try:
            self.pd = PD(self.ctx)
            cred_bytes = struct.pack('!6Q', *self.crypto_details['credential'])
            key = struct.pack('!5Q', *self.crypto_details['wrapped_key'])
            self.dek_init_attr = \
                Mlx5DEKInitAttr(self.pd, key=key,
                                key_size=dve.MLX5DV_CRYPTO_KEY_SIZE_128,
                                key_purpose=dve.MLX5DV_CRYPTO_KEY_PURPOSE_AES_XTS,
                                opaque=DEK_OPAQUE)
            self.verify_create_dek_out_of_login_session()
            self.verify_login_state(dve.MLX5DV_CRYPTO_LOGIN_STATE_NO_LOGIN)

            # Login to crypto session
            self.login_attr = Mlx5CryptoLoginAttr(cred_bytes)
            Mlx5Context.crypto_login(self.ctx, self.login_attr)
            self.verify_login_state(dve.MLX5DV_CRYPTO_LOGIN_STATE_VALID)
            self.verify_login_twice()
            self.dek = Mlx5DEK(self.ctx, self.dek_init_attr)
            self.verify_dek_opaque()
            self.dek.close()

            # Logout from crypto session
            Mlx5Context.crypto_logout(self.ctx)
            self.verify_login_state(dve.MLX5DV_CRYPTO_LOGIN_STATE_NO_LOGIN)
        except PyverbsRDMAError as ex:
            print(ex)
            if ex.error_code == errno.EOPNOTSUPP:
                raise unittest.SkipTest('Create crypto elements is not supported')
            raise ex
예제 #3
0
 def func_wrapper(instance):
     try:
         ctx = Mlx5Context(Mlx5DVContextAttr(), instance.dev_name)
     except PyverbsUserError as ex:
         raise unittest.SkipTest(f'Could not open mlx5 context ({ex})')
     except PyverbsRDMAError:
         raise unittest.SkipTest('Opening mlx5 context is not supported')
     # Query NIC Flow Table capabilities
     cmd_in = struct.pack('!HIH8s', MLX5_CMD_OP_QUERY_HCA_CAP, 0,
                          MLX5_CMD_MOD_NIC_FLOW_TABLE_CAP << 1 | 0x1,
                          bytes(8))
     try:
         cmd_out = Mlx5Context.devx_general_cmd(
             ctx, cmd_in, MLX5_CMD_OP_QUERY_HCA_CAP_OUT_LEN)
     except PyverbsRDMAError as ex:
         if ex.error_code in [errno.EOPNOTSUPP, errno.EPROTONOSUPPORT]:
             raise unittest.SkipTest(
                 'DevX general command is not supported')
         raise ex
     cmd_view = memoryview(cmd_out)
     status = cmd_view[0]
     if status:
         raise PyverbsRDMAError(
             'Query NIC Flow Table CAPs failed with status'
             f' ({status})')
     # Verify that both NIC RX and TX support reformat actions by checking
     # the following PRM fields: encap_general_header,
     # log_max_packet_reformat, and reformat (for both RX and TX).
     if not (cmd_view[20] & 0x80 and cmd_view[21] & 0x1f
             and cmd_view[80] & 0x1 and cmd_view[272] & 0x1):
         raise unittest.SkipTest('NIC flow table does not support reformat')
     return func(instance)
예제 #4
0
 def verify_login_twice(self):
     """
     Verify that when there is already a login session alive the second login
     fails.
     """
     with self.assertRaises(PyverbsRDMAError) as ex:
         Mlx5Context.crypto_login(self.ctx, self.login_attr)
     self.assertEqual(ex.exception.error_code, errno.EEXIST)
예제 #5
0
 def create_client_dek(self):
     """
     Create DEK using the client resources.
     """
     cred_bytes = struct.pack('!6Q', *self.crypto_details['credential'])
     log_attr = Mlx5CryptoLoginAttr(cred_bytes)
     Mlx5Context.crypto_login(self.client.ctx, log_attr)
     key = struct.pack('!5Q', *self.crypto_details['wrapped_key'])
     if self.key_size == dve.MLX5DV_CRYPTO_KEY_SIZE_256:
         key = struct.pack('!9Q', *self.crypto_details['wrapped_256_bits_key'])
     self.dek_attr = Mlx5DEKInitAttr(self.client.pd, key=key,
                                     key_size=self.key_size,
                                     key_purpose=dve.MLX5DV_CRYPTO_KEY_PURPOSE_AES_XTS)
     self.dek = Mlx5DEK(self.client.ctx, self.dek_attr)
예제 #6
0
    def wrapper(instance):
        cmd_in = struct.pack('!HIH8s', MLX5_CMD_OP_QUERY_HCA_CAP,
                             0, MLX5_CMD_MOD_DEVICE_MEMORY_CAP << 1 | 0x1,
                             bytes(8))
        cmd_out = Mlx5Context.devx_general_cmd(
            instance.ctx, cmd_in, MLX5_CMD_OP_QUERY_HCA_CAP_OUT_LEN)
        cmd_view = memoryview(cmd_out)
        status = cmd_view[0]
        if status:
            raise PyverbsRDMAError(
                'Query Device Memory CAPs failed with status'
                f' ({status})')

        memic_op_support = int.from_bytes(cmd_view[80:84], 'big')
        increment_size_sup = cmd_view[20]
        test_and_set_size_sup = cmd_view[22]
        # Verify that MEMIC atomic operations (both increment and test_and_set)
        # are supported with write/read size of 1 Byte.
        if memic_op_support & 0x3 != 0x3:
            raise unittest.SkipTest(
                'MEMIC atomic operations are not supported')
        if not increment_size_sup & test_and_set_size_sup & 0x1:
            raise unittest.SkipTest(
                'MEMIC atomic operations are not supported with 1 Bytes read/write sizes'
            )
        return func(instance)
예제 #7
0
        def _create_mr_devx(self, rdma_device, buf_size):
            """This method create mkey and memory buffer using devx (part of ofed driver).
            """
            mlx5dv_attr = Mlx5DVContextAttr()
            self.ctx = Mlx5Context(mlx5dv_attr, name=rdma_device)
            self.my_pd = PD(self.ctx)
            self.dv_pd = Mlx5DvObj(dve.MLX5DV_OBJ_PD, pd=self.my_pd).dvpd
            self.umem = self._create_umem(self.ctx, buf_size)
            self.mkey_ctx = SwMkc(umr_en=0,
                                  lr=1,
                                  lw=1,
                                  access_mode_1_0=0x1,
                                  pd=self.dv_pd.pdn,
                                  start_addr=self.umem.umem_addr,
                                  len=buf_size)
            mkey_in = CreateMkeyIn(sw_mkc=self.mkey_ctx,
                                   mkey_umem_id=self.umem.umem_id,
                                   mkey_umem_valid=1)
            self.mkey_obj = Mlx5DevxObj(self.ctx, mkey_in,
                                        len(CreateMkeyOut()))
            mkey_out = CreateMkeyOut(self.mkey_obj.out_view)
            if mkey_out.status:
                raise PyverbsRDMAError(
                    "Failed to create mkey with syndrome {0}".format(
                        mkey_out.syndrome))

            mkey_index = mkey_out.mkey_index
            self.lkey = mkey_index << 8
예제 #8
0
 def create_context(self):
     mlx5dv_attr = Mlx5DVContextAttr()
     try:
         self.ctx = Mlx5Context(mlx5dv_attr, name=self.dev_name)
     except PyverbsUserError as ex:
         raise unittest.SkipTest(f'Could not open mlx5 context ({ex})')
     except PyverbsRDMAError:
         raise unittest.SkipTest('Opening mlx5 context is not supported')
예제 #9
0
 def create_context(self):
     try:
         attr = Mlx5DVContextAttr(dve.MLX5DV_CONTEXT_FLAGS_DEVX)
         self.ctx = Mlx5Context(attr, self.dev_name)
     except PyverbsUserError as ex:
         raise unittest.SkipTest(f'Could not open mlx5 context ({ex})')
     except PyverbsRDMAError:
         raise unittest.SkipTest('Opening mlx5 DevX context is not supported')
예제 #10
0
 def __init__(self, dev_name):
     try:
         mlx5dv_attr = Mlx5DVContextAttr(e.MLX5DV_CONTEXT_FLAGS_DEVX)
         self.ctx = Mlx5Context(mlx5dv_attr, dev_name)
     except PyverbsUserError as ex:
         raise unittest.SkipTest('Could not open mlx5 context ({})'.format(
             str(ex)))
     except PyverbsRDMAError:
         raise unittest.SkipTest(
             'Opening mlx5 DevX context is not supported')
     self.pps = []
예제 #11
0
 def create_context(self):
     mlx5dv_attr = Mlx5DVContextAttr()
     try:
         self.ctx = Mlx5Context(mlx5dv_attr, name=self.dev_name)
     except PyverbsUserError as ex:
         raise unittest.SkipTest(f'Could not open mlx5 context ({ex})')
     except PyverbsRDMAError:
         raise unittest.SkipTest('Opening mlx5 context is not supported')
     if self.requested_dev_cap:
         if not self.ctx.query_mlx5_device().flags & self.requested_dev_cap:
             miss_caps = context_flags_to_str(self.requested_dev_cap)
             raise unittest.SkipTest(f'Device caps doesn\'t support {miss_caps}')
예제 #12
0
def check_crypto_caps(dev_name):
    """
    Check that this device support crypto actions.
    :param dev_name: The device name.
    """
    mlx5dv_attr = Mlx5DVContextAttr()
    ctx = Mlx5Context(mlx5dv_attr, name=dev_name)
    crypto_caps = ctx.query_mlx5_device().crypto_caps
    failed_selftests = crypto_caps['failed_selftests']
    if failed_selftests:
        raise unittest.SkipTest(f'The device crypto selftest failed ({failed_selftests})')
    if not dve.MLX5DV_CRYPTO_ENGINES_CAP_AES_XTS & crypto_caps['crypto_engines']:
        raise unittest.SkipTest('The device crypto engines does not support AES')
예제 #13
0
 def func_wrapper(instance):
     try:
         ctx = Mlx5Context(Mlx5DVContextAttr(), instance.dev_name)
     except PyverbsUserError as ex:
         raise unittest.SkipTest(f'Could not open mlx5 context ({ex})')
     except PyverbsRDMAError:
         raise unittest.SkipTest('Opening mlx5 context is not supported')
     # Query NIC Flow Table capabilities
     cmd_in = struct.pack('!HIH8s', MLX5_CMD_OP_QUERY_HCA_CAP, 0,
                          MLX5_CMD_MOD_NIC_FLOW_TABLE_CAP << 1 | 0x1,
                          bytes(8))
     cmd_out = Mlx5Context.devx_general_cmd(
         ctx, cmd_in, MLX5_CMD_OP_QUERY_HCA_CAP_OUT_LEN)
     cmd_view = memoryview(cmd_out)
     status = cmd_view[0]
     if status:
         raise PyverbsRDMAError(
             'Query NIC Flow Table CAPs failed with status'
             f' ({status})')
     # Verify that both NIC RX and TX support reformat actions
     if not (cmd_view[80] & 0x1 and cmd_view[272] & 0x1):
         raise unittest.SkipTest('NIC flow table does not support reformat')
     return func(instance)
 def create_conn_param(self, qp_num=0, conn_idx=0):
     if conn_idx and self.passive:
         try:
             ctx = self.child_id.context
             self.reserved_qp_num = Mlx5Context.reserved_qpn_alloc(ctx)
         except PyverbsRDMAError as ex:
             if ex.error_code == errno.EOPNOTSUPP:
                 raise unittest.SkipTest(
                     'Alloc reserved QP number is not supported')
             raise ex
         qp_num = self.reserved_qp_num
     else:
         qp_num = self.qps[conn_idx].qp_num
     return ConnParam(qp_num=qp_num)
def convert_ts_to_ns(ctx, device_ts):
    """
    Convert device timestamp from HCA core clock units to corresponding
    nanosecond counts.
    :param ctx: The context that gets this timestamp.
    :param device_ts: The device timestamp to translate.
    :return: Timestamp in nanoseconds
    """
    try:
        timestamp_in_ns = Mlx5Context.device_timestamp_to_ns(ctx, device_ts)
    except PyverbsRDMAError as ex:
        if ex.error_code == errno.EOPNOTSUPP:
            raise unittest.SkipTest('Converting timestamp to nanoseconds is not supported')
        raise ex
    return timestamp_in_ns
예제 #16
0
    def test_dma_memcpy_large_data_bad_flow(self):
        """
        Bad flow test, testing DMA memcpy with data larger than the maximum
        allowed size, according to the HCA capabilities.
        :return: None
        """
        try:
            ctx = Mlx5Context(Mlx5DVContextAttr(), name=self.dev_name)
        except PyverbsUserError as ex:
            raise unittest.SkipTest(f'Could not open mlx5 context ({ex})')
        except PyverbsRDMAError:
            raise unittest.SkipTest('Opening mlx5 context is not supported')
        max_size = ctx.query_mlx5_device(
            dve.MLX5DV_CONTEXT_MASK_WR_MEMCPY_LENGTH).max_wr_memcpy_length
        max_size = max_size if max_size else 1024

        with self.assertRaises(PyverbsRDMAError):
            self.dma_memcpy(max_size + 1)
예제 #17
0
    def test_dv_query_port(self):
        """
        Test the DV query port and that no error is returned.
        """
        for port in range(1, self.attr_ex.phys_port_cnt_ex + 1):
            try:
                port_attr = Mlx5Context.query_mlx5_port(self.ctx, port)
            except PyverbsRDMAError as ex:
                if ex.error_code in [errno.EOPNOTSUPP, errno.EPROTONOSUPPORT]:
                    raise unittest.SkipTest(
                        f'mlx5dv_query_port() isn\'t supported')
                raise ex

            if (port_attr.flags & e.MLX5DV_QUERY_PORT_VPORT_STEERING_ICM_RX_):
                self.assertNotEqual(port_attr.vport_steering_icm_rx, 0,
                                    f'Vport steering icm rx address is zero')

            if (port_attr.flags & e.MLX5DV_QUERY_PORT_VPORT_STEERING_ICM_TX_):
                self.assertNotEqual(port_attr.vport_steering_icm_tx, 0,
                                    f'Vport steering icm tx address is zero')

            if (port_attr.flags & e.MLX5DV_QUERY_PORT_VPORT_REG_C0_):
                self.assertNotEqual(port_attr.reg_c0_mask, 0,
                                    f'Vport reg c0 mask is zero')
 def disconnect(self):
     if self.cm_res.reserved_qp_num and self.cm_res.passive:
         Mlx5Context.reserved_qpn_dealloc(self.cm_res.child_id.context,
                                          self.cm_res.reserved_qp_num)
         self.cm_res.reserved_qp_num = 0
     super().disconnect()
예제 #19
0
 def verify_login_state(self, expected_state):
     """
     Query the session login state and verify that it's as expected.
     """
     state = Mlx5Context.query_login_state(self.ctx)
     self.assertEqual(state, expected_state)