[lkml]   [2012]   [Feb]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    SubjectRe: Memory corruption due to word sharing
    On Wed, Feb 1, 2012 at 11:40 AM, Jakub Jelinek <> wrote:
    > Well, the C++11/C11 model doesn't allow to use the underlying type
    > for accesses, consider e.g.
    > struct S { long s1; unsigned int s2 : 5; unsigned int s3 : 19; unsigned char s4; unsigned int s5; };
    > struct T { long s1 : 16; unsigned int s2; };
    > on e.g. x86_64-linux, S is 16 byte long, field s4 is packed together into
    > the same 32 bits as s2 and s3.  While the memory model allows s2 to be
    > changed when storing s3 (i.e. use a RMW cycle on it), it doesn't allow s4
    > to be changed, as it isn't a bitfield (you'd need s4 : 8 for that).
    > T is 8 bytes long, again, s2 is packed into the same 64 bits as s1,
    > and the memory model doesn't allow s2 to be modified.
    > Not sure what the kernel would expect in such a case.

    So the kernel really doesn't care what you do to things *within* the bitfield.

    Sure, we do have some expectations of packing, but basically we never
    expect bitfields to be 'atomic'. You really don't need to worry about

    From a correctness standpoint, I really don't think the kernel cares
    if gcc does bitfield reads and writes one bit at a time. Seriously.

    The bug is that the bitfield write wrote *outside* the bitfield.
    That's *WRONG*. It's completely wrong, even if you write back the same
    value you read. It's *always* wrong. It's simply not acceptable.

    If gcc does that kind of crap, then gcc needs to align bitfields
    sufficiently that the accesses that are outside the bitfields never
    touch any other fields.

    So what I would suggest:

    - use the *smallest* aligned access you can use to access the
    bitfield. This will be 'correct', but it may perform badly.

    This is apparently what x86 does. So on x86, if you have a one-bit
    bitfield within a bitfield that is really 32 bits wide, it looks like
    gcc will generally generate a byte load/store to set that bit. I don't
    know exactly what the rules are, but this is fine from a *correctness*

    - However, while using the *smallest* possible access may generate
    correct code, it often generates really *crappy* code. Which is
    exactly the bug that I reported in

    So quite frankly, my suggestion is to just try to use the base type.

    But *whatever* you do, using a type *larger* than the whole bitfield
    itself is a bug.

    And dammit, the people who continue to bring up C11 as if this was a
    new issue, and only needs to be worried about if you support C11 (ie
    gcc-4.7 and up) are just in denial.

    The 'volatile' example makes it entirely clear that the bug has
    nothing what-so-ever to do with C11.

    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to
    More majordomo info at
    Please read the FAQ at

     \ /
      Last update: 2012-02-01 21:05    [W:0.029 / U:13.688 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site