diff options
| author | Mahesh A Saptasagar <c_msapta@qti.qualcomm.com> | 2015-02-27 18:37:09 -0800 |
|---|---|---|
| committer | AnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com> | 2015-03-03 18:47:45 +0530 |
| commit | a147336cd9ec6428fcabb626471fbfa4accfefe4 (patch) | |
| tree | 972086c2868e4d7add24eb2eaabc470f0291ec7c | |
| parent | 13c964862011b272268463e6ee3e593bfc0a132e (diff) | |
qcacld-2.0: Protect netdev ops functions from SSR
This is prima to qcacld-2.0 propagation.
Protect netdev ops functions from accessing deallocated or
un-initialized data structures while SSR is in progress.
Change-Id: Iec49881017b8e7da34e82af995680765ddceee3d
CRs-Fixed: 801494
| -rwxr-xr-x | CORE/HDD/src/wlan_hdd_main.c | 242 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_tx_rx.c | 51 |
2 files changed, 197 insertions, 96 deletions
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 3cbdd0616462..71e9f2467baa 100755 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -7534,7 +7534,15 @@ static int hdd_driver_ioctl(hdd_adapter_t *pAdapter, struct ifreq *ifr) return ret; } -int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +/** + * __hdd_ioctl() - HDD ioctl handler + * @dev: pointer to net_device structure + * @ifr: pointer to ifreq structure + * @cmd: ioctl command + * + * Return: 0 for success and error number for failure. + */ +static int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *pHddCtx; @@ -7590,6 +7598,24 @@ int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) return ret; } +/** + * hdd_ioctl() - Wrapper function to protect __hdd_ioctl() function from SSR + * @dev: pointer to net_device structure + * @ifr: pointer to ifreq structure + * @cmd: ioctl command + * + * Return: 0 for success and error number for failure. + */ +static int hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + int ret; + + vos_ssr_protect(__func__); + ret = __hdd_ioctl(dev, ifr, cmd); + vos_ssr_unprotect(__func__); + + return ret; +} /* @@ -8311,18 +8337,15 @@ v_BOOL_t hdd_is_valid_mac_address(const tANI_U8 *pMacAddr) return (xdigit == 12 && (separator == 5 || separator == 0)); } -/**--------------------------------------------------------------------------- - - \brief hdd_open() - HDD Open function - - This is called in response to ifconfig up - - \param - dev Pointer to net_device structure - - \return - 0 for success non-zero for failure - - --------------------------------------------------------------------------*/ -int hdd_open (struct net_device *dev) +/** + * __hdd_open() - HDD Open function + * @dev: pointer to net_device structure + * + * This is called in response to ifconfig up + * + * Return: 0 for success and error number for failure + */ +static int __hdd_open(struct net_device *dev) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); @@ -8369,25 +8392,42 @@ int hdd_open (struct net_device *dev) return ret; } -int hdd_mon_open (struct net_device *dev) +/** + * hdd_open() - Wrapper function for __hdd_open to protect it from SSR + * @dev: pointer to net_device structure + * + * This is called in response to ifconfig up + * + * Return: 0 for success and error number for failure + */ +static int hdd_open(struct net_device *dev) { - netif_start_queue(dev); + int ret; - return 0; -} -/**--------------------------------------------------------------------------- + vos_ssr_protect(__func__); + ret = __hdd_open(dev); + vos_ssr_unprotect(__func__); - \brief hdd_stop() - HDD stop function - - This is called in response to ifconfig down + return ret; +} - \param - dev Pointer to net_device structure - \return - 0 for success non-zero for failure +int hdd_mon_open (struct net_device *dev) +{ + netif_start_queue(dev); - --------------------------------------------------------------------------*/ + return 0; +} -int hdd_stop (struct net_device *dev) +/** + * __hdd_stop() - HDD stop function + * @dev: pointer to net_device structure + * + * This is called in response to ifconfig down + * + * Return: 0 for success and error number for failure + */ +static int __hdd_stop(struct net_device *dev) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); @@ -8492,57 +8532,79 @@ int hdd_stop (struct net_device *dev) return 0; } -/**--------------------------------------------------------------------------- - - \brief hdd_uninit() - HDD uninit function - - This is called during the netdev unregister to uninitialize all data -associated with the device +/** + * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR + * @dev: pointer to net_device structure + * + * This is called in response to ifconfig down + * + * Return: 0 for success and error number for failure + */ +static int hdd_stop (struct net_device *dev) +{ + int ret; - \param - dev Pointer to net_device structure + vos_ssr_protect(__func__); + ret = __hdd_stop(dev); + vos_ssr_unprotect(__func__); - \return - void + return ret; +} - --------------------------------------------------------------------------*/ -static void hdd_uninit (struct net_device *dev) +/** + * __hdd_uninit() - HDD uninit function + * @dev: pointer to net_device structure + * + * This is called during the netdev unregister to uninitialize all data + * associated with the device + * + * Return: none + */ +static void __hdd_uninit(struct net_device *dev) { - hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); - ENTER(); + ENTER(); - do - { - if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) - { - hddLog(VOS_TRACE_LEVEL_FATAL, - "%s: Invalid magic", __func__); - break; - } + if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) { + hddLog(LOGP, FL("Invalid magic")); + return; + } - if (NULL == pAdapter->pHddCtx) - { - hddLog(VOS_TRACE_LEVEL_FATAL, - "%s: NULL pHddCtx", __func__); - break; - } + if (NULL == pAdapter->pHddCtx) { + hddLog(LOGP, FL("NULL pHddCtx")); + return; + } - if (dev != pAdapter->dev) - { - hddLog(VOS_TRACE_LEVEL_FATAL, - "%s: Invalid device reference", __func__); - /* we haven't validated all cases so let this go for now */ - } + if (dev != pAdapter->dev) + hddLog(LOGP, FL("Invalid device reference")); - hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter); + hdd_deinit_adapter(pAdapter->pHddCtx, pAdapter); - /* after uninit our adapter structure will no longer be valid */ - pAdapter->dev = NULL; - pAdapter->magic = 0; - } while (0); + /* After uninit our adapter structure will no longer be valid */ + pAdapter->dev = NULL; + pAdapter->magic = 0; - EXIT(); + EXIT(); +} + +/** + * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR + * @dev: pointer to net_device structure + * + * This is called during the netdev unregister to uninitialize all data + * associated with the device + * + * Return: none + */ +static void hdd_uninit(struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_uninit(dev); + vos_ssr_unprotect(__func__); } + /**--------------------------------------------------------------------------- \brief hdd_full_pwr_cbk() - HDD full power callback function @@ -8657,32 +8719,50 @@ VOS_STATUS hdd_read_cfg_file(v_VOID_t *pCtx, char *pFileName, return VOS_STATUS_SUCCESS; } -/**--------------------------------------------------------------------------- - - \brief hdd_set_mac_address() - +/** + * __hdd_set_mac_address() - HDD set mac address + * @dev: pointer to net_device structure + * @addr: Pointer to the sockaddr + * + * This function sets the user specified mac address using + * the command ifconfig wlanX hw ether <mac adress>. + * + * Return: 0 for success. + */ +static int __hdd_set_mac_address(struct net_device *dev, void *addr) +{ + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + struct sockaddr *psta_mac_addr = addr; - This function sets the user specified mac address using - the command ifconfig wlanX hw ether <mac adress>. + ENTER(); - \param - dev - Pointer to the net device. - - addr - Pointer to the sockaddr. - \return - 0 for success, non zero for failure + memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN); + memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); - --------------------------------------------------------------------------*/ + EXIT(); + return 0; +} +/** + * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address() + * function from SSR + * @dev: pointer to net_device structure + * @addr: Pointer to the sockaddr + * + * This function sets the user specified mac address using + * the command ifconfig wlanX hw ether <mac adress>. + * + * Return: 0 for success. + */ static int hdd_set_mac_address(struct net_device *dev, void *addr) { - hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); - struct sockaddr *psta_mac_addr = addr; - eHalStatus halStatus = eHAL_STATUS_SUCCESS; + int ret; - ENTER(); + vos_ssr_protect(__func__); + ret = __hdd_set_mac_address(dev, addr); + vos_ssr_unprotect(__func__); - memcpy(&pAdapter->macAddressCurrent, psta_mac_addr->sa_data, ETH_ALEN); - memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN); - - EXIT(); - return halStatus; + return ret; } tANI_U8* wlan_hdd_get_intf_addr(hdd_context_t* pHddCtx) diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index 66559e6854e4..b6b2abe6262b 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -47,6 +47,7 @@ #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/etherdevice.h> +#include <vos_sched.h> #ifdef IPV6_MCAST_WAR #include <linux/if_ether.h> #endif @@ -1012,15 +1013,17 @@ VOS_STATUS hdd_Ibss_GetStaId(hdd_station_ctx_t *pHddStaCtx, v_MACADDR_t *pMacAdd return VOS_STATUS_E_FAILURE; } -/**============================================================================ - @brief hdd_tx_timeout() - Function called by OS if there is any - timeout during transmission. Since HDD simply enqueues packet - and returns control to OS right away, this would never be invoked - - @param dev : [in] pointer to Libra network device - @return : None - ===========================================================================*/ -void hdd_tx_timeout(struct net_device *dev) +/** + * __hdd_tx_timeout() - HDD tx timeout handler + * @dev: pointer to net_device structure + * + * Function called by OS if there is any timeout during transmission. + * Since HDD simply enqueues packet and returns control to OS right away, + * this would never be invoked + * + * Return: none + */ +static void __hdd_tx_timeout(struct net_device *dev) { hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); struct netdev_queue *txq; @@ -1028,10 +1031,12 @@ void hdd_tx_timeout(struct net_device *dev) hddLog(LOGE, FL("Transmission timeout occurred jiffies %lu trans_start %lu"), jiffies, dev->trans_start); - //Getting here implies we disabled the TX queues for too long. Queues are - //disabled either because of disassociation or low resource scenarios. In - //case of disassociation it is ok to ignore this. But if associated, we have - //do possible recovery here + /* + * Getting here implies we disabled the TX queues for too long. Queues are + * disabled either because of disassociation or low resource scenarios. In + * case of disassociation it is ok to ignore this. But if associated, we have + * do possible recovery here. + */ VOS_TRACE( VOS_MODULE_ID_HDD_DATA, VOS_TRACE_LEVEL_INFO, "num_bytes AC0: %d AC1: %d AC2: %d AC3: %d", @@ -1047,8 +1052,7 @@ void hdd_tx_timeout(struct net_device *dev) pAdapter->isTxSuspended[2], pAdapter->isTxSuspended[3]); - for (i = 0; i < 8; i++) - { + for (i = 0; i < 8; i++) { txq = netdev_get_tx_queue(dev, i); hddLog(LOG1, FL("Queue%d status: %d txq->trans_start %lu"), i, netif_tx_queue_stopped(txq), txq->trans_start); @@ -1058,6 +1062,23 @@ void hdd_tx_timeout(struct net_device *dev) "carrier state: %d", netif_carrier_ok(dev)); } +/** + * hdd_tx_timeout() - Wrapper function to protect __hdd_tx_timeout from SSR + * @dev: pointer to net_device structure + * + * Function called by OS if there is any timeout during transmission. + * Since HDD simply enqueues packet and returns control to OS right away, + * this would never be invoked + * + * Return: none + */ +void hdd_tx_timeout(struct net_device *dev) +{ + vos_ssr_protect(__func__); + __hdd_tx_timeout(dev); + vos_ssr_unprotect(__func__); +} + /**============================================================================ @brief hdd_stats() - Function registered with the Linux OS for |
