|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/9] AMD/IOMMU: use bit field for IRTE
On 13/06/2019 14:23, Jan Beulich wrote:
> At the same time restrict its scope to just the single source file
> actually using it, and abstract accesses by introducing a union of
> pointers. (A union of the actual table entries is not used to make it
> impossible to [wrongly, once the 128-bit form gets added] perform
> pointer arithmetic / array accesses on derived types.)
>
> Also move away from updating the entries piecemeal: Construct a full new
> entry, and write it out.
>
> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
> ---
> It would have been nice to use write_atomic() or ACCESS_ONCE() for the
> actual writes, but both cast the value to a scalar one, which doesn't
> suit us here (and I also didn't want to make the compound type a union
> with a raw member just for this).
Actually, having looked at the following patch, I think it would be
better to union with a uint32_t raw, so that we can use...
> @@ -101,47 +118,44 @@ static unsigned int alloc_intremap_entry
> return slot;
> }
>
> -static u32 *get_intremap_entry(int seg, int bdf, int offset)
> +static union irte_ptr get_intremap_entry(unsigned int seg, unsigned int bdf,
> + unsigned int offset)
> {
> - u32 *table = get_ivrs_mappings(seg)[bdf].intremap_table;
> + union irte_ptr table = {
> + .raw = get_ivrs_mappings(seg)[bdf].intremap_table
> + };
> +
> + ASSERT(table.raw && (offset < INTREMAP_ENTRIES));
>
> - ASSERT( (table != NULL) && (offset < INTREMAP_ENTRIES) );
> + table.basic += offset;
>
> - return table + offset;
> + return table;
> }
>
> -static void free_intremap_entry(int seg, int bdf, int offset)
> +static void free_intremap_entry(unsigned int seg, unsigned int bdf, unsigned
> int offset)
> {
> - u32 *entry = get_intremap_entry(seg, bdf, offset);
> + union irte_ptr entry = get_intremap_entry(seg, bdf, offset);
> +
> + *entry.basic = (struct irte_basic){};
ACCESS_ONCE(*entry.basic.raw) = 0;
and...
>
> - memset(entry, 0, sizeof(u32));
> __clear_bit(offset, get_ivrs_mappings(seg)[bdf].intremap_inuse);
> }
>
> -static void update_intremap_entry(u32* entry, u8 vector, u8 int_type,
> - u8 dest_mode, u8 dest)
> -{
> - set_field_in_reg_u32(IOMMU_CONTROL_ENABLED, 0,
> - INT_REMAP_ENTRY_REMAPEN_MASK,
> - INT_REMAP_ENTRY_REMAPEN_SHIFT, entry);
> - set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, *entry,
> - INT_REMAP_ENTRY_SUPIOPF_MASK,
> - INT_REMAP_ENTRY_SUPIOPF_SHIFT, entry);
> - set_field_in_reg_u32(int_type, *entry,
> - INT_REMAP_ENTRY_INTTYPE_MASK,
> - INT_REMAP_ENTRY_INTTYPE_SHIFT, entry);
> - set_field_in_reg_u32(IOMMU_CONTROL_DISABLED, *entry,
> - INT_REMAP_ENTRY_REQEOI_MASK,
> - INT_REMAP_ENTRY_REQEOI_SHIFT, entry);
> - set_field_in_reg_u32((u32)dest_mode, *entry,
> - INT_REMAP_ENTRY_DM_MASK,
> - INT_REMAP_ENTRY_DM_SHIFT, entry);
> - set_field_in_reg_u32((u32)dest, *entry,
> - INT_REMAP_ENTRY_DEST_MAST,
> - INT_REMAP_ENTRY_DEST_SHIFT, entry);
> - set_field_in_reg_u32((u32)vector, *entry,
> - INT_REMAP_ENTRY_VECTOR_MASK,
> - INT_REMAP_ENTRY_VECTOR_SHIFT, entry);
> +static void update_intremap_entry(union irte_ptr entry, unsigned int vector,
> + unsigned int int_type,
> + unsigned int dest_mode, unsigned int dest)
> +{
> + struct irte_basic basic = {
> + .remap_en = 1,
> + .sup_io_pf = 0,
> + .int_type = int_type,
> + .rq_eoi = 0,
> + .dm = dest_mode,
> + .dest = dest,
> + .vector = vector,
> + };
> +
> + *entry.basic = basic;
ACCESS_ONCE(*entry.basic.raw) = basic.raw.
The problem is in an unoptimised case, structure assignment in
implemented with memcpy(), which may be implemented as `rep stosb` which
may result in a spliced write with the enable bit set first.
Using a union with raw allows for the use of ACCESS_ONCE(), which forces
the compiler to implement them as 32bit single mov's.
~Andrew
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |