Commit 82add4e1 authored by Shivasharan S's avatar Shivasharan S Committed by Martin K. Petersen

scsi: megaraid_sas: Incorrect processing of IOCTL frames for SMP/STP commands

cmd->frame->dcmd.opcode will be valid only for MFI_CMD_DCMD
IOCTL frames. Currently driver check for cmd->frame->dcmd.opcode without
checking cmd type. Ensure we check dcmd opcode only for MFI_CMD_DCMD
commands. Separate handling of MFI_CMD_SMP/STP commands from
MFI_CMD_DCMD in completion path.
Signed-off-by: default avatarKashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: default avatarShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b9637d14
...@@ -187,16 +187,19 @@ ...@@ -187,16 +187,19 @@
/* /*
* MFI command opcodes * MFI command opcodes
*/ */
#define MFI_CMD_INIT 0x00 enum MFI_CMD_OP {
#define MFI_CMD_LD_READ 0x01 MFI_CMD_INIT = 0x0,
#define MFI_CMD_LD_WRITE 0x02 MFI_CMD_LD_READ = 0x1,
#define MFI_CMD_LD_SCSI_IO 0x03 MFI_CMD_LD_WRITE = 0x2,
#define MFI_CMD_PD_SCSI_IO 0x04 MFI_CMD_LD_SCSI_IO = 0x3,
#define MFI_CMD_DCMD 0x05 MFI_CMD_PD_SCSI_IO = 0x4,
#define MFI_CMD_ABORT 0x06 MFI_CMD_DCMD = 0x5,
#define MFI_CMD_SMP 0x07 MFI_CMD_ABORT = 0x6,
#define MFI_CMD_STP 0x08 MFI_CMD_SMP = 0x7,
#define MFI_CMD_INVALID 0xff MFI_CMD_STP = 0x8,
MFI_CMD_OP_COUNT,
MFI_CMD_INVALID = 0xff
};
#define MR_DCMD_CTRL_GET_INFO 0x01010000 #define MR_DCMD_CTRL_GET_INFO 0x01010000
#define MR_DCMD_LD_GET_LIST 0x03010000 #define MR_DCMD_LD_GET_LIST 0x03010000
......
...@@ -3298,6 +3298,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, ...@@ -3298,6 +3298,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
case MFI_CMD_SMP: case MFI_CMD_SMP:
case MFI_CMD_STP: case MFI_CMD_STP:
megasas_complete_int_cmd(instance, cmd);
break;
case MFI_CMD_DCMD: case MFI_CMD_DCMD:
opcode = le32_to_cpu(cmd->frame->dcmd.opcode); opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
/* Check for LD map update */ /* Check for LD map update */
...@@ -3384,6 +3387,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, ...@@ -3384,6 +3387,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
default: default:
dev_info(&instance->pdev->dev, "Unknown command completed! [0x%X]\n", dev_info(&instance->pdev->dev, "Unknown command completed! [0x%X]\n",
hdr->cmd); hdr->cmd);
megasas_complete_int_cmd(instance, cmd);
break; break;
} }
} }
...@@ -7017,7 +7021,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -7017,7 +7021,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
void *sense = NULL; void *sense = NULL;
dma_addr_t sense_handle; dma_addr_t sense_handle;
unsigned long *sense_ptr; unsigned long *sense_ptr;
u32 opcode; u32 opcode = 0;
memset(kbuff_arr, 0, sizeof(kbuff_arr)); memset(kbuff_arr, 0, sizeof(kbuff_arr));
...@@ -7027,6 +7031,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -7027,6 +7031,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
return -EINVAL; return -EINVAL;
} }
if (ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) {
dev_err(&instance->pdev->dev,
"Received invalid ioctl command 0x%x\n",
ioc->frame.hdr.cmd);
return -ENOTSUPP;
}
cmd = megasas_get_cmd(instance); cmd = megasas_get_cmd(instance);
if (!cmd) { if (!cmd) {
dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n"); dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n");
...@@ -7045,6 +7056,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -7045,6 +7056,8 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE | cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE |
MFI_FRAME_SGL64 | MFI_FRAME_SGL64 |
MFI_FRAME_SENSE64)); MFI_FRAME_SENSE64));
if (cmd->frame->hdr.cmd == MFI_CMD_DCMD)
opcode = le32_to_cpu(cmd->frame->dcmd.opcode); opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
if (opcode == MR_DCMD_CTRL_SHUTDOWN) { if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
...@@ -7127,8 +7140,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance, ...@@ -7127,8 +7140,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) { if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) {
cmd->sync_cmd = 0; cmd->sync_cmd = 0;
dev_err(&instance->pdev->dev, dev_err(&instance->pdev->dev,
"return -EBUSY from %s %d opcode 0x%x cmd->cmd_status_drv 0x%x\n", "return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n",
__func__, __LINE__, opcode, cmd->cmd_status_drv); __func__, __LINE__, cmd->frame->hdr.cmd, opcode,
cmd->cmd_status_drv);
return -EBUSY; return -EBUSY;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment