On 7. 10. 24 06:13, Suravee Suthikulpanit wrote: > + > /**************************************************************************** > * > * Helper functions > * > ****************************************************************************/ > > +static void write_dte_upper128(struct dev_table_entry *ptr, struct dev_table_entry *new) > +{ > + struct dev_table_entry old = {}; > + > + do { > + old.data128[1] = ptr->data128[1]; > + new->data[2] &= ~DTE_DATA2_INTR_MASK; > + new->data[2] |= old.data[2] & (DTE_DATA2_INTR_MASK | DTE_DATA2_RESV_MASK); > + } while (!try_cmpxchg128(&ptr->data128[1], &old.data128[1], new->data128[1])); Please note that try_cmpxchg inherently updates &old.data128[1] above on failure. There is no need to update value again in the loop. Please also note that the value from ptr->data128[1] should be read using READ_ONCE() to prevent compiler from merging, refetching or reordering the read. Currently, there is no READ_ONCE() implemented for __int128, so something like the attached patch should be used. Based on the above, the loop should be rewritten as: old.data128[1] = READ_ONCE(ptr->data128[1]); do { new->data[2] &= ~DTE_DATA2_INTR_MASK; new->data[2] |= old.data[2] & (DTE_DATA2_INTR_MASK | DTE_DATA2_RESV_MASK); } while (!try_cmpxchg128(&ptr->data128[1], &old.data128[1], new->data128[1])); > +} > + > +static void write_dte_lower128(struct dev_table_entry *ptr, struct dev_table_entry *new) > +{ > + struct dev_table_entry old = {}; > + > + /* > + * Need to preserve DTE[96:106], which can be set by information in IVRS table. > + * See set_dev_entry_from_acpi(). > + */ > + new->data[1] |= ptr->data[1] & DTE_FLAG_MASK; > + > + do { > + old.data128[0] = ptr->data128[0]; > + } while (!try_cmpxchg128(&ptr->data128[0], &old.data128[0], new->data128[0])); And this one as: old.data128[0] = READ_ONCE(ptr->data128[0]); do { } while (!try_cmpxchg128(&ptr->data128[0], &old.data128[0], new->data128[0])); Best regards, Uros.