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

ah.c (3405B)


      1// SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause
      2/*
      3 * Copyright(c) 2016 - 2019 Intel Corporation.
      4 */
      5
      6#include <linux/slab.h>
      7#include "ah.h"
      8#include "vt.h" /* for prints */
      9
     10/**
     11 * rvt_check_ah - validate the attributes of AH
     12 * @ibdev: the ib device
     13 * @ah_attr: the attributes of the AH
     14 *
     15 * If driver supports a more detailed check_ah function call back to it
     16 * otherwise just check the basics.
     17 *
     18 * Return: 0 on success
     19 */
     20int rvt_check_ah(struct ib_device *ibdev,
     21		 struct rdma_ah_attr *ah_attr)
     22{
     23	int err;
     24	int port_num = rdma_ah_get_port_num(ah_attr);
     25	struct ib_port_attr port_attr;
     26	struct rvt_dev_info *rdi = ib_to_rvt(ibdev);
     27	u8 ah_flags = rdma_ah_get_ah_flags(ah_attr);
     28	u8 static_rate = rdma_ah_get_static_rate(ah_attr);
     29
     30	err = ib_query_port(ibdev, port_num, &port_attr);
     31	if (err)
     32		return -EINVAL;
     33	if (port_num < 1 ||
     34	    port_num > ibdev->phys_port_cnt)
     35		return -EINVAL;
     36	if (static_rate != IB_RATE_PORT_CURRENT &&
     37	    ib_rate_to_mbps(static_rate) < 0)
     38		return -EINVAL;
     39	if ((ah_flags & IB_AH_GRH) &&
     40	    rdma_ah_read_grh(ah_attr)->sgid_index >= port_attr.gid_tbl_len)
     41		return -EINVAL;
     42	if (rdi->driver_f.check_ah)
     43		return rdi->driver_f.check_ah(ibdev, ah_attr);
     44	return 0;
     45}
     46EXPORT_SYMBOL(rvt_check_ah);
     47
     48/**
     49 * rvt_create_ah - create an address handle
     50 * @ibah: the IB address handle
     51 * @init_attr: the attributes of the AH
     52 * @udata: pointer to user's input output buffer information.
     53 *
     54 * This may be called from interrupt context.
     55 *
     56 * Return: 0 on success
     57 */
     58int rvt_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
     59		  struct ib_udata *udata)
     60{
     61	struct rvt_ah *ah = ibah_to_rvtah(ibah);
     62	struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
     63	unsigned long flags;
     64
     65	if (rvt_check_ah(ibah->device, init_attr->ah_attr))
     66		return -EINVAL;
     67
     68	spin_lock_irqsave(&dev->n_ahs_lock, flags);
     69	if (dev->n_ahs_allocated == dev->dparms.props.max_ah) {
     70		spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
     71		return -ENOMEM;
     72	}
     73
     74	dev->n_ahs_allocated++;
     75	spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
     76
     77	rdma_copy_ah_attr(&ah->attr, init_attr->ah_attr);
     78
     79	if (dev->driver_f.notify_new_ah)
     80		dev->driver_f.notify_new_ah(ibah->device,
     81					    init_attr->ah_attr, ah);
     82
     83	return 0;
     84}
     85
     86/**
     87 * rvt_destroy_ah - Destroy an address handle
     88 * @ibah: address handle
     89 * @destroy_flags: destroy address handle flags (see enum rdma_destroy_ah_flags)
     90 * Return: 0 on success
     91 */
     92int rvt_destroy_ah(struct ib_ah *ibah, u32 destroy_flags)
     93{
     94	struct rvt_dev_info *dev = ib_to_rvt(ibah->device);
     95	struct rvt_ah *ah = ibah_to_rvtah(ibah);
     96	unsigned long flags;
     97
     98	spin_lock_irqsave(&dev->n_ahs_lock, flags);
     99	dev->n_ahs_allocated--;
    100	spin_unlock_irqrestore(&dev->n_ahs_lock, flags);
    101
    102	rdma_destroy_ah_attr(&ah->attr);
    103	return 0;
    104}
    105
    106/**
    107 * rvt_modify_ah - modify an ah with given attrs
    108 * @ibah: address handle to modify
    109 * @ah_attr: attrs to apply
    110 *
    111 * Return: 0 on success
    112 */
    113int rvt_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
    114{
    115	struct rvt_ah *ah = ibah_to_rvtah(ibah);
    116
    117	if (rvt_check_ah(ibah->device, ah_attr))
    118		return -EINVAL;
    119
    120	ah->attr = *ah_attr;
    121
    122	return 0;
    123}
    124
    125/**
    126 * rvt_query_ah - return attrs for ah
    127 * @ibah: address handle to query
    128 * @ah_attr: return info in this
    129 *
    130 * Return: always 0
    131 */
    132int rvt_query_ah(struct ib_ah *ibah, struct rdma_ah_attr *ah_attr)
    133{
    134	struct rvt_ah *ah = ibah_to_rvtah(ibah);
    135
    136	*ah_attr = ah->attr;
    137
    138	return 0;
    139}