summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMahesh A Saptasagar <c_msapta@qti.qualcomm.com>2015-02-27 18:37:09 -0800
committerAnjaneeDevi Kapparapu <c_akappa@qti.qualcomm.com>2015-03-03 18:47:45 +0530
commita147336cd9ec6428fcabb626471fbfa4accfefe4 (patch)
tree972086c2868e4d7add24eb2eaabc470f0291ec7c
parent13c964862011b272268463e6ee3e593bfc0a132e (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-xCORE/HDD/src/wlan_hdd_main.c242
-rw-r--r--CORE/HDD/src/wlan_hdd_tx_rx.c51
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