[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