x86,intel_iommu: Replace cmpxchg_double()

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Tested-by: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20230531132323.855976804@infradead.org
This commit is contained in:
Peter Zijlstra 2023-05-31 15:08:42 +02:00
parent 0a0a6800b0
commit b1fe7f2cda
2 changed files with 64 additions and 61 deletions

View File

@ -175,18 +175,14 @@ static int modify_irte(struct irq_2_iommu *irq_iommu,
irte = &iommu->ir_table->base[index];
if ((irte->pst == 1) || (irte_modified->pst == 1)) {
bool ret;
ret = cmpxchg_double(&irte->low, &irte->high,
irte->low, irte->high,
irte_modified->low, irte_modified->high);
/*
* We use cmpxchg16 to atomically update the 128-bit IRTE,
* and it cannot be updated by the hardware or other processors
* behind us, so the return value of cmpxchg16 should be the
* same as the old value.
*/
WARN_ON(!ret);
u128 old = irte->irte;
WARN_ON(!try_cmpxchg128(&irte->irte, &old, irte_modified->irte));
} else {
WRITE_ONCE(irte->low, irte_modified->low);
WRITE_ONCE(irte->high, irte_modified->high);

View File

@ -202,67 +202,74 @@ static inline void detect_intel_iommu(void)
struct irte {
union {
/* Shared between remapped and posted mode*/
struct {
__u64 present : 1, /* 0 */
fpd : 1, /* 1 */
__res0 : 6, /* 2 - 6 */
avail : 4, /* 8 - 11 */
__res1 : 3, /* 12 - 14 */
pst : 1, /* 15 */
vector : 8, /* 16 - 23 */
__res2 : 40; /* 24 - 63 */
};
union {
/* Shared between remapped and posted mode*/
struct {
__u64 present : 1, /* 0 */
fpd : 1, /* 1 */
__res0 : 6, /* 2 - 6 */
avail : 4, /* 8 - 11 */
__res1 : 3, /* 12 - 14 */
pst : 1, /* 15 */
vector : 8, /* 16 - 23 */
__res2 : 40; /* 24 - 63 */
};
/* Remapped mode */
struct {
__u64 r_present : 1, /* 0 */
r_fpd : 1, /* 1 */
dst_mode : 1, /* 2 */
redir_hint : 1, /* 3 */
trigger_mode : 1, /* 4 */
dlvry_mode : 3, /* 5 - 7 */
r_avail : 4, /* 8 - 11 */
r_res0 : 4, /* 12 - 15 */
r_vector : 8, /* 16 - 23 */
r_res1 : 8, /* 24 - 31 */
dest_id : 32; /* 32 - 63 */
};
/* Remapped mode */
struct {
__u64 r_present : 1, /* 0 */
r_fpd : 1, /* 1 */
dst_mode : 1, /* 2 */
redir_hint : 1, /* 3 */
trigger_mode : 1, /* 4 */
dlvry_mode : 3, /* 5 - 7 */
r_avail : 4, /* 8 - 11 */
r_res0 : 4, /* 12 - 15 */
r_vector : 8, /* 16 - 23 */
r_res1 : 8, /* 24 - 31 */
dest_id : 32; /* 32 - 63 */
};
/* Posted mode */
struct {
__u64 p_present : 1, /* 0 */
p_fpd : 1, /* 1 */
p_res0 : 6, /* 2 - 7 */
p_avail : 4, /* 8 - 11 */
p_res1 : 2, /* 12 - 13 */
p_urgent : 1, /* 14 */
p_pst : 1, /* 15 */
p_vector : 8, /* 16 - 23 */
p_res2 : 14, /* 24 - 37 */
pda_l : 26; /* 38 - 63 */
};
__u64 low;
};
/* Posted mode */
struct {
__u64 p_present : 1, /* 0 */
p_fpd : 1, /* 1 */
p_res0 : 6, /* 2 - 7 */
p_avail : 4, /* 8 - 11 */
p_res1 : 2, /* 12 - 13 */
p_urgent : 1, /* 14 */
p_pst : 1, /* 15 */
p_vector : 8, /* 16 - 23 */
p_res2 : 14, /* 24 - 37 */
pda_l : 26; /* 38 - 63 */
};
__u64 low;
};
union {
/* Shared between remapped and posted mode*/
struct {
__u64 sid : 16, /* 64 - 79 */
sq : 2, /* 80 - 81 */
svt : 2, /* 82 - 83 */
__res3 : 44; /* 84 - 127 */
};
union {
/* Shared between remapped and posted mode*/
struct {
__u64 sid : 16, /* 64 - 79 */
sq : 2, /* 80 - 81 */
svt : 2, /* 82 - 83 */
__res3 : 44; /* 84 - 127 */
};
/* Posted mode*/
struct {
__u64 p_sid : 16, /* 64 - 79 */
p_sq : 2, /* 80 - 81 */
p_svt : 2, /* 82 - 83 */
p_res3 : 12, /* 84 - 95 */
pda_h : 32; /* 96 - 127 */
/* Posted mode*/
struct {
__u64 p_sid : 16, /* 64 - 79 */
p_sq : 2, /* 80 - 81 */
p_svt : 2, /* 82 - 83 */
p_res3 : 12, /* 84 - 95 */
pda_h : 32; /* 96 - 127 */
};
__u64 high;
};
};
__u64 high;
#ifdef CONFIG_IRQ_REMAP
__u128 irte;
#endif
};
};