On Thu, Apr 25, 2024 at 9:18 PM Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > > On Thu, 25 Apr 2024 at 11:58, Linus Torvalds > <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > > > > And maybe this time, it's not a buggy mess? > > Actually, even with MASK_VAL() fixed, I think it's *STILL* a buggy mess. > > Why? Beuse the *uses* of MASK_VAL() seem entirely bogus. > > In particular, we have this in cpc_write(): > > if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) > val = MASK_VAL(reg, val); > > switch (size) { > case 8: > writeb_relaxed(val, vaddr); > break; > case 16: > writew_relaxed(val, vaddr); > break; > ... > > and I strongly suspect that it needs to update the 'vaddr' too. Something like > > if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { > val = MASK_VAL(reg, val); > #ifdef __LITTLE_ENDIAN > vaddr += reg->bit_offset >> 3; > if (reg->bit_offset & 7) > return -EFAULT; > #else > /* Fixme if we ever care */ > if (reg->bit_offset) > return -EFAULT; > #endif > } > > *might* be changing this in the right direction, but it's unclear and > I neither know that CPC rules, nor did I think _that_ much about it. This is a very nice catch, thank you! > Anyway, the take-away should be that all this code is entirely broken > and somebody didn't think enough about it. > > It's possible that that whole cpc_write() ACPI_ADR_SPACE_SYSTEM_MEMORY > case should be done as a 64-bit "read-mask-write" sequence. > > Possibly with "reg->bit_offset == 0" and the 8/16/32/64-bit cases as a > special case for "just do the write". > > Or, maybe writes with a non-zero bit offset shouldn't be allowed at > all, and there are CPC rules that aren't checked. I don't know. I only > know that the current code is seriously broken. In any case, this needs to be taken care of (Jared?). Thanks, Rafael