cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rdma.c (4632B)


      1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
      2/* Copyright (c) 2019 Mellanox Technologies */
      3
      4#include <linux/mlx5/vport.h>
      5#include <rdma/ib_verbs.h>
      6#include <net/addrconf.h>
      7
      8#include "lib/mlx5.h"
      9#include "eswitch.h"
     10#include "fs_core.h"
     11#include "rdma.h"
     12
     13static void mlx5_rdma_disable_roce_steering(struct mlx5_core_dev *dev)
     14{
     15	struct mlx5_core_roce *roce = &dev->priv.roce;
     16
     17	mlx5_del_flow_rules(roce->allow_rule);
     18	mlx5_destroy_flow_group(roce->fg);
     19	mlx5_destroy_flow_table(roce->ft);
     20}
     21
     22static int mlx5_rdma_enable_roce_steering(struct mlx5_core_dev *dev)
     23{
     24	int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
     25	struct mlx5_core_roce *roce = &dev->priv.roce;
     26	struct mlx5_flow_handle *flow_rule = NULL;
     27	struct mlx5_flow_table_attr ft_attr = {};
     28	struct mlx5_flow_namespace *ns = NULL;
     29	struct mlx5_flow_act flow_act = {};
     30	struct mlx5_flow_spec *spec;
     31	struct mlx5_flow_table *ft;
     32	struct mlx5_flow_group *fg;
     33	void *match_criteria;
     34	u32 *flow_group_in;
     35	void *misc;
     36	int err;
     37
     38	if (!(MLX5_CAP_FLOWTABLE_RDMA_RX(dev, ft_support) &&
     39	      MLX5_CAP_FLOWTABLE_RDMA_RX(dev, table_miss_action_domain)))
     40		return -EOPNOTSUPP;
     41
     42	flow_group_in = kvzalloc(inlen, GFP_KERNEL);
     43	if (!flow_group_in)
     44		return -ENOMEM;
     45	spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
     46	if (!spec) {
     47		kvfree(flow_group_in);
     48		return -ENOMEM;
     49	}
     50
     51	ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_RDMA_RX_KERNEL);
     52	if (!ns) {
     53		mlx5_core_err(dev, "Failed to get RDMA RX namespace");
     54		err = -EOPNOTSUPP;
     55		goto free;
     56	}
     57
     58	ft_attr.max_fte = 1;
     59	ft = mlx5_create_flow_table(ns, &ft_attr);
     60	if (IS_ERR(ft)) {
     61		mlx5_core_err(dev, "Failed to create RDMA RX flow table");
     62		err = PTR_ERR(ft);
     63		goto free;
     64	}
     65
     66	MLX5_SET(create_flow_group_in, flow_group_in, match_criteria_enable,
     67		 MLX5_MATCH_MISC_PARAMETERS);
     68	match_criteria = MLX5_ADDR_OF(create_flow_group_in, flow_group_in,
     69				      match_criteria);
     70	MLX5_SET_TO_ONES(fte_match_param, match_criteria,
     71			 misc_parameters.source_port);
     72
     73	fg = mlx5_create_flow_group(ft, flow_group_in);
     74	if (IS_ERR(fg)) {
     75		err = PTR_ERR(fg);
     76		mlx5_core_err(dev, "Failed to create RDMA RX flow group err(%d)\n", err);
     77		goto destroy_flow_table;
     78	}
     79
     80	spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS;
     81	misc = MLX5_ADDR_OF(fte_match_param, spec->match_value,
     82			    misc_parameters);
     83	MLX5_SET(fte_match_set_misc, misc, source_port,
     84		 dev->priv.eswitch->manager_vport);
     85	misc = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
     86			    misc_parameters);
     87	MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
     88
     89	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW;
     90	flow_rule = mlx5_add_flow_rules(ft, spec, &flow_act, NULL, 0);
     91	if (IS_ERR(flow_rule)) {
     92		err = PTR_ERR(flow_rule);
     93		mlx5_core_err(dev, "Failed to add RoCE allow rule, err=%d\n",
     94			      err);
     95		goto destroy_flow_group;
     96	}
     97
     98	kvfree(spec);
     99	kvfree(flow_group_in);
    100	roce->ft = ft;
    101	roce->fg = fg;
    102	roce->allow_rule = flow_rule;
    103
    104	return 0;
    105
    106destroy_flow_group:
    107	mlx5_destroy_flow_group(fg);
    108destroy_flow_table:
    109	mlx5_destroy_flow_table(ft);
    110free:
    111	kvfree(spec);
    112	kvfree(flow_group_in);
    113	return err;
    114}
    115
    116static void mlx5_rdma_del_roce_addr(struct mlx5_core_dev *dev)
    117{
    118	mlx5_core_roce_gid_set(dev, 0, 0, 0,
    119			       NULL, NULL, false, 0, 1);
    120}
    121
    122static void mlx5_rdma_make_default_gid(struct mlx5_core_dev *dev, union ib_gid *gid)
    123{
    124	u8 hw_id[ETH_ALEN];
    125
    126	mlx5_query_mac_address(dev, hw_id);
    127	gid->global.subnet_prefix = cpu_to_be64(0xfe80000000000000LL);
    128	addrconf_addr_eui48(&gid->raw[8], hw_id);
    129}
    130
    131static int mlx5_rdma_add_roce_addr(struct mlx5_core_dev *dev)
    132{
    133	union ib_gid gid;
    134	u8 mac[ETH_ALEN];
    135
    136	mlx5_rdma_make_default_gid(dev, &gid);
    137	return mlx5_core_roce_gid_set(dev, 0,
    138				      MLX5_ROCE_VERSION_1,
    139				      0, gid.raw, mac,
    140				      false, 0, 1);
    141}
    142
    143void mlx5_rdma_disable_roce(struct mlx5_core_dev *dev)
    144{
    145	struct mlx5_core_roce *roce = &dev->priv.roce;
    146
    147	if (!roce->ft)
    148		return;
    149
    150	mlx5_rdma_disable_roce_steering(dev);
    151	mlx5_rdma_del_roce_addr(dev);
    152	mlx5_nic_vport_disable_roce(dev);
    153}
    154
    155void mlx5_rdma_enable_roce(struct mlx5_core_dev *dev)
    156{
    157	int err;
    158
    159	if (!MLX5_CAP_GEN(dev, roce))
    160		return;
    161
    162	err = mlx5_nic_vport_enable_roce(dev);
    163	if (err) {
    164		mlx5_core_err(dev, "Failed to enable RoCE: %d\n", err);
    165		return;
    166	}
    167
    168	err = mlx5_rdma_add_roce_addr(dev);
    169	if (err) {
    170		mlx5_core_err(dev, "Failed to add RoCE address: %d\n", err);
    171		goto disable_roce;
    172	}
    173
    174	err = mlx5_rdma_enable_roce_steering(dev);
    175	if (err) {
    176		mlx5_core_err(dev, "Failed to enable RoCE steering: %d\n", err);
    177		goto del_roce_addr;
    178	}
    179
    180	return;
    181
    182del_roce_addr:
    183	mlx5_rdma_del_roce_addr(dev);
    184disable_roce:
    185	mlx5_nic_vport_disable_roce(dev);
    186}