Commit 91f7b74a authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Jens Axboe
Browse files

DAC960: split up ioctl function to reduce stack size



When CONFIG_KASAN is set, all the local variables in this function are
allocated on the stack together, leading to a warning about possible
kernel stack overflow:

drivers/block/DAC960.c: In function 'DAC960_gam_ioctl':
drivers/block/DAC960.c:7061:1: error: the frame size of 2240 bytes is larger than 2048 bytes [-Werror=frame-larger-than=]

By splitting up the function into smaller chunks, we can avoid that and
make the code slightly more readable at the same time. The coding style
in this file is completely nonstandard, and I chose to not touch that
at all, leaving the unconventional intendation unchanged to make it
easier to review the diff.

Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent cf8c0c6a
Loading
Loading
Loading
Loading
+90 −70
Original line number Original line Diff line number Diff line
@@ -6619,43 +6619,27 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller)


#ifdef DAC960_GAM_MINOR
#ifdef DAC960_GAM_MINOR


/*
static long DAC960_gam_get_controller_info(DAC960_ControllerInfo_T __user *UserSpaceControllerInfo)
 * DAC960_gam_ioctl is the ioctl function for performing RAID operations.
*/

static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
						unsigned long Argument)
{
  long ErrorCode = 0;
  if (!capable(CAP_SYS_ADMIN)) return -EACCES;

  mutex_lock(&DAC960_mutex);
  switch (Request)
    {
    case DAC960_IOCTL_GET_CONTROLLER_COUNT:
      ErrorCode = DAC960_ControllerCount;
      break;
    case DAC960_IOCTL_GET_CONTROLLER_INFO:
{
{
	DAC960_ControllerInfo_T __user *UserSpaceControllerInfo =
	  (DAC960_ControllerInfo_T __user *) Argument;
	DAC960_ControllerInfo_T ControllerInfo;
	DAC960_ControllerInfo_T ControllerInfo;
	DAC960_Controller_T *Controller;
	DAC960_Controller_T *Controller;
	int ControllerNumber;
	int ControllerNumber;
	long ErrorCode;

	if (UserSpaceControllerInfo == NULL)
	if (UserSpaceControllerInfo == NULL)
		ErrorCode = -EINVAL;
		ErrorCode = -EINVAL;
	else ErrorCode = get_user(ControllerNumber,
	else ErrorCode = get_user(ControllerNumber,
			     &UserSpaceControllerInfo->ControllerNumber);
			     &UserSpaceControllerInfo->ControllerNumber);
	if (ErrorCode != 0)
	if (ErrorCode != 0)
		break;
		goto out;
	ErrorCode = -ENXIO;
	ErrorCode = -ENXIO;
	if (ControllerNumber < 0 ||
	if (ControllerNumber < 0 ||
	    ControllerNumber > DAC960_ControllerCount - 1) {
	    ControllerNumber > DAC960_ControllerCount - 1) {
	  break;
		goto out;
	}
	}
	Controller = DAC960_Controllers[ControllerNumber];
	Controller = DAC960_Controllers[ControllerNumber];
	if (Controller == NULL)
	if (Controller == NULL)
		break;
		goto out;
	memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
	memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
	ControllerInfo.ControllerNumber = ControllerNumber;
	ControllerInfo.ControllerNumber = ControllerNumber;
	ControllerInfo.FirmwareType = Controller->FirmwareType;
	ControllerInfo.FirmwareType = Controller->FirmwareType;
@@ -6670,12 +6654,12 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
	strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
	strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
	ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
	ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
			     sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
			     sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0);
	break;
out:
	return ErrorCode;
}
}
    case DAC960_IOCTL_V1_EXECUTE_COMMAND:

static long DAC960_gam_v1_execute_command(DAC960_V1_UserCommand_T __user *UserSpaceUserCommand)
{
{
	DAC960_V1_UserCommand_T __user *UserSpaceUserCommand =
	  (DAC960_V1_UserCommand_T __user *) Argument;
	DAC960_V1_UserCommand_T UserCommand;
	DAC960_V1_UserCommand_T UserCommand;
	DAC960_Controller_T *Controller;
	DAC960_Controller_T *Controller;
	DAC960_Command_T *Command = NULL;
	DAC960_Command_T *Command = NULL;
@@ -6688,39 +6672,41 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
	int ControllerNumber, DataTransferLength;
	int ControllerNumber, DataTransferLength;
	unsigned char *DataTransferBuffer = NULL;
	unsigned char *DataTransferBuffer = NULL;
	dma_addr_t DataTransferBufferDMA;
	dma_addr_t DataTransferBufferDMA;
        long ErrorCode;

	if (UserSpaceUserCommand == NULL) {
	if (UserSpaceUserCommand == NULL) {
		ErrorCode = -EINVAL;
		ErrorCode = -EINVAL;
		break;
		goto out;
	}
	}
	if (copy_from_user(&UserCommand, UserSpaceUserCommand,
	if (copy_from_user(&UserCommand, UserSpaceUserCommand,
				   sizeof(DAC960_V1_UserCommand_T))) {
				   sizeof(DAC960_V1_UserCommand_T))) {
		ErrorCode = -EFAULT;
		ErrorCode = -EFAULT;
		break;
		goto out;
	}
	}
	ControllerNumber = UserCommand.ControllerNumber;
	ControllerNumber = UserCommand.ControllerNumber;
    	ErrorCode = -ENXIO;
    	ErrorCode = -ENXIO;
	if (ControllerNumber < 0 ||
	if (ControllerNumber < 0 ||
	    ControllerNumber > DAC960_ControllerCount - 1)
	    ControllerNumber > DAC960_ControllerCount - 1)
	    	break;
		goto out;
	Controller = DAC960_Controllers[ControllerNumber];
	Controller = DAC960_Controllers[ControllerNumber];
	if (Controller == NULL)
	if (Controller == NULL)
		break;
		goto out;
	ErrorCode = -EINVAL;
	ErrorCode = -EINVAL;
	if (Controller->FirmwareType != DAC960_V1_Controller)
	if (Controller->FirmwareType != DAC960_V1_Controller)
		break;
		goto out;
	CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
	CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
	DataTransferLength = UserCommand.DataTransferLength;
	DataTransferLength = UserCommand.DataTransferLength;
	if (CommandOpcode & 0x80)
	if (CommandOpcode & 0x80)
		break;
		goto out;
	if (CommandOpcode == DAC960_V1_DCDB)
	if (CommandOpcode == DAC960_V1_DCDB)
	  {
	  {
	    if (copy_from_user(&DCDB, UserCommand.DCDB,
	    if (copy_from_user(&DCDB, UserCommand.DCDB,
			       sizeof(DAC960_V1_DCDB_T))) {
			       sizeof(DAC960_V1_DCDB_T))) {
		ErrorCode = -EFAULT;
		ErrorCode = -EFAULT;
		break;
		goto out;
	    }
	    }
	    if (DCDB.Channel >= DAC960_V1_MaxChannels)
	    if (DCDB.Channel >= DAC960_V1_MaxChannels)
	    		break;
		goto out;
	    if (!((DataTransferLength == 0 &&
	    if (!((DataTransferLength == 0 &&
		   DCDB.Direction
		   DCDB.Direction
		   == DAC960_V1_DCDB_NoDataTransfer) ||
		   == DAC960_V1_DCDB_NoDataTransfer) ||
@@ -6730,15 +6716,15 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
		  (DataTransferLength < 0 &&
		  (DataTransferLength < 0 &&
		   DCDB.Direction
		   DCDB.Direction
		   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
		   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
		   	break;
			goto out;
	    if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
	    if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
		!= abs(DataTransferLength))
		!= abs(DataTransferLength))
			break;
			goto out;
	    DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice,
	    DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice,
			sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA);
			sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA);
	    if (DCDB_IOBUF == NULL) {
	    if (DCDB_IOBUF == NULL) {
	    		ErrorCode = -ENOMEM;
	    		ErrorCode = -ENOMEM;
			break;
			goto out;
		}
		}
	  }
	  }
	ErrorCode = -ENOMEM;
	ErrorCode = -ENOMEM;
@@ -6748,19 +6734,19 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
                                                       DataTransferLength,
                                                       DataTransferLength,
                                                       &DataTransferBufferDMA);
                                                       &DataTransferBufferDMA);
	    if (DataTransferBuffer == NULL)
	    if (DataTransferBuffer == NULL)
	    	break;
		goto out;
	  }
	  }
	else if (DataTransferLength < 0)
	else if (DataTransferLength < 0)
	  {
	  {
	    DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
	    DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
				-DataTransferLength, &DataTransferBufferDMA);
				-DataTransferLength, &DataTransferBufferDMA);
	    if (DataTransferBuffer == NULL)
	    if (DataTransferBuffer == NULL)
	    	break;
		goto out;
	    if (copy_from_user(DataTransferBuffer,
	    if (copy_from_user(DataTransferBuffer,
			       UserCommand.DataTransferBuffer,
			       UserCommand.DataTransferBuffer,
			       -DataTransferLength)) {
			       -DataTransferLength)) {
		ErrorCode = -EFAULT;
		ErrorCode = -EFAULT;
		break;
		goto out;
	    }
	    }
	  }
	  }
	if (CommandOpcode == DAC960_V1_DCDB)
	if (CommandOpcode == DAC960_V1_DCDB)
@@ -6837,12 +6823,12 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
	if (DCDB_IOBUF != NULL)
	if (DCDB_IOBUF != NULL)
	  pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T),
	  pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T),
			DCDB_IOBUF, DCDB_IOBUFDMA);
			DCDB_IOBUF, DCDB_IOBUFDMA);
      	break;
	out:
	return ErrorCode;
}
}
    case DAC960_IOCTL_V2_EXECUTE_COMMAND:

static long DAC960_gam_v2_execute_command(DAC960_V2_UserCommand_T __user *UserSpaceUserCommand)
{
{
	DAC960_V2_UserCommand_T __user *UserSpaceUserCommand =
	  (DAC960_V2_UserCommand_T __user *) Argument;
	DAC960_V2_UserCommand_T UserCommand;
	DAC960_V2_UserCommand_T UserCommand;
	DAC960_Controller_T *Controller;
	DAC960_Controller_T *Controller;
	DAC960_Command_T *Command = NULL;
	DAC960_Command_T *Command = NULL;
@@ -6855,26 +6841,26 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
	dma_addr_t DataTransferBufferDMA;
	dma_addr_t DataTransferBufferDMA;
	unsigned char *RequestSenseBuffer = NULL;
	unsigned char *RequestSenseBuffer = NULL;
	dma_addr_t RequestSenseBufferDMA;
	dma_addr_t RequestSenseBufferDMA;
	long ErrorCode = -EINVAL;


	ErrorCode = -EINVAL;
	if (UserSpaceUserCommand == NULL)
	if (UserSpaceUserCommand == NULL)
		break;
		goto out;
	if (copy_from_user(&UserCommand, UserSpaceUserCommand,
	if (copy_from_user(&UserCommand, UserSpaceUserCommand,
			   sizeof(DAC960_V2_UserCommand_T))) {
			   sizeof(DAC960_V2_UserCommand_T))) {
		ErrorCode = -EFAULT;
		ErrorCode = -EFAULT;
		break;
		goto out;
	}
	}
	ErrorCode = -ENXIO;
	ErrorCode = -ENXIO;
	ControllerNumber = UserCommand.ControllerNumber;
	ControllerNumber = UserCommand.ControllerNumber;
	if (ControllerNumber < 0 ||
	if (ControllerNumber < 0 ||
	    ControllerNumber > DAC960_ControllerCount - 1)
	    ControllerNumber > DAC960_ControllerCount - 1)
	    	break;
		goto out;
	Controller = DAC960_Controllers[ControllerNumber];
	Controller = DAC960_Controllers[ControllerNumber];
	if (Controller == NULL)
	if (Controller == NULL)
		break;
		goto out;
	if (Controller->FirmwareType != DAC960_V2_Controller){
	if (Controller->FirmwareType != DAC960_V2_Controller){
		ErrorCode = -EINVAL;
		ErrorCode = -EINVAL;
		break;
		goto out;
	}
	}
	DataTransferLength = UserCommand.DataTransferLength;
	DataTransferLength = UserCommand.DataTransferLength;
    	ErrorCode = -ENOMEM;
    	ErrorCode = -ENOMEM;
@@ -6884,14 +6870,14 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
                                                       DataTransferLength,
                                                       DataTransferLength,
                                                       &DataTransferBufferDMA);
                                                       &DataTransferBufferDMA);
	    if (DataTransferBuffer == NULL)
	    if (DataTransferBuffer == NULL)
	    	break;
		goto out;
	  }
	  }
	else if (DataTransferLength < 0)
	else if (DataTransferLength < 0)
	  {
	  {
	    DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
	    DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice,
				-DataTransferLength, &DataTransferBufferDMA);
				-DataTransferLength, &DataTransferBufferDMA);
	    if (DataTransferBuffer == NULL)
	    if (DataTransferBuffer == NULL)
	    	break;
		goto out;
	    if (copy_from_user(DataTransferBuffer,
	    if (copy_from_user(DataTransferBuffer,
			       UserCommand.DataTransferBuffer,
			       UserCommand.DataTransferBuffer,
			       -DataTransferLength)) {
			       -DataTransferLength)) {
@@ -7001,42 +6987,44 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
	if (RequestSenseBuffer != NULL)
	if (RequestSenseBuffer != NULL)
	  pci_free_consistent(Controller->PCIDevice, RequestSenseLength,
	  pci_free_consistent(Controller->PCIDevice, RequestSenseLength,
		RequestSenseBuffer, RequestSenseBufferDMA);
		RequestSenseBuffer, RequestSenseBufferDMA);
        break;
out:
        return ErrorCode;
}
}
    case DAC960_IOCTL_V2_GET_HEALTH_STATUS:

static long DAC960_gam_v2_get_health_status(DAC960_V2_GetHealthStatus_T __user *UserSpaceGetHealthStatus)
{
{
	DAC960_V2_GetHealthStatus_T __user *UserSpaceGetHealthStatus =
	  (DAC960_V2_GetHealthStatus_T __user *) Argument;
	DAC960_V2_GetHealthStatus_T GetHealthStatus;
	DAC960_V2_GetHealthStatus_T GetHealthStatus;
	DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
	DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
	DAC960_Controller_T *Controller;
	DAC960_Controller_T *Controller;
	int ControllerNumber;
	int ControllerNumber;
	long ErrorCode;

	if (UserSpaceGetHealthStatus == NULL) {
	if (UserSpaceGetHealthStatus == NULL) {
		ErrorCode = -EINVAL;
		ErrorCode = -EINVAL;
		break;
		goto out;
	}
	}
	if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
	if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
			   sizeof(DAC960_V2_GetHealthStatus_T))) {
			   sizeof(DAC960_V2_GetHealthStatus_T))) {
		ErrorCode = -EFAULT;
		ErrorCode = -EFAULT;
		break;
		goto out;
	}
	}
	ErrorCode = -ENXIO;
	ErrorCode = -ENXIO;
	ControllerNumber = GetHealthStatus.ControllerNumber;
	ControllerNumber = GetHealthStatus.ControllerNumber;
	if (ControllerNumber < 0 ||
	if (ControllerNumber < 0 ||
	    ControllerNumber > DAC960_ControllerCount - 1)
	    ControllerNumber > DAC960_ControllerCount - 1)
		    break;
		goto out;
	Controller = DAC960_Controllers[ControllerNumber];
	Controller = DAC960_Controllers[ControllerNumber];
	if (Controller == NULL)
	if (Controller == NULL)
		break;
		goto out;
	if (Controller->FirmwareType != DAC960_V2_Controller) {
	if (Controller->FirmwareType != DAC960_V2_Controller) {
		ErrorCode = -EINVAL;
		ErrorCode = -EINVAL;
		break;
		goto out;
	}
	}
	if (copy_from_user(&HealthStatusBuffer,
	if (copy_from_user(&HealthStatusBuffer,
			   GetHealthStatus.HealthStatusBuffer,
			   GetHealthStatus.HealthStatusBuffer,
			   sizeof(DAC960_V2_HealthStatusBuffer_T))) {
			   sizeof(DAC960_V2_HealthStatusBuffer_T))) {
		ErrorCode = -EFAULT;
		ErrorCode = -EFAULT;
		break;
		goto out;
	}
	}
	ErrorCode = wait_event_interruptible_timeout(Controller->HealthStatusWaitQueue,
	ErrorCode = wait_event_interruptible_timeout(Controller->HealthStatusWaitQueue,
			!(Controller->V2.HealthStatusBuffer->StatusChangeCounter
			!(Controller->V2.HealthStatusBuffer->StatusChangeCounter
@@ -7046,7 +7034,7 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
			DAC960_MonitoringTimerInterval);
			DAC960_MonitoringTimerInterval);
	if (ErrorCode == -ERESTARTSYS) {
	if (ErrorCode == -ERESTARTSYS) {
		ErrorCode = -EINTR;
		ErrorCode = -EINTR;
		break;
		goto out;
	}
	}
	if (copy_to_user(GetHealthStatus.HealthStatusBuffer,
	if (copy_to_user(GetHealthStatus.HealthStatusBuffer,
			 Controller->V2.HealthStatusBuffer,
			 Controller->V2.HealthStatusBuffer,
@@ -7054,7 +7042,39 @@ static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
		ErrorCode = -EFAULT;
		ErrorCode = -EFAULT;
	else
	else
		ErrorCode =  0;
		ErrorCode =  0;

out:
	return ErrorCode;
}
}

/*
 * DAC960_gam_ioctl is the ioctl function for performing RAID operations.
*/

static long DAC960_gam_ioctl(struct file *file, unsigned int Request,
						unsigned long Argument)
{
  long ErrorCode = 0;
  void __user *argp = (void __user *)Argument;
  if (!capable(CAP_SYS_ADMIN)) return -EACCES;

  mutex_lock(&DAC960_mutex);
  switch (Request)
    {
    case DAC960_IOCTL_GET_CONTROLLER_COUNT:
      ErrorCode = DAC960_ControllerCount;
      break;
    case DAC960_IOCTL_GET_CONTROLLER_INFO:
      ErrorCode = DAC960_gam_get_controller_info(argp);
      break;
    case DAC960_IOCTL_V1_EXECUTE_COMMAND:
      ErrorCode = DAC960_gam_v1_execute_command(argp);
      break;
    case DAC960_IOCTL_V2_EXECUTE_COMMAND:
      ErrorCode = DAC960_gam_v2_execute_command(argp);
      break;
    case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
      ErrorCode = DAC960_gam_v2_get_health_status(argp);
      break;
      break;
      default:
      default:
	ErrorCode = -ENOTTY;
	ErrorCode = -ENOTTY;