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>
diff --git a/drivers/interrupt_controller/intc_intel_vtd.c b/drivers/interrupt_controller/intc_intel_vtd.c
index 60082f9..f90c20d 100644
--- a/drivers/interrupt_controller/intc_intel_vtd.c
+++ b/drivers/interrupt_controller/intc_intel_vtd.c
@@ -82,24 +82,24 @@
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;
}
diff --git a/drivers/interrupt_controller/intc_intel_vtd.h b/drivers/interrupt_controller/intc_intel_vtd.h
index 894d7da..82ed093 100644
--- a/drivers/interrupt_controller/intc_intel_vtd.h
+++ b/drivers/interrupt_controller/intc_intel_vtd.h
@@ -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.