i40e/i40evf: add max buf len to aq debug print helper
authorShannon Nelson <shannon.nelson@intel.com>
Thu, 10 Jul 2014 07:58:20 +0000 (07:58 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Wed, 27 Aug 2014 07:40:14 +0000 (00:40 -0700)
There is at least one case in the Firmware API where the response to a
command changes the buffer size field in the AQ descriptor to a larger
number than what the request's buffer size started as.  This is in addition
to setting an error flag and is in order to tell the requester how much
larger a buffer is required for the answer.  We need to be sure not to
use that number when dumping the contents of the data buffer because it
can send us into the weeds and generate an invalid pointer exception.

This patch adds a max buffer size parameter to the print helper to be
sure the code knows when to stop.

Change-ID: Ib84f7ed72140fe9d600086d8f2002fc5d8753092
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/i40e/i40e_adminq.c
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_prototype.h
drivers/net/ethernet/intel/i40evf/i40e_adminq.c
drivers/net/ethernet/intel/i40evf/i40e_common.c
drivers/net/ethernet/intel/i40evf/i40e_prototype.h

index b29c157b1f57b7d587f00ff208a0124991d06bdb..72f5d25a222f0769ea514d5789407a543e66c3c2 100644 (file)
@@ -840,7 +840,8 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
 
        /* bump the tail */
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n");
-       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff);
+       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring,
+                     buff, buff_size);
        (hw->aq.asq.next_to_use)++;
        if (hw->aq.asq.next_to_use == hw->aq.asq.count)
                hw->aq.asq.next_to_use = 0;
@@ -891,7 +892,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
 
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
                   "AQTX: desc and buffer writeback:\n");
-       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff);
+       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size);
 
        /* update the error if time out occurred */
        if ((!cmd_completed) &&
@@ -987,7 +988,8 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
                       e->msg_size);
 
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
-       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf);
+       i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
+                     hw->aq.arq_buf_size);
 
        /* Restore the original datalen and buffer address in the desc,
         * FW updates datalen to indicate the event message
index df43e7c6777c238423af02e9171bf418ad08e339..01874c0fff1dcd4b71078318e29a206854271b80 100644 (file)
@@ -75,13 +75,15 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
  * @mask: debug mask
  * @desc: pointer to admin queue descriptor
  * @buffer: pointer to command buffer
+ * @buf_len: max length of buffer
  *
  * Dumps debug log about adminq command with descriptor contents.
  **/
 void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
-                  void *buffer)
+                  void *buffer, u16 buf_len)
 {
        struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
+       u16 len = le16_to_cpu(aq_desc->datalen);
        u8 *aq_buffer = (u8 *)buffer;
        u32 data[4];
        u32 i = 0;
@@ -105,7 +107,9 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
        if ((buffer != NULL) && (aq_desc->datalen != 0)) {
                memset(data, 0, sizeof(data));
                i40e_debug(hw, mask, "AQ CMD Buffer:\n");
-               for (i = 0; i < le16_to_cpu(aq_desc->datalen); i++) {
+               if (buf_len < len)
+                       len = buf_len;
+               for (i = 0; i < len; i++) {
                        data[((i % 16) / 4)] |=
                                ((u32)aq_buffer[i]) << (8 * (i % 4));
                        if ((i % 16) == 15) {
index 949a9a01778b9c17aad87a78af9a933ac191856a..0988b5c1fe87d080e950f146c4c0c0b8ae231189 100644 (file)
@@ -52,10 +52,8 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
                                struct i40e_asq_cmd_details *cmd_details);
 
 /* debug function for adminq */
-void i40e_debug_aq(struct i40e_hw *hw,
-                  enum i40e_debug_mask mask,
-                  void *desc,
-                  void *buffer);
+void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask,
+                  void *desc, void *buffer, u16 buf_len);
 
 void i40e_idle_aq(struct i40e_hw *hw);
 bool i40e_check_asq_alive(struct i40e_hw *hw);
index 00300603361464b4e9f3b20da7774a1069bdf071..f206be9178422afc01a955f481f8e523cbb3093c 100644 (file)
@@ -788,7 +788,8 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
 
        /* bump the tail */
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n");
-       i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff);
+       i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring,
+                       buff, buff_size);
        (hw->aq.asq.next_to_use)++;
        if (hw->aq.asq.next_to_use == hw->aq.asq.count)
                hw->aq.asq.next_to_use = 0;
@@ -842,7 +843,8 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
 
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
                   "AQTX: desc and buffer writeback:\n");
-       i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff);
+       i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff,
+                       buff_size);
 
        /* update the error if time out occurred */
        if ((!cmd_completed) &&
@@ -938,7 +940,8 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw,
                hw->aq.nvm_busy = false;
 
        i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
-       i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf);
+       i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
+                       hw->aq.arq_buf_size);
 
        /* Restore the original datalen and buffer address in the desc,
         * FW updates datalen to indicate the event message
index 4ea90bf239bb204ed5603b66680413191f46bf66..9525605519645eb241f5473bcdd345a0afe21a09 100644 (file)
@@ -75,13 +75,15 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw)
  * @mask: debug mask
  * @desc: pointer to admin queue descriptor
  * @buffer: pointer to command buffer
+ * @buf_len: max length of buffer
  *
  * Dumps debug log about adminq command with descriptor contents.
  **/
 void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
-                  void *buffer)
+                  void *buffer, u16 buf_len)
 {
        struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
+       u16 len = le16_to_cpu(aq_desc->datalen);
        u8 *aq_buffer = (u8 *)buffer;
        u32 data[4];
        u32 i = 0;
@@ -105,7 +107,9 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
        if ((buffer != NULL) && (aq_desc->datalen != 0)) {
                memset(data, 0, sizeof(data));
                i40e_debug(hw, mask, "AQ CMD Buffer:\n");
-               for (i = 0; i < le16_to_cpu(aq_desc->datalen); i++) {
+               if (buf_len < len)
+                       len = buf_len;
+               for (i = 0; i < len; i++) {
                        data[((i % 16) / 4)] |=
                                ((u32)aq_buffer[i]) << (8 * (i % 4));
                        if ((i % 16) == 15) {
index 849edcc2e398f7bfdaaea5eaf078ba714977ca5f..9173834825ac4cc1bbe5c3ecbc85e77db693c76f 100644 (file)
@@ -53,10 +53,8 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
 bool i40evf_asq_done(struct i40e_hw *hw);
 
 /* debug function for adminq */
-void i40evf_debug_aq(struct i40e_hw *hw,
-                  enum i40e_debug_mask mask,
-                  void *desc,
-                  void *buffer);
+void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask,
+                    void *desc, void *buffer, u16 buf_len);
 
 void i40e_idle_aq(struct i40e_hw *hw);
 void i40evf_resume_aq(struct i40e_hw *hw);