|
Joerg Roedel |
cc9aff |
From: David Woodhouse <dwmw@amazon.co.uk>
|
|
Joerg Roedel |
cc9aff |
Date: Wed, 7 Oct 2020 13:20:44 +0100
|
|
Joerg Roedel |
cc9aff |
Subject: [PATCH 3/5] x86/ioapic: Handle Extended Destination ID field in RTE
|
|
Joerg Roedel |
cc9aff |
Patch-mainline: Never, upstream uses different implementation
|
|
Joerg Roedel |
cc9aff |
References: bsc#1181001, jsc#ECO-3191
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
The IOAPIC Redirection Table Entries contain an 8-bit Extended
|
|
Joerg Roedel |
cc9aff |
Destination ID field which maps to bits 11-4 of the MSI address.
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
The lowest bit is used to indicate remappable format, when interrupt
|
|
Joerg Roedel |
cc9aff |
remapping is in use. A hypervisor can use the other 7 bits to permit
|
|
Joerg Roedel |
cc9aff |
guests to address up to 15 bits of APIC IDs, thus allowing 32768 vCPUs
|
|
Joerg Roedel |
cc9aff |
before having to expose a vIOMMU and interrupt remapping to the guest.
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
No behavioural change in this patch, since nothing yet permits APIC IDs
|
|
Joerg Roedel |
cc9aff |
above 255 to be used with the non-IR IOAPIC domain. Except for the case
|
|
Joerg Roedel |
cc9aff |
where IR is enabled but there are IOAPICs which aren't in the scope of
|
|
Joerg Roedel |
cc9aff |
any IOMMU, which is totally hosed anyway and needs fixing independently
|
|
Joerg Roedel |
cc9aff |
of this change.
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
|
|
Joerg Roedel |
cc9aff |
Acked-by: Joerg Roedel <jroedel@suse.de>
|
|
Joerg Roedel |
cc9aff |
---
|
|
Joerg Roedel |
cc9aff |
arch/x86/include/asm/io_apic.h | 3 ++-
|
|
Joerg Roedel |
cc9aff |
arch/x86/kernel/apic/io_apic.c | 19 +++++++++++++------
|
|
Joerg Roedel |
cc9aff |
2 files changed, 15 insertions(+), 7 deletions(-)
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
--- a/arch/x86/include/asm/io_apic.h
|
|
Joerg Roedel |
cc9aff |
+++ b/arch/x86/include/asm/io_apic.h
|
|
Joerg Roedel |
cc9aff |
@@ -77,7 +77,8 @@ struct IO_APIC_route_entry {
|
|
Joerg Roedel |
cc9aff |
mask : 1, /* 0: enabled, 1: disabled */
|
|
Joerg Roedel |
cc9aff |
__reserved_2 : 15;
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
- __u32 __reserved_3 : 24,
|
|
Joerg Roedel |
cc9aff |
+ __u32 __reserved_3 : 17,
|
|
Joerg Roedel |
cc9aff |
+ ext_dest : 7,
|
|
Joerg Roedel |
cc9aff |
dest : 8;
|
|
Joerg Roedel |
cc9aff |
} __attribute__ ((packed));
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
--- a/arch/x86/kernel/apic/io_apic.c
|
|
Joerg Roedel |
cc9aff |
+++ b/arch/x86/kernel/apic/io_apic.c
|
|
Joerg Roedel |
cc9aff |
@@ -1268,10 +1268,10 @@ static void io_apic_print_entries(unsign
|
|
Joerg Roedel |
cc9aff |
buf, (ir_entry->index << 15) | ir_entry->index,
|
|
Joerg Roedel |
cc9aff |
ir_entry->zero);
|
|
Joerg Roedel |
cc9aff |
else
|
|
Joerg Roedel |
cc9aff |
- printk(KERN_DEBUG "%s, %s, D(%02X), M(%1d)\n",
|
|
Joerg Roedel |
cc9aff |
+ printk(KERN_DEBUG "%s, %s, D(%02X%02X), M(%1d)\n",
|
|
Joerg Roedel |
cc9aff |
buf,
|
|
Joerg Roedel |
cc9aff |
entry.dest_mode == IOAPIC_DEST_MODE_LOGICAL ?
|
|
Joerg Roedel |
cc9aff |
- "logical " : "physical",
|
|
Joerg Roedel |
cc9aff |
+ "logical " : "physical", entry.ext_dest,
|
|
Joerg Roedel |
cc9aff |
entry.dest, entry.delivery_mode);
|
|
Joerg Roedel |
cc9aff |
}
|
|
Joerg Roedel |
cc9aff |
}
|
|
Joerg Roedel |
cc9aff |
@@ -1439,6 +1439,7 @@ void native_disable_io_apic(void)
|
|
Joerg Roedel |
cc9aff |
*/
|
|
Joerg Roedel |
cc9aff |
if (ioapic_i8259.pin != -1) {
|
|
Joerg Roedel |
cc9aff |
struct IO_APIC_route_entry entry;
|
|
Joerg Roedel |
cc9aff |
+ u32 apic_id = read_apic_id();
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
memset(&entry, 0, sizeof(entry));
|
|
Joerg Roedel |
cc9aff |
entry.mask = IOAPIC_UNMASKED;
|
|
Joerg Roedel |
cc9aff |
@@ -1446,7 +1447,8 @@ void native_disable_io_apic(void)
|
|
Joerg Roedel |
cc9aff |
entry.polarity = IOAPIC_POL_HIGH;
|
|
Joerg Roedel |
cc9aff |
entry.dest_mode = IOAPIC_DEST_MODE_PHYSICAL;
|
|
Joerg Roedel |
cc9aff |
entry.delivery_mode = dest_ExtINT;
|
|
Joerg Roedel |
cc9aff |
- entry.dest = read_apic_id();
|
|
Joerg Roedel |
cc9aff |
+ entry.dest = apic_id & 0xff;
|
|
Joerg Roedel |
cc9aff |
+ entry.ext_dest = apic_id >> 8;
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
/*
|
|
Joerg Roedel |
cc9aff |
* Add it to the IO-APIC irq-routing table:
|
|
Joerg Roedel |
cc9aff |
@@ -1861,7 +1863,8 @@ static int ioapic_set_affinity(struct ir
|
|
Joerg Roedel |
cc9aff |
raw_spin_lock_irqsave(&ioapic_lock, flags);
|
|
Joerg Roedel |
cc9aff |
if (ret >= 0 && ret != IRQ_SET_MASK_OK_DONE) {
|
|
Joerg Roedel |
cc9aff |
cfg = irqd_cfg(irq_data);
|
|
Joerg Roedel |
cc9aff |
- data->entry.dest = cfg->dest_apicid;
|
|
Joerg Roedel |
cc9aff |
+ data->entry.dest = cfg->dest_apicid & 0xff;
|
|
Joerg Roedel |
cc9aff |
+ data->entry.ext_dest = cfg->dest_apicid >> 8;
|
|
Joerg Roedel |
cc9aff |
data->entry.vector = cfg->vector;
|
|
Joerg Roedel |
cc9aff |
for_each_irq_pin(entry, data->irq_2_pin)
|
|
Joerg Roedel |
cc9aff |
__ioapic_write_entry(entry->apic, entry->pin,
|
|
Joerg Roedel |
cc9aff |
@@ -1969,6 +1972,7 @@ static inline void __init unlock_ExtINT_
|
|
Joerg Roedel |
cc9aff |
int apic, pin, i;
|
|
Joerg Roedel |
cc9aff |
struct IO_APIC_route_entry entry0, entry1;
|
|
Joerg Roedel |
cc9aff |
unsigned char save_control, save_freq_select;
|
|
Joerg Roedel |
cc9aff |
+ u32 apic_id;
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
pin = find_isa_irq_pin(8, mp_INT);
|
|
Joerg Roedel |
cc9aff |
if (pin == -1) {
|
|
Joerg Roedel |
cc9aff |
@@ -1984,11 +1988,13 @@ static inline void __init unlock_ExtINT_
|
|
Joerg Roedel |
cc9aff |
entry0 = ioapic_read_entry(apic, pin);
|
|
Joerg Roedel |
cc9aff |
clear_IO_APIC_pin(apic, pin);
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
+ apic_id = hard_smp_processor_id();
|
|
Joerg Roedel |
cc9aff |
memset(&entry1, 0, sizeof(entry1));
|
|
Joerg Roedel |
cc9aff |
|
|
Joerg Roedel |
cc9aff |
entry1.dest_mode = IOAPIC_DEST_MODE_PHYSICAL;
|
|
Joerg Roedel |
cc9aff |
entry1.mask = IOAPIC_UNMASKED;
|
|
Joerg Roedel |
cc9aff |
- entry1.dest = hard_smp_processor_id();
|
|
Joerg Roedel |
cc9aff |
+ entry1.dest = apic_id & 0xff;
|
|
Joerg Roedel |
cc9aff |
+ entry1.ext_dest = apic_id >> 8;
|
|
Joerg Roedel |
cc9aff |
entry1.delivery_mode = dest_ExtINT;
|
|
Joerg Roedel |
cc9aff |
entry1.polarity = entry0.polarity;
|
|
Joerg Roedel |
cc9aff |
entry1.trigger = IOAPIC_EDGE;
|
|
Joerg Roedel |
cc9aff |
@@ -2896,7 +2902,8 @@ static void mp_setup_entry(struct irq_cf
|
|
Joerg Roedel |
cc9aff |
memset(entry, 0, sizeof(*entry));
|
|
Joerg Roedel |
cc9aff |
entry->delivery_mode = apic->irq_delivery_mode;
|
|
Joerg Roedel |
cc9aff |
entry->dest_mode = apic->irq_dest_mode;
|
|
Joerg Roedel |
cc9aff |
- entry->dest = cfg->dest_apicid;
|
|
Joerg Roedel |
cc9aff |
+ entry->dest = cfg->dest_apicid & 0xff;
|
|
Joerg Roedel |
cc9aff |
+ entry->ext_dest = cfg->dest_apicid >> 8;
|
|
Joerg Roedel |
cc9aff |
entry->vector = cfg->vector;
|
|
Joerg Roedel |
cc9aff |
entry->trigger = data->trigger;
|
|
Joerg Roedel |
cc9aff |
entry->polarity = data->polarity;
|