mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-01-05 07:35:31 +00:00
hv: Handle holes in GSI i.e. Global System Interrupt for multiple IO-APICs
MADT is used to specify the GSI base for each IO-APIC and the number of interrupt pins per IO-APIC is programmed into Max. Redir. Entry register of that IO-APIC. On platforms with multiple IO-APICs, there can be holes in the GSI space. For example, on a platform with 2 IO-APICs, the following configuration has a hole (from 24 to 31) in the GSI space. IO-APIC 1: GSI base - 0, number of pins - 24 IO-APIC 2: GSI base - 32, number of pins - 8 This patch also adjusts the size for variables used to represent the total number of IO-APICs on the system from uint16_t to uint8_t as the ACPI MADT uses only 8-bits to indicate the unique IO-APIC IDs. Tracked-On: #4151 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
committed by
wenlingz
parent
85217e362f
commit
f67ac09141
@@ -1253,7 +1253,7 @@ static int32_t shell_show_vioapic_info(int32_t argc, char **argv)
|
||||
static int32_t get_ioapic_info(char *str_arg, size_t str_max_len)
|
||||
{
|
||||
char *str = str_arg;
|
||||
uint32_t irq;
|
||||
uint32_t gsi;
|
||||
size_t len, size = str_max_len;
|
||||
uint32_t ioapic_nr_gsi = 0U;
|
||||
|
||||
@@ -1264,20 +1264,21 @@ static int32_t get_ioapic_info(char *str_arg, size_t str_max_len)
|
||||
size -= len;
|
||||
str += len;
|
||||
|
||||
ioapic_nr_gsi = ioapic_get_nr_gsi ();
|
||||
for (irq = 0U; irq < ioapic_nr_gsi; irq++) {
|
||||
void *addr = gsi_to_ioapic_base(irq);
|
||||
uint32_t pin = ioapic_irq_to_pin(irq);
|
||||
ioapic_nr_gsi = get_max_nr_gsi ();
|
||||
for (gsi = 0U; gsi < ioapic_nr_gsi; gsi++) {
|
||||
void *addr;
|
||||
uint32_t pin;
|
||||
union ioapic_rte rte;
|
||||
|
||||
/* Add NULL check for addr, INVALID_PIN check for pin */
|
||||
if ((addr == NULL) || (!ioapic_is_pin_valid(pin))) {
|
||||
goto overflow;
|
||||
if (!is_gsi_valid(gsi)) {
|
||||
continue;
|
||||
}
|
||||
addr = gsi_to_ioapic_base(gsi);
|
||||
pin = gsi_to_ioapic_pin(gsi);
|
||||
|
||||
ioapic_get_rte_entry(addr, pin, &rte);
|
||||
|
||||
len = snprintf(str, size, "\r\n%03d\t%03hhu\t0x%08X\t0x%08X\t", irq, pin, rte.u.hi_32, rte.u.lo_32);
|
||||
len = snprintf(str, size, "\r\n%03d\t%03hhu\t0x%08X\t0x%08X\t", gsi, pin, rte.u.hi_32, rte.u.lo_32);
|
||||
if (len >= size) {
|
||||
goto overflow;
|
||||
}
|
||||
@@ -1285,8 +1286,10 @@ static int32_t get_ioapic_info(char *str_arg, size_t str_max_len)
|
||||
str += len;
|
||||
|
||||
len = snprintf(str, size, "0x%02X\t0x%02X\t%s\t%s\t%u\t%d\t%d",
|
||||
rte.bits.vector, rte.bits.dest_field, rte.bits.dest_mode ? "logic" : "phys",
|
||||
rte.bits.trigger_mode ? "level" : "edge", rte.bits.delivery_mode, rte.bits.remote_irr,
|
||||
rte.bits.vector, rte.bits.dest_field,
|
||||
(rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_LOGICAL)? "logic" : "phys",
|
||||
(rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL)? "level" : "edge",
|
||||
rte.bits.delivery_mode, rte.bits.remote_irr,
|
||||
rte.bits.intr_mask);
|
||||
if (len >= size) {
|
||||
goto overflow;
|
||||
|
||||
Reference in New Issue
Block a user