Hi, That's a bit of a long story, and I'm not sure whether I remember all the details, but I'll give it a try.
First of all, not all sparcs have 32 bit userland and 64 bit kernel. The 32 bit sparc chips have 32 bit userland and 32 bit kernel, and it's also possible to run a 32 bit kernel on a 64 bit sparc (ultrasparc). Furthermore, someone recently succeeded in booting a 64 bit userland. So.. different word size in kernel/userspace gives rise to a lot of interesting problems, with the biggest problem being passing structs between userspace and kernelspace. arch/sparc64/kernel/ioctl32.c is probably the biggest pile of doggy doo you'll ever see in your life. What it basically does is translate structs with 32bit long/pointer members to structs with 64bit long/pointer members and vice versa. It has to know about pretty much every single ioctl and every single struct in the entire kernel. (Admittedly, on MIPS the ioctl conversion story is much worse -- there you can additionally have different endianity in kernel and user space, as I've been told.) brctl creates and destroys bridge interfaces by issuing SIOCGIFBR ioctls against a packet socket. The argument to this ioctl is a userspace pointer to an array of longs. ioctl32.c has SIOCGIFBR marked as a 'compatible' ioctl, which means it will do no translation on it. So far, so good. Two problemlets remain: - the kernel's idea of 'long' (64 bit) is different than userspace's idea of 'long' (32 bit), but I worked around that by adding a hack to brctl that detects a 64 bit kernel on sparc, and uses userspace 'long long' (64 bit) in that case. (note that this is not the right way to do it!) - casting a pointer to a long long by doing (unsigned long long)p will sign-extend the pointer, converting 0xbffff340 to 0xffffffffbffff340, which is not what you want. Mask off the high 32 bits or do the cast differently. With these ugly hacks, you can do addbr and delbr. However, the other ioctls still don't work. Some investigation shows that the ioctl that brctl uses, SIOCDEVPRIVATE, aliases to SIOCGPPPSTATS, and that ioctl32.c has an ioctl translator for SIOCGPPPSTATS. So, the PPP translator code unhelpfully messes up all SIOCDEVPRIVATE ioctls ever issued. This I hacked around by using SIOCDEVPRIVATE+3 instead of SIOCDEVPRIVATE. So now things should work. Well, almost. One problem is that ioctl32.c calls ioctls with set_fs(KERNEL_DS). This means that all copy_from_user will access kernel addresses, not userspace addresses, which will cause all copy_from_user calls to silently hang the box (oh, the joys of remote kernel debugging..). I hacked around this by explicitly setting fs back to USER_DS (see http://bridge.sf.net/patches/2.4_fix_sparc64_bridging.diff. The middle hunk fixes a refcount leak that's present in the stock sparc64 kernel code, which took me another four hours to figure out.) hope this helps, Lennert On Mon, Jan 28, 2002 at 08:45:22PM +0100, Bart De Schuymer wrote: > Hello Lennert, > > I'm interested in knowing how you solved that sparc problem for the bridge > userspace program. > I assume with some compiler options? Could you enlighten me please? > Ebtables has similar problems on the sparc... > > cheers, > Bart > _______________________________________________ Bridge mailing list [EMAIL PROTECTED] http://www.math.leidenuniv.nl/mailman/listinfo/bridge
