drivers/interrupt_controller: Write IRTE as 64bits blocks in VT-D

Looks like a source of fault if pieces of IRTE are written instead of
the whole 64 bits block it belongs to.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This commit is contained in:
Tomasz Bursztyka 2021-01-11 08:53:11 +01:00 committed by Anas Nashif
commit a8c8abd27e
2 changed files with 38 additions and 32 deletions

View file

@ -82,24 +82,24 @@ static int vtd_ictl_remap(const struct device *dev,
uint32_t flags)
{
struct vtd_ictl_data *data = dev->data;
struct vtd_irte irte = { 0 };
memset(&data->irte[irte_idx], 0, sizeof(struct vtd_irte));
data->irte[irte_idx].l.vector = vector;
irte.l.vector = vector;
if (IS_ENABLED(CONFIG_X2APIC)) {
data->irte[irte_idx].l.dst_id = arch_curr_cpu()->id;
irte.l.dst_id = arch_curr_cpu()->id;
} else {
data->irte[irte_idx].l.dst_id = arch_curr_cpu()->id << 8;
irte.l.dst_id = arch_curr_cpu()->id << 8;
}
data->irte[irte_idx].l.trigger_mode =
(flags & IOAPIC_TRIGGER_MASK) >> 15;
data->irte[irte_idx].l.delivery_mode =
(flags & IOAPIC_DELIVERY_MODE_MASK) >> 8;
data->irte[irte_idx].l.dst_mode = 1;
data->irte[irte_idx].l.redirection_hint = 1;
data->irte[irte_idx].l.present = 1;
irte.l.trigger_mode = (flags & IOAPIC_TRIGGER_MASK) >> 15;
irte.l.delivery_mode = (flags & IOAPIC_DELIVERY_MODE_MASK) >> 8;
irte.l.dst_mode = 1;
irte.l.redirection_hint = 1;
irte.l.present = 1;
data->irte[irte_idx].low = irte.low;
data->irte[irte_idx].high = irte.high;
return 0;
}

View file

@ -17,27 +17,33 @@
/* Interrupt Remapping Table Entry (IRTE) for Remapped Interrupts */
struct vtd_irte {
struct {
uint64_t present : 1;
uint64_t fpd : 1;
uint64_t dst_mode : 1;
uint64_t redirection_hint : 1;
uint64_t trigger_mode : 1;
uint64_t delivery_mode : 3;
uint64_t available : 4;
uint64_t _reserved_0 : 3;
uint64_t irte_mode : 1;
uint64_t vector : 8;
uint64_t _reserved_1 : 8;
uint64_t dst_id : 32;
} l;
union {
struct vtd_irte_low {
uint64_t present : 1;
uint64_t fpd : 1;
uint64_t dst_mode : 1;
uint64_t redirection_hint : 1;
uint64_t trigger_mode : 1;
uint64_t delivery_mode : 3;
uint64_t available : 4;
uint64_t _reserved_0 : 3;
uint64_t irte_mode : 1;
uint64_t vector : 8;
uint64_t _reserved_1 : 8;
uint64_t dst_id : 32;
} l;
uint64_t low;
};
struct {
uint64_t src_id : 16;
uint64_t src_id_qualifier : 2;
uint64_t src_validation_type : 2;
uint64_t _reserved : 44;
} h;
union {
struct vtd_irte_high {
uint64_t src_id : 16;
uint64_t src_id_qualifier : 2;
uint64_t src_validation_type : 2;
uint64_t _reserved : 44;
} h;
uint64_t high;
};
} __packed;
/* The table must be 4KB aligned, which is exactly 256 entries.