I don't suppose there are any guidelines from ARM about compatibility between 32bit userspace and 64bit kernel on some hypothetical future version of the ARM architecture? Some hints about what to do or not do could perhaps save some ioctl compat glue later on down the line..
BR, -R
---------- Forwarded message ---------- From: Rob Clark rob.clark@linaro.org Date: Sun, Sep 18, 2011 at 3:15 PM Subject: Re: [PATCH] RFCv2: omapdrm DRM/KMS driver for TI OMAP platforms To: Thomas Hellstrom thomas@shipmail.org Cc: Inki Dae inki.dae@samsung.com, dri-devel@lists.freedesktop.org, patches@linaro.org
On Sun, Sep 18, 2011 at 3:00 PM, Thomas Hellstrom thomas@shipmail.org wrote:
On 09/18/2011 09:50 PM, Rob Clark wrote:
On Sun, Sep 18, 2011 at 2:36 PM, Thomas Hellstromthomas@shipmail.org wrote:
On 09/17/2011 11:32 PM, Rob Clark wrote:
From: Rob Clarkrob@ti.com
[snip]
diff --git a/include/drm/omap_drm.h b/include/drm/omap_drm.h new file mode 100644 index 0000000..ea0ae8e --- /dev/null +++ b/include/drm/omap_drm.h @@ -0,0 +1,111 @@ +/*
- linux/include/drm/omap_drm.h
- Copyright (C) 2011 Texas Instruments
- Author: Rob Clarkrob@ti.com
- This program is free software; you can redistribute it and/or modify
it
- under the terms of the GNU General Public License version 2 as
published by
- the Free Software Foundation.
- This program is distributed in the hope that it will be useful, but
WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for
- more details.
- You should have received a copy of the GNU General Public License
along with
- this program. If not, seehttp://www.gnu.org/licenses/.
- */
+#ifndef __OMAP_DRM_H__ +#define __OMAP_DRM_H__
+#include "drm.h"
+/* Please note that modifications to all structs defined here are
- subject to backwards-compatibility constraints.
- */
+#define OMAP_PARAM_CHIPSET_ID 1 /* ie. 0x3430, 0x4430, etc */
+struct drm_omap_param {
- uint64_t param; /* in */
- uint64_t value; /* in (set_param), out
(get_param) */ +};
+struct drm_omap_get_base {
- char plugin_name[64]; /* in */
- uint32_t ioctl_base; /* out */
+};
What about future ARM 64-bit vs 32-bit structure sizes? On x86 we always take care to make structures appearing in the drm user-space interfaces having sizes that are a multiple of 64-bits, to avoid having to maintain compat code for 32-bit apps running on 64 bit kernels. For the same reasons, structure members with 64 bit alignment requirements on 64-bit systems need to be carefully places.
I don't know whether there is or will be a 64-bit ARM, but it might be worth taking into consideration.
There isn't currently any 64-bit ARM, but it is a safe assumption that there will be some day.. I guess we'll have enough fun w/ various random 32b devices when LPAE arrives w/ the cortex-a15..
I did try to make sure any uint64_t's were aligned to a 64bit offset, but beyond that I confess to not being an expert on how 64 vs 32b ioctl compat stuff is handled or what the issues going from 32->64b are. If there are some additional considerations that should be taken care of, then now is the time. So far I don't have any pointer fields in any of the ioctl structs. Beyond that, I'm not entirely sure what else needs to be done, but would appreciate any pointers to docs about how the compat stuff works.
BR, -R
I've actually avoided writing compat ioctl code myself, by trying to make sure that structures look identical in the 64-bit and 32-bit x86 ABIs, but the compat code is there to translate pointers and to overcome alignment incompatibilities.
A good way to at least try to avoid having to maintain compat code once the 64-bit ABI shows up is to make sure that 64-bit scalars and embedded structures are placed on 64-bit boundaries, padding if necessary, and to make sure (using padding) that struct sizes are always multiples of 64 bits.
So far this is true for 64bit scalars.. I'm using stdint types everywhere so there is no chance for fields having different sizes on 64b vs 32b. And the only structs contained within ioctl structs so far are starting at offset==0.
Is it necessary to ensure that the ioctl structs themselves (as opposed to structs within those structs) have sizes that are multiple of 64b? The ioctl structs are copied (copy_from_user()/copy_to_user()), which I would have assumed would be sufficient?
But since there is no 64-bit ARM yet, it might be better to rely on using compat code in the future than on making guesses about alignment restrictions of the ABI...
hmm, it might be nice to get some guidelines from ARM on this, since I really have no idea what a 64b ARM architecture would look like..
BR, -R
/Thomas
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Sunday 18 September 2011 15:24:37 Rob Clark wrote:
I don't suppose there are any guidelines from ARM about compatibility between 32bit userspace and 64bit kernel on some hypothetical future version of the ARM architecture? Some hints about what to do or not do could perhaps save some ioctl compat glue later on down the line..
There are some rules that should be followed regardless:
* ioctl commands should never be written in an architecture specific way. In the example of the OMAP driver, you definitely want to be able ot use the same command when running Linux on the C6x DSP.
* If possible, use only scalar values as ioctl arguments
* Avoid types that are register sized: 'long', 'size_t', pointer. Instead use only __u8, __u16, __u32 and __u64 and their signed versions.
* If you use structures, try very hard to avoid pointers in them, it messes up all sorts of tools.
* If you use structures, make all members naturally aligned, and pad the size of the structures to a multiple of the maximum member size.
* Never put sub-command numbers into a structure.
But since there is no 64-bit ARM yet, it might be better to rely on using compat code in the future than on making guesses about alignment restrictions of the ABI...
hmm, it might be nice to get some guidelines from ARM on this, since I really have no idea what a 64b ARM architecture would look like...
Assuming that we can prevent any funny stuff from going into such an ABI, we only need to worry about the warts of the current ABI for ARM specific considerations. The one thing that I've noticed before is that structs on ARM (at least on one of the ABIs, forgot which) are padded to 32 bits, even if all members inside are smaller.
It would be a huge pain if a 64 bit ABI had /different/ padding rules here, like not padding (logical choice by itself, but hurts is here), or padding everything to 64 bits (maybe not worth porting the kernel to then).
Arnd
On Mon, Sep 19, 2011 at 2:15 AM, Arnd Bergmann arnd@arndb.de wrote:
On Sunday 18 September 2011 15:24:37 Rob Clark wrote:
I don't suppose there are any guidelines from ARM about compatibility between 32bit userspace and 64bit kernel on some hypothetical future version of the ARM architecture? Some hints about what to do or not do could perhaps save some ioctl compat glue later on down the line..
There are some rules that should be followed regardless:
- ioctl commands should never be written in an architecture specific
way. In the example of the OMAP driver, you definitely want to be able ot use the same command when running Linux on the C6x DSP.
If possible, use only scalar values as ioctl arguments
Avoid types that are register sized: 'long', 'size_t', pointer.
Instead use only __u8, __u16, __u32 and __u64 and their signed versions.
ok.. I'm using stdint types (ie. uint8_t, etc..) so same result
- If you use structures, try very hard to avoid pointers in them,
it messes up all sorts of tools.
- If you use structures, make all members naturally aligned, and pad
the size of the structures to a multiple of the maximum member size.
- Never put sub-command numbers into a structure.
I didn't get this comment.. what is special about sub-command #'s?
BR, -R
But since there is no 64-bit ARM yet, it might be better to rely on using compat code in the future than on making guesses about alignment restrictions of the ABI...
hmm, it might be nice to get some guidelines from ARM on this, since I really have no idea what a 64b ARM architecture would look like...
Assuming that we can prevent any funny stuff from going into such an ABI, we only need to worry about the warts of the current ABI for ARM specific considerations. The one thing that I've noticed before is that structs on ARM (at least on one of the ABIs, forgot which) are padded to 32 bits, even if all members inside are smaller.
It would be a huge pain if a 64 bit ABI had /different/ padding rules here, like not padding (logical choice by itself, but hurts is here), or padding everything to 64 bits (maybe not worth porting the kernel to then).
Arnd
On Monday 19 September 2011, Rob Clark wrote:
- If you use structures, try very hard to avoid pointers in them,
it messes up all sorts of tools.
- If you use structures, make all members naturally aligned, and pad
the size of the structures to a multiple of the maximum member size.
- Never put sub-command numbers into a structure.
I didn't get this comment.. what is special about sub-command #'s?
It's mostly general interface cleanliness. We have the ioctl command multiplexer nested inside the syscall command multiplexer, which is both the reason its convenience and for most of the problems associated with ioctl.
Nesting another multiplexor inside a single ioctl command gives you more ugliness and more problems without any added convenience (ioctl numbers are cheap). Specifically for 32 bit compat ioctls, you don't want to have to handle sub-commands in different ways but instead have some commands go directly to the native function while only the ones whose author screwed up go through a compat conversion.
Arnd
Arnd,
On Mon, Sep 19, 2011 at 08:15:45AM +0100, Arnd Bergmann wrote:
Assuming that we can prevent any funny stuff from going into such an ABI, we only need to worry about the warts of the current ABI for ARM specific considerations. The one thing that I've noticed before is that structs on ARM (at least on one of the ABIs, forgot which) are padded to 32 bits, even if all members inside are smaller.
This is only the case for the old ABI. EABI lays out structures so that they are aligned to their most aligned member and padded to be the smallest possible multiple of that alignment which can contain all of their aligned members.
It's described more formally in the PCS document:
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
Will
On Mon, Sep 19, 2011 at 10:39 AM, Will Deacon will.deacon@arm.com wrote:
Arnd,
On Mon, Sep 19, 2011 at 08:15:45AM +0100, Arnd Bergmann wrote:
Assuming that we can prevent any funny stuff from going into such an ABI, we only need to worry about the warts of the current ABI for ARM specific considerations. The one thing that I've noticed before is that structs on ARM (at least on one of the ABIs, forgot which) are padded to 32 bits, even if all members inside are smaller.
This is only the case for the old ABI. EABI lays out structures so that they are aligned to their most aligned member and padded to be the smallest possible multiple of that alignment which can contain all of their aligned members.
Hmm, so then since you can build the kernel w/ OABI compatibility, it seems like structs should always have padding fields to force them to be a multiple of 32bits...
BR, -R
It's described more formally in the PCS document:
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
Will
linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev
On Mon, 19 Sep 2011, Rob Clark wrote:
On Mon, Sep 19, 2011 at 10:39 AM, Will Deacon will.deacon@arm.com wrote:
Arnd,
On Mon, Sep 19, 2011 at 08:15:45AM +0100, Arnd Bergmann wrote:
Assuming that we can prevent any funny stuff from going into such an ABI, we only need to worry about the warts of the current ABI for ARM specific considerations. The one thing that I've noticed before is that structs on ARM (at least on one of the ABIs, forgot which) are padded to 32 bits, even if all members inside are smaller.
This is only the case for the old ABI. EABI lays out structures so that they are aligned to their most aligned member and padded to be the smallest possible multiple of that alignment which can contain all of their aligned members.
Hmm, so then since you can build the kernel w/ OABI compatibility, it seems like structs should always have padding fields to force them to be a multiple of 32bits...
Depends what you want to achieve. The OABI compat is there only to allow _most_ old binaries to execute on a modern system. When I wrote that code, I left out ioctl ABI compatibility issues because there are simply too many of them, and in practice the most often used ones just work already. A notable exception is ALSA.
So at this point I think there is no point caring too much about the OABI.
Nicolas
On Monday 19 September 2011 10:43:00 Rob Clark wrote:
On Mon, Sep 19, 2011 at 10:39 AM, Will Deacon will.deacon@arm.com wrote:
Arnd,
On Mon, Sep 19, 2011 at 08:15:45AM +0100, Arnd Bergmann wrote:
Assuming that we can prevent any funny stuff from going into such an ABI, we only need to worry about the warts of the current ABI for ARM specific considerations. The one thing that I've noticed before is that structs on ARM (at least on one of the ABIs, forgot which) are padded to 32 bits, even if all members inside are smaller.
This is only the case for the old ABI. EABI lays out structures so that they are aligned to their most aligned member and padded to be the smallest possible multiple of that alignment which can contain all of their aligned members.
Hmm, so then since you can build the kernel w/ OABI compatibility, it seems like structs should always have padding fields to force them to be a multiple of 32bits...
It depends on whether you want those structures to be compatible with any other structure. To give a different example, qemu-user supports converting ioctl data structures to the host data structure for any commands it knows. When you want to run an arm-oabi binary for instance on an x86-32 host, you need to conver the data structures that have this layout, but not when running the same program built for arm-eabi.
In either case however, you will have to convert the data structures that contain pointers running qemu-user on x86-64.
Arnd
On Monday 19 September 2011 19:36:27 Arnd Bergmann wrote:
Hmm, so then since you can build the kernel w/ OABI compatibility, it seems like structs should always have padding fields to force them to be a multiple of 32bits...
It depends on whether you want those structures to be compatible with any other structure. To give a different example, qemu-user supports converting ioctl data structures to the host data structure for any commands it knows. When you want to run an arm-oabi binary for instance on an x86-32 host, you need to conver the data structures that have this layout, but not when running the same program built for arm-eabi.
In either case however, you will have to convert the data structures that contain pointers running qemu-user on x86-64.
Sorry, I misunderstood your question. Yes, as Nicolas explained, the oabi-compat code in an arm-eabi kernel is broken indeed but works most of the time in practice.
Arnd