[LinuxPPS] linuxpps-v5.3.2 is missing ioctl32 compatibility

George Spelvin linux at horizon.com
Sun Oct 26 22:56:19 CET 2008


I thought I might mention that linuxpps is missing support for running
32-bit clients on a 64-bit kernel.  Since all the structures are
fixed-size, this whould be pretty simple:

diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index 5235c67..0c32809 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -59,6 +59,7 @@
 #include <linux/i2c-dev.h>
 #include <linux/atalk.h>
 #include <linux/loop.h>
+#include <linux/pps.h>
 
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci.h>
@@ -2019,6 +2020,12 @@ COMPATIBLE_IOCTL(RTC_WKALM_RD)
  */
 COMPATIBLE_IOCTL(_IOR('p', 20, int[7])) /* RTCGET */
 COMPATIBLE_IOCTL(_IOW('p', 21, int[7])) /* RTCSET */
+/* LinuxPPS entries, also little p */
+COMPATIBLE_IOCTL(PPS_CHECK)
+COMPATIBLE_IOCTL(PPS_GETPARAMS)
+COMPATIBLE_IOCTL(PPS_SETPARAMS)
+COMPATIBLE_IOCTL(PPS_GETCAP)
+COMPATIBLE_IOCTL(PPS_FETCH)
 /* Little m */
 COMPATIBLE_IOCTL(MTIOCTOP)
 /* Socket level stuff */

Unfortunately, with that patch, ntp is currently reporting 
"refclock_atom: time_pps_getcap failed: Invalid argument"
with a kernel message of
ioctl32(ntpd:3440): Unknown cmd fd(5) cmd(800470a3){t:'p';sz:4} arg(ff987e78) on /dev/pps0

Oh!  That's because it's currently (erroneously)
#define PPS_GETCAP              _IOR('p', 0xa3, int *)

The third argument to the _IOx constructors is the type *pointed to* by
the third argument to ioctl(), so that's saying that I pass an "int **"
there.  And that means that PPS_GETCAP is 800870a3 (bits 30:16 give size,
which is 8 on a 64-bit machine) to the kernel, but 800470a3 to the 32-bit
application, so obviously it doesn't work.

I also need to correct the ioctl number definitions:

diff --git a/include/linux/pps.h b/include/linux/pps.h
index 9a74d06..d2d2514 100644
--- a/include/linux/pps.h
+++ b/include/linux/pps.h
@@ -124,10 +124,10 @@ struct pps_fdata {
 #include <linux/ioctl.h>
 
 #define PPS_CHECK		_IO('p', 0xa0)
-#define PPS_GETPARAMS		_IOR('p', 0xa1, struct pps_kparams *)
-#define PPS_SETPARAMS		_IOW('p', 0xa2, struct pps_kparams *)
-#define PPS_GETCAP		_IOR('p', 0xa3, int *)
-#define PPS_FETCH		_IOWR('p', 0xa4, struct pps_fdata *)
+#define PPS_GETPARAMS		_IOR('p', 0xa1, struct pps_kparams)
+#define PPS_SETPARAMS		_IOW('p', 0xa2, struct pps_kparams)
+#define PPS_GETCAP		_IOR('p', 0xa3, int)
+#define PPS_FETCH		_IOWR('p', 0xa4, struct pps_fdata)
 
 #ifdef __KERNEL__
 
That could explain some other problems, too, as I think the ioctl system by default
uses that size to validate data transfers...

Anyway, I have to send this before rebooting to test the second patch.



More information about the LinuxPPS mailing list