Transparent ioctls

The third argument of the transparent ioctl is a pointer to the data in user space to be copied in or out.

This address is remapped properly by the ioctl system call. The streams driver or module passes M_COPYIN or M_COPYOUT messages to the stream head and the stream head calls the copyin or copyout subroutines.

If the third argument of the ioctl subroutine points to a structure that contains a pointer (for example, ptr64) or long, remapping is solved by a new structure, copyreq64, which contains a 64-bit user space pointer. If the message block flag is set to MSG64BIT, the driver or module will pass M_COPYIN64 or M_COPYOUT64 to copy in or out a pointer within a structure. In this case, the stream head will call copyin64 or copyout64 to move the data into or out of the user address space, respectively.

The copyreq64 structure uses the last unused cq_filler field to store the 64-bit address. The copyreq64 structure looks like the following example:

struct copyreq64 {
              int     cq_cmd;         /* command type == ioc_cmd */
              cred_t *cq_cr;          /* pointer to full credentials*/
              int     cq_id;          /* ioctl id == ioc_id */
              ioc_pad cq_ad;          /* addr to copy data to/from */
              uint    cq_size;        /* number of bytes to copy */
              int     cq_flag;        /* reserved */
              mblk_t *cq_private;     /* module's private state info*/
              ptr64   cq_addr64;      /* 64-bit address */
              long    cq_filler[2];   /* reserved */
              };

The cq_addr64 field is added in the above structure and the size of the cq_filler is reduced, so overall size remains same. The driver or module first determines whether the MSG64BIT flag is set and, if so, stores the user-space 64-bit address in the cq_addr64 field.