古いPowerPCに接続されたカスタムハードウェア用のキャラクターデバイスドライバーのIOCTLを作成しているときに、奇妙な問題を見つけました。これが私のコードの抽象化です:
u32 mydev_data;
...
static long mydev_ioctl(struct file * file, unsigned int cmd, unsigned long arg)
{
void __user *user_arg = (void __user *)arg;
long result;
switch(cmd) {
case MYDEV_GETDATA:
result = put_user(mydev_data, user_arg);
break;
...
}
return result;
}
さて、これはゴミを返します。ただし、回線を入れ替えると
result = put_user(mydev_data, user_arg);
と
result = put_user(mydev_data, (unsigned long __user *) user_arg);
問題はなくなります。
ここで何が起こっているのですか?user_argは__user*としてマークされているため、唯一の違いはvoidとunsignedlongです。しかし、ここではポインタの種類は重要ではないと思います。明らかに私は間違っていますが、誰かが理由を説明できますか?