Re: [PATCH] x86/ioperm: Use atomic64_inc_return() in ksys_ioperm()

From: H. Peter Anvin
Date: Sat Oct 26 2024 - 19:38:57 EST


On 10/26/24 16:28, H. Peter Anvin wrote:

By any sane definition, the constraint should actually be an input constraint on the frame pointer itself; something like:

#define ASM_CALL_CONSTRAINT "r" (__builtin_frame_address(0))

... except that "r" really should be a %rbp constraint, but %rbp doesn't seem to have a constraint letter. At least gcc 14.2 seems to do the right thing anyway, though: __builtin_frame_address(0) seems to force a frame pointer to have been created (even with -fomit-frame-pointer specified, and in a leaf function), and the value is always passed in %rbp (because why on Earth would it do it differently, when it is sitting right there?)

cl
This also matches the "tell the compiler [and programmer] what we actually mean" issue that you have mentioned in other contexts.

Anyway, here is a simple test case that can be used to verify that this construct does indeed work; at least with gcc 14.2.1 and clang 18.1.8 (the ones I ran a very quick test on).

It's simple enough that it is pretty straightforward to mess around with various modifications. So far I haven't been able to trip up the compilers this way.

-hpa
unsigned long testit_reg(unsigned long x, unsigned long y)
{
unsigned long z = x + y;
unsigned long v;

asm("# Frame pointer in %[fp]\n\tmov %[in],%[out]"
: [out] "=r" (v)
: [in] "r" (z), [fp] "r" (__builtin_frame_address(0)));

return v;
}

unsigned long testit_buf(unsigned long x, unsigned long y)
{
unsigned long z = x + y;
unsigned long buffer[64];

asm("# Frame pointer in %[fp]\n\tmov %[in],%[out]"
: [out] "=m" (buffer)
: [in] "r" (z), [fp] "r" (__builtin_frame_address(0)));

return buffer[0];
}