Inline assembly correctness (especially __volatile__) Here's my inline-assembly functions, which is used my x86 32bit kernel.

static inline uint8_t ckPortInByte(uint16_t port)
{
    uint8_t ret;
    __asm__ __volatile__ ( "in %1, %0" : "=a"(ret) : "d"(port) );
    return ret;
}

static inline void ckPortOutByte(uint16_t port, uint8_t data)
{
    __asm__ __volatile__ ( "out %0, %1" : : "a"(data), "d"(port) );
}

static inline uint32_t ckAsmGetEFlag()
{
    uint32_t ret;
    __asm__ __volatile__ ( "pushfl \n pop %0" : "=g"(ret) );
    return ret;
}

static inline void ckAsmSetEFlag(uint32_t eflag)
{
    __asm__ __volatile__ ( "push %0 \n popfl" : : "g"(eflag) );
}

static inline uint32_t ckGetCr0()
{
    uint32_t ret;
    __asm__ ( "mov %%cr0, %0" : "=r"(ret) );
    return ret;
}

static inline void ckSetCr0(uint32_t value)
{
    __asm__ ( "mov %0, %%cr0" : : "r"(value) );
}

static inline uint32_t ckGetCr3()
{
    uint32_t ret;
    __asm__ ( "mov %%cr3, %0 " : "=r"(ret) );
    return ret;
}

static inline void ckSetCr3(uint32_t value)
{
    __asm__ ( "mov %0, %%cr3" : : "r"(value) );
}

static inline void ckAsmCpuid(uint32_t code, CpuidStruct *cs)
{
    __asm__
    (
        "cpuid"
        : "=a"(cs-&gt;eax), "=b"(cs-&gt;ebx), "=c"(cs-&gt;ecx), "=d"(cs-&gt;edx)
        : "a"(code)
    );
}

static inline void ckAsmCli()
{
    __asm__ __volatile__ ( "cli" );
}

static inline void ckAsmSti()
{
    __asm__ __volatile__ ( "sti" );
}

static inline void ckAsmStiHlt()
{
    __asm__ __volatile__ ( "sti \n hlt" );
}

static inline void ckAsmHlt()
{
    __asm__ __volatile__ ( "hlt" );
}


It seems that everything is ok.

However, recently I had a bug, which is related to these functions, especially __volatile__ correctness. (Can you see __volatile__ in ckPortInByte and ckPortOutByte? They didn't exist before I fixed it...)

So, I'm really afraid now - Is there anything wrong? (i.e. unnecessary or missing __volatile__)
Your use of volatile appears to be correct, but I think you should do a couple of things for safety:


Add a clobber constraint for the flags (AKA "condition codes") to ckAsmSetEFlag. I believe this is "cc" for x86 machines.
Add clobber constraints for CR0 and CR3 to ckSetCr0 and ckSetCr3, respectively. [edit] This appears to be impossible with GCC. Not sure if this is a problem or not.[/edit]


While GCC's inline assembly syntax is very powerful, it can be horribly unintuitive. Since you're writing a kernel and messing with control registers, you really should be checking the assembly listings for every module you compile, to verify that the compiler is honouring your intentions.