Skip to contentSkip to conversation

implement generic rtc compat ioctl handling

PATCH In review Christoph Hellwig 2 participants 3 messages Nov 11, 2005 – Nov 20, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 implement generic rtc compat ioctl handling

This patch implements generic handling of RTC_IRQP_READ32, RTC_IRQP_SET32, RTC_EPOCH_READ32 and RTC_EPOCH_SET32 in fs/compat_ioctl.c. It's based on the x86_64 code which needed a little massaging to be endian-clean and use compat_alloc_user_space aswell as the compat_ types.

parisc used COMPAT_IOCTL or generic w_long handlers for these which is wrong and can't work because the ioctls encode sizeof(unsigned long) in their ioctl number. parisc also duplicated COMPAT_IOCTL entries for other rtc ioctls which I remove in this patch, too.

arch/parisc/kernel/ioctl32.c +0 -19
Index: linux-2.6/arch/parisc/kernel/ioctl32.c
===================================================================
@@ -571,25 +571,6 @@
 HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
 HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
 
-#if defined(CONFIG_GEN_RTC)
-COMPATIBLE_IOCTL(RTC_AIE_ON)
-COMPATIBLE_IOCTL(RTC_AIE_OFF)
-COMPATIBLE_IOCTL(RTC_UIE_ON)
-COMPATIBLE_IOCTL(RTC_UIE_OFF)
-COMPATIBLE_IOCTL(RTC_PIE_ON)
-COMPATIBLE_IOCTL(RTC_PIE_OFF)
-COMPATIBLE_IOCTL(RTC_WIE_ON)
-COMPATIBLE_IOCTL(RTC_WIE_OFF)
-COMPATIBLE_IOCTL(RTC_ALM_SET)   /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_ALM_READ)  /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_RD_TIME)   /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_SET_TIME)  /* struct rtc_time only has ints */
-HANDLE_IOCTL(RTC_IRQP_READ, w_long)
-COMPATIBLE_IOCTL(RTC_IRQP_SET)
-HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
-COMPATIBLE_IOCTL(RTC_EPOCH_SET)
-#endif
-
 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
 HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
 HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
arch/x86_64/ia32/ia32_ioctl.c +0 -47

59 lines not on this page · raw message

fs/compat_ioctl.c +44 -0

56 lines not on this page · raw message

#1 lore raw

fs/compat_ioctl.c line 2574

Quoted 7 lines · Christoph Hellwig
fs/compat_ioctl.c +6 -0
+static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
+{
+       compat_ulong_t __user *val = compat_alloc_user_space(sizeof(*val));
+       compat_ulong_t __user *uval = (compat_ulong_t __user *)arg;
+       int ret;
+

This one should really be

compat_ulong_t __user *uval = compat_ptr(arg);

It's not really a problem since the only architecture where compat_ptr() makes a difference (64 bit s390) doesn't have an RTC driver, but it should be changed nevertheless.

Also, I suppose the declaration of val is wrong, since the ioctl methods expect a pointer to an unsigned long, not a compat_ulong_t. If you change that, the copy_in_user() won't work either.

	Arnd <><
#2 lore raw
Quoted 12 lines · Arnd Bergmann

Review

Quoted 7 lines · Christoph Hellwig
(quoted diff) +6 -0
+static int rtc_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
+{
+???????compat_ulong_t __user *val = compat_alloc_user_space(sizeof(*val));
+???????compat_ulong_t __user *uval = (compat_ulong_t __user *)arg;
+???????int ret;
+

This one should really be

compat_ulong_t __user *uval = compat_ptr(arg);

Quoted 7 lines

It's not really a problem since the only architecture where compat_ptr() makes a difference (64 bit s390) doesn't have an RTC driver, but it should be changed nevertheless.

Also, I suppose the declaration of val is wrong, since the ioctl methods expect a pointer to an unsigned long, not a compat_ulong_t. If you change that, the copy_in_user() won't work either.

Yeah. This stuff was hurting my brain so I decided to go for the traditional get_fs() based version instead:

arch/parisc/kernel/ioctl32.c +0 -19
Index: linux-2.6/arch/parisc/kernel/ioctl32.c
===================================================================
@@ -571,25 +571,6 @@
 HANDLE_IOCTL(SIOCGPPPCSTATS, dev_ifsioc)
 HANDLE_IOCTL(SIOCGPPPVER, dev_ifsioc)
 
-#if defined(CONFIG_GEN_RTC)
-COMPATIBLE_IOCTL(RTC_AIE_ON)
-COMPATIBLE_IOCTL(RTC_AIE_OFF)
-COMPATIBLE_IOCTL(RTC_UIE_ON)
-COMPATIBLE_IOCTL(RTC_UIE_OFF)
-COMPATIBLE_IOCTL(RTC_PIE_ON)
-COMPATIBLE_IOCTL(RTC_PIE_OFF)
-COMPATIBLE_IOCTL(RTC_WIE_ON)
-COMPATIBLE_IOCTL(RTC_WIE_OFF)
-COMPATIBLE_IOCTL(RTC_ALM_SET)   /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_ALM_READ)  /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_RD_TIME)   /* struct rtc_time only has ints */
-COMPATIBLE_IOCTL(RTC_SET_TIME)  /* struct rtc_time only has ints */
-HANDLE_IOCTL(RTC_IRQP_READ, w_long)
-COMPATIBLE_IOCTL(RTC_IRQP_SET)
-HANDLE_IOCTL(RTC_EPOCH_READ, w_long)
-COMPATIBLE_IOCTL(RTC_EPOCH_SET)
-#endif
-
 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
 HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
 HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
arch/x86_64/ia32/ia32_ioctl.c +0 -47

59 lines not on this page · raw message

fs/compat_ioctl.c +47 -0

59 lines not on this page · raw message