1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/list.h> 4 #include <linux/netdevice.h> 5 #include <linux/xarray.h> 6 #include <net/net_namespace.h> 7 #include <net/psp.h> 8 9 #include "psp.h" 10 #include "psp-nl-gen.h" 11 12 DEFINE_XARRAY_ALLOC1(psp_devs); 13 struct mutex psp_devs_lock; 14 15 /** 16 * DOC: PSP locking 17 * 18 * psp_devs_lock protects the psp_devs xarray. 19 * Ordering is take the psp_devs_lock and then the instance lock. 20 * Each instance is protected by RCU, and has a refcount. 21 * When driver unregisters the instance gets flushed, but struct sticks around. 22 */ 23 24 /** 25 * psp_dev_check_access() - check if user in a given net ns can access PSP dev 26 * @psd: PSP device structure user is trying to access 27 * @net: net namespace user is in 28 * 29 * Return: 0 if PSP device should be visible in @net, errno otherwise. 30 */ 31 int psp_dev_check_access(struct psp_dev *psd, struct net *net) 32 { 33 if (dev_net(psd->main_netdev) == net) 34 return 0; 35 return -ENOENT; 36 } 37 38 /** 39 * psp_dev_create() - create and register PSP device 40 * @netdev: main netdevice 41 * @psd_ops: driver callbacks 42 * @psd_caps: device capabilities 43 * @priv_ptr: back-pointer to driver private data 44 * 45 * Return: pointer to allocated PSP device, or ERR_PTR. 46 */ 47 struct psp_dev * 48 psp_dev_create(struct net_device *netdev, 49 struct psp_dev_ops *psd_ops, struct psp_dev_caps *psd_caps, 50 void *priv_ptr) 51 { 52 struct psp_dev *psd; 53 static u32 last_id; 54 int err; 55 56 if (WARN_ON(!psd_caps->versions || 57 !psd_ops->set_config || 58 !psd_ops->key_rotate || 59 !psd_ops->rx_spi_alloc || 60 !psd_ops->tx_key_add || 61 !psd_ops->tx_key_del)) 62 return ERR_PTR(-EINVAL); 63 64 psd = kzalloc(sizeof(*psd), GFP_KERNEL); 65 if (!psd) 66 return ERR_PTR(-ENOMEM); 67 68 psd->main_netdev = netdev; 69 psd->ops = psd_ops; 70 psd->caps = psd_caps; 71 psd->drv_priv = priv_ptr; 72 73 mutex_init(&psd->lock); 74 INIT_LIST_HEAD(&psd->active_assocs); 75 INIT_LIST_HEAD(&psd->prev_assocs); 76 INIT_LIST_HEAD(&psd->stale_assocs); 77 refcount_set(&psd->refcnt, 1); 78 79 mutex_lock(&psp_devs_lock); 80 err = xa_alloc_cyclic(&psp_devs, &psd->id, psd, xa_limit_16b, 81 &last_id, GFP_KERNEL); 82 if (err) { 83 mutex_unlock(&psp_devs_lock); 84 kfree(psd); 85 return ERR_PTR(err); 86 } 87 mutex_lock(&psd->lock); 88 mutex_unlock(&psp_devs_lock); 89 90 psp_nl_notify_dev(psd, PSP_CMD_DEV_ADD_NTF); 91 92 rcu_assign_pointer(netdev->psp_dev, psd); 93 94 mutex_unlock(&psd->lock); 95 96 return psd; 97 } 98 EXPORT_SYMBOL(psp_dev_create); 99 100 void psp_dev_destroy(struct psp_dev *psd) 101 { 102 mutex_lock(&psp_devs_lock); 103 xa_erase(&psp_devs, psd->id); 104 mutex_unlock(&psp_devs_lock); 105 106 mutex_destroy(&psd->lock); 107 kfree_rcu(psd, rcu); 108 } 109 110 /** 111 * psp_dev_unregister() - unregister PSP device 112 * @psd: PSP device structure 113 */ 114 void psp_dev_unregister(struct psp_dev *psd) 115 { 116 struct psp_assoc *pas, *next; 117 118 mutex_lock(&psp_devs_lock); 119 mutex_lock(&psd->lock); 120 121 psp_nl_notify_dev(psd, PSP_CMD_DEV_DEL_NTF); 122 123 /* Wait until psp_dev_destroy() to call xa_erase() to prevent a 124 * different psd from being added to the xarray with this id, while 125 * there are still references to this psd being held. 126 */ 127 xa_store(&psp_devs, psd->id, NULL, GFP_KERNEL); 128 mutex_unlock(&psp_devs_lock); 129 130 list_splice_init(&psd->active_assocs, &psd->prev_assocs); 131 list_splice_init(&psd->prev_assocs, &psd->stale_assocs); 132 list_for_each_entry_safe(pas, next, &psd->stale_assocs, assocs_list) 133 psp_dev_tx_key_del(psd, pas); 134 135 rcu_assign_pointer(psd->main_netdev->psp_dev, NULL); 136 137 psd->ops = NULL; 138 psd->drv_priv = NULL; 139 140 mutex_unlock(&psd->lock); 141 142 psp_dev_put(psd); 143 } 144 EXPORT_SYMBOL(psp_dev_unregister); 145 146 unsigned int psp_key_size(u32 version) 147 { 148 switch (version) { 149 case PSP_VERSION_HDR0_AES_GCM_128: 150 case PSP_VERSION_HDR0_AES_GMAC_128: 151 return 16; 152 case PSP_VERSION_HDR0_AES_GCM_256: 153 case PSP_VERSION_HDR0_AES_GMAC_256: 154 return 32; 155 default: 156 return 0; 157 } 158 } 159 EXPORT_SYMBOL(psp_key_size); 160 161 static int __init psp_init(void) 162 { 163 mutex_init(&psp_devs_lock); 164 165 return genl_register_family(&psp_nl_family); 166 } 167 168 subsys_initcall(psp_init); 169