Skip to content

Commit ec86921

Browse files
Sainath Grandhiwenlingz
authored andcommitted
hv: Introduce Global System Interrupt (GSI) into INTx Remapping
As ACRN prepares to support platforms with multiple IO-APICs, GSI is a better way to represent physical and virtual INTx interrupt source. 1) This patch replaces usage of "pin" with "gsi" whereever applicable across the modules. 2) PIC pin to gsi is trickier and needs to consider the usage of "Interrupt Source Override" structure in ACPI for the corresponding VM. Tracked-On: #4151 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
1 parent b0997e7 commit ec86921

File tree

12 files changed

+198
-128
lines changed

12 files changed

+198
-128
lines changed

hypervisor/arch/x86/guest/assign.c

Lines changed: 56 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -170,18 +170,18 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry)
170170
union ioapic_rte virt_rte;
171171
bool phys;
172172

173-
vioapic_get_rte(vm, virt_sid->intx_id.pin, &virt_rte);
173+
vioapic_get_rte(vm, virt_sid->intx_id.gsi, &virt_rte);
174174
rte = virt_rte;
175175

176176
/* init polarity & pin state */
177177
if (rte.bits.intr_polarity == IOAPIC_RTE_INTPOL_ALO) {
178178
if (entry->polarity == 0U) {
179-
vioapic_set_irqline_nolock(vm, virt_sid->intx_id.pin, GSI_SET_HIGH);
179+
vioapic_set_irqline_nolock(vm, virt_sid->intx_id.gsi, GSI_SET_HIGH);
180180
}
181181
entry->polarity = 1U;
182182
} else {
183183
if (entry->polarity == 1U) {
184-
vioapic_set_irqline_nolock(vm, virt_sid->intx_id.pin, GSI_SET_LOW);
184+
vioapic_set_irqline_nolock(vm, virt_sid->intx_id.gsi, GSI_SET_LOW);
185185
}
186186
entry->polarity = 0U;
187187
}
@@ -241,7 +241,7 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry)
241241
ioapic_get_rte(phys_irq, &phys_rte);
242242
rte = phys_rte;
243243
rte.bits.trigger_mode = IOAPIC_RTE_TRGRMODE_EDGE;
244-
vpic_get_irqline_trigger_mode(vm_pic(vm), (uint32_t)virt_sid->intx_id.pin, &trigger);
244+
vpic_get_irqline_trigger_mode(vm_pic(vm), (uint32_t)virt_sid->intx_id.gsi, &trigger);
245245
if (trigger == LEVEL_TRIGGER) {
246246
rte.bits.trigger_mode = IOAPIC_RTE_TRGRMODE_LEVEL;
247247
}
@@ -342,13 +342,13 @@ remove_msix_remapping(const struct acrn_vm *vm, uint16_t virt_bdf, uint32_t entr
342342
* - if the entry already be added by sos_vm, then change the owner to current vm
343343
* - if the entry already be added by other vm, return NULL
344344
*/
345-
static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin,
346-
uint32_t phys_pin, enum intx_ctlr vpin_ctlr)
345+
static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint32_t virt_gsi,
346+
uint32_t phys_gsi, enum intx_ctlr vgsi_ctlr)
347347
{
348348
struct ptirq_remapping_info *entry = NULL;
349-
DEFINE_INTX_SID(phys_sid, phys_pin, INTX_CTLR_IOAPIC);
350-
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
351-
uint32_t phys_irq = ioapic_pin_to_irq(phys_pin);
349+
DEFINE_INTX_SID(phys_sid, phys_gsi, INTX_CTLR_IOAPIC);
350+
DEFINE_INTX_SID(virt_sid, virt_gsi, vgsi_ctlr);
351+
uint32_t phys_irq = ioapic_gsi_to_irq(phys_gsi);
352352

353353
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &phys_sid, NULL);
354354
if (entry == NULL) {
@@ -366,16 +366,16 @@ static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint3
366366
}
367367
}
368368
} else {
369-
pr_err("INTX re-add vpin %d", virt_pin);
369+
pr_err("INTX re-add vpin %d", virt_gsi);
370370
}
371371
} else if (entry->vm != vm) {
372372
if (is_sos_vm(entry->vm)) {
373373
entry->vm = vm;
374374
entry->virt_sid.value = virt_sid.value;
375375
entry->polarity = 0U;
376376
} else {
377-
pr_err("INTX pin%d already in vm%d with vpin%d, not able to add into vm%d with vpin%d",
378-
phys_pin, entry->vm->vm_id, entry->virt_sid.intx_id.pin, vm->vm_id, virt_pin);
377+
pr_err("INTX gsi%d already in vm%d with vgsi%d, not able to add into vm%d with vgsi%d",
378+
phys_gsi, entry->vm->vm_id, entry->virt_sid.intx_id.gsi, vm->vm_id, virt_gsi);
379379
entry = NULL;
380380
}
381381
} else {
@@ -389,20 +389,20 @@ static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint3
389389
*/
390390

391391
if (entry != NULL) {
392-
dev_dbg(DBG_LEVEL_IRQ, "VM%d INTX add pin mapping vpin%d:ppin%d",
393-
entry->vm->vm_id, virt_pin, phys_pin);
392+
dev_dbg(DBG_LEVEL_IRQ, "VM%d INTX add pin mapping vgsi%d:pgsi%d",
393+
entry->vm->vm_id, virt_gsi, phys_gsi);
394394
}
395395

396396
return entry;
397397
}
398398

399399
/* deactive & remove mapping entry of vpin for vm */
400-
static void remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_pin, enum intx_ctlr vpin_ctlr)
400+
static void remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_gsi, enum intx_ctlr vgsi_ctlr)
401401
{
402402
uint32_t phys_irq;
403403
struct ptirq_remapping_info *entry;
404404
struct intr_source intr_src;
405-
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
405+
DEFINE_INTX_SID(virt_sid, virt_gsi, vgsi_ctlr);
406406

407407
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
408408
if (entry != NULL) {
@@ -417,11 +417,11 @@ static void remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_pin, e
417417

418418
dmar_free_irte(intr_src, (uint16_t)phys_irq);
419419
dev_dbg(DBG_LEVEL_IRQ,
420-
"deactive %s intx entry:ppin=%d, pirq=%d ",
421-
(vpin_ctlr == INTX_CTLR_PIC) ? "vPIC" : "vIOAPIC",
422-
entry->phys_sid.intx_id.pin, phys_irq);
423-
dev_dbg(DBG_LEVEL_IRQ, "from vm%d vpin=%d\n",
424-
entry->vm->vm_id, virt_pin);
420+
"deactive %s intx entry:pgsi=%d, pirq=%d ",
421+
(vgsi_ctlr == INTX_CTLR_PIC) ? "vPIC" : "vIOAPIC",
422+
entry->phys_sid.intx_id.gsi, phys_irq);
423+
dev_dbg(DBG_LEVEL_IRQ, "from vm%d vgsi=%d\n",
424+
entry->vm->vm_id, virt_gsi);
425425
}
426426

427427
ptirq_release_entry(entry);
@@ -439,22 +439,22 @@ static void ptirq_handle_intx(struct acrn_vm *vm,
439439
bool trigger_lvl = false;
440440

441441
/* INTX_CTLR_IOAPIC means we have vioapic enabled */
442-
vioapic_get_rte(vm, (uint32_t)virt_sid->intx_id.pin, &rte);
442+
vioapic_get_rte(vm, (uint32_t)virt_sid->intx_id.gsi, &rte);
443443
if (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL) {
444444
trigger_lvl = true;
445445
}
446446

447447
if (trigger_lvl) {
448448
if (entry->polarity != 0U) {
449-
vioapic_set_irqline_lock(vm, virt_sid->intx_id.pin, GSI_SET_LOW);
449+
vioapic_set_irqline_lock(vm, virt_sid->intx_id.gsi, GSI_SET_LOW);
450450
} else {
451-
vioapic_set_irqline_lock(vm, virt_sid->intx_id.pin, GSI_SET_HIGH);
451+
vioapic_set_irqline_lock(vm, virt_sid->intx_id.gsi, GSI_SET_HIGH);
452452
}
453453
} else {
454454
if (entry->polarity != 0U) {
455-
vioapic_set_irqline_lock(vm, virt_sid->intx_id.pin, GSI_FALLING_PULSE);
455+
vioapic_set_irqline_lock(vm, virt_sid->intx_id.gsi, GSI_FALLING_PULSE);
456456
} else {
457-
vioapic_set_irqline_lock(vm, virt_sid->intx_id.pin, GSI_RAISING_PULSE);
457+
vioapic_set_irqline_lock(vm, virt_sid->intx_id.gsi, GSI_RAISING_PULSE);
458458
}
459459
}
460460

@@ -470,11 +470,11 @@ static void ptirq_handle_intx(struct acrn_vm *vm,
470470
enum vpic_trigger trigger;
471471

472472
/* INTX_CTLR_PIC means we have vpic enabled */
473-
vpic_get_irqline_trigger_mode(vm_pic(vm), virt_sid->intx_id.pin, &trigger);
473+
vpic_get_irqline_trigger_mode(vm_pic(vm), virt_sid->intx_id.gsi, &trigger);
474474
if (trigger == LEVEL_TRIGGER) {
475-
vpic_set_irqline(vm_pic(vm), virt_sid->intx_id.pin, GSI_SET_HIGH);
475+
vpic_set_irqline(vm_pic(vm), virt_sid->intx_id.gsi, GSI_SET_HIGH);
476476
} else {
477-
vpic_set_irqline(vm_pic(vm), virt_sid->intx_id.pin, GSI_RAISING_PULSE);
477+
vpic_set_irqline(vm_pic(vm), virt_sid->intx_id.gsi, GSI_RAISING_PULSE);
478478
}
479479
break;
480480
}
@@ -525,11 +525,11 @@ void ptirq_softirq(uint16_t pcpu_id)
525525
}
526526
}
527527

528-
void ptirq_intx_ack(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ctlr vpin_ctlr)
528+
void ptirq_intx_ack(struct acrn_vm *vm, uint32_t virt_gsi, enum intx_ctlr vgsi_ctlr)
529529
{
530530
uint32_t phys_irq;
531531
struct ptirq_remapping_info *entry;
532-
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
532+
DEFINE_INTX_SID(virt_sid, virt_gsi, vgsi_ctlr);
533533

534534
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
535535
if (entry != NULL) {
@@ -538,20 +538,20 @@ void ptirq_intx_ack(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ctlr vpin_c
538538
/* NOTE: only Level trigger will process EOI/ACK and if we got here
539539
* means we have this vioapic or vpic or both enabled
540540
*/
541-
switch (vpin_ctlr) {
541+
switch (vgsi_ctlr) {
542542
case INTX_CTLR_IOAPIC:
543543
if (entry->polarity != 0U) {
544-
vioapic_set_irqline_lock(vm, virt_pin, GSI_SET_HIGH);
544+
vioapic_set_irqline_lock(vm, virt_gsi, GSI_SET_HIGH);
545545
} else {
546-
vioapic_set_irqline_lock(vm, virt_pin, GSI_SET_LOW);
546+
vioapic_set_irqline_lock(vm, virt_gsi, GSI_SET_LOW);
547547
}
548548
break;
549549
case INTX_CTLR_PIC:
550-
vpic_set_irqline(vm_pic(vm), virt_pin, GSI_SET_LOW);
550+
vpic_set_irqline(vm_pic(vm), virt_gsi, GSI_SET_LOW);
551551
break;
552552
default:
553553
/*
554-
* In this switch statement, vpin_ctlr shall either be
554+
* In this switch statement, vgsi_ctlr shall either be
555555
* INTX_CTLR_IOAPIC or INTX_CTLR_PIC.
556556
* Gracefully return if prior case clauses have not been met.
557557
*/
@@ -670,12 +670,12 @@ static void activate_physical_ioapic(struct acrn_vm *vm,
670670
/* Main entry for PCI/Legacy device assignment with INTx, calling from vIOAPIC
671671
* or vPIC
672672
*/
673-
int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ctlr vpin_ctlr)
673+
int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_gsi, enum intx_ctlr vgsi_ctlr)
674674
{
675675
int32_t status = 0;
676676
struct ptirq_remapping_info *entry = NULL;
677-
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
678-
DEFINE_INTX_SID(alt_virt_sid, virt_pin, vpin_ctlr);
677+
DEFINE_INTX_SID(virt_sid, virt_gsi, vgsi_ctlr);
678+
DEFINE_INTX_SID(alt_virt_sid, virt_gsi, vgsi_ctlr);
679679

680680
/*
681681
* virt pin could come from vpic master, vpic slave or vioapic
@@ -689,7 +689,7 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
689689
*/
690690

691691
/* no remap for vuart intx */
692-
if (!is_vuart_intx(vm, virt_sid.intx_id.pin)) {
692+
if (!is_vuart_intx(vm, virt_sid.intx_id.gsi)) {
693693
/* query if we have virt to phys mapping */
694694
spinlock_obtain(&ptdev_lock);
695695
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
@@ -703,38 +703,32 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
703703
* the other vpin source for legacy pin. If yes, then
704704
* switch vpin source is needed
705705
*/
706-
if (virt_pin < NR_LEGACY_PIN) {
707-
uint32_t vpin = get_pic_pin_from_ioapic_pin(virt_pin);
706+
if (virt_gsi < NR_LEGACY_PIN) {
708707

709-
if (vpin_ctlr == INTX_CTLR_PIC) {
708+
if (vgsi_ctlr == INTX_CTLR_PIC) {
710709
alt_virt_sid.intx_id.ctlr = INTX_CTLR_IOAPIC;
711710
} else {
712711
alt_virt_sid.intx_id.ctlr = INTX_CTLR_PIC;
713712
}
714-
alt_virt_sid.intx_id.pin = vpin;
715713

716714
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &alt_virt_sid, vm);
717715
if (entry != NULL) {
718716
entry->virt_sid.value = virt_sid.value;
719717
dev_dbg(DBG_LEVEL_IRQ,
720-
"IOAPIC pin=%hhu pirq=%u vpin=%d switch from %s to %s vpin=%d for vm%d",
721-
entry->phys_sid.intx_id.pin,
722-
entry->allocated_pirq, entry->virt_sid.intx_id.pin,
723-
(vpin_ctlr == INTX_CTLR_IOAPIC) ? "vPIC" : "vIOAPIC",
724-
(vpin_ctlr == INTX_CTLR_IOAPIC) ? "vIOPIC" : "vPIC",
725-
virt_pin, entry->vm->vm_id);
718+
"IOAPIC gsi=%hhu pirq=%u vgsi=%d switch from %s to %s for vm%d",
719+
entry->phys_sid.intx_id.gsi,
720+
entry->allocated_pirq, entry->virt_sid.intx_id.gsi,
721+
(vgsi_ctlr == INTX_CTLR_IOAPIC) ? "vPIC" : "vIOAPIC",
722+
(vgsi_ctlr == INTX_CTLR_IOAPIC) ? "vIOPIC" : "vPIC",
723+
entry->vm->vm_id);
726724
}
727725
}
728726

729727
/* entry could be updated by above switch check */
730728
if (entry == NULL) {
731-
uint32_t phys_pin = virt_pin;
729+
uint32_t phys_gsi = virt_gsi;
732730

733-
/* fix vPIC pin to correct native IOAPIC pin */
734-
if (vpin_ctlr == INTX_CTLR_PIC) {
735-
phys_pin = get_pic_pin_from_ioapic_pin(virt_pin);
736-
}
737-
entry = add_intx_remapping(vm, virt_pin, phys_pin, vpin_ctlr);
731+
entry = add_intx_remapping(vm, virt_gsi, phys_gsi, vgsi_ctlr);
738732
if (entry == NULL) {
739733
pr_err("%s, add intx remapping failed",
740734
__func__);
@@ -769,13 +763,13 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
769763
* - currently, one phys_pin can only be held by one pin source (vPIC or
770764
* vIOAPIC)
771765
*/
772-
int32_t ptirq_add_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, uint32_t phys_pin, bool pic_pin)
766+
int32_t ptirq_add_intx_remapping(struct acrn_vm *vm, uint32_t virt_gsi, uint32_t phys_gsi, bool pic_pin)
773767
{
774768
struct ptirq_remapping_info *entry;
775-
enum intx_ctlr vpin_ctlr = pic_pin ? INTX_CTLR_PIC : INTX_CTLR_IOAPIC;
769+
enum intx_ctlr vgsi_ctlr = pic_pin ? INTX_CTLR_PIC : INTX_CTLR_IOAPIC;
776770

777771
spinlock_obtain(&ptdev_lock);
778-
entry = add_intx_remapping(vm, virt_pin, phys_pin, vpin_ctlr);
772+
entry = add_intx_remapping(vm, virt_gsi, phys_gsi, vgsi_ctlr);
779773
spinlock_release(&ptdev_lock);
780774

781775
return (entry != NULL) ? 0 : -ENODEV;
@@ -784,12 +778,12 @@ int32_t ptirq_add_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, uint32_t
784778
/*
785779
* @pre vm != NULL
786780
*/
787-
void ptirq_remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_pin, bool pic_pin)
781+
void ptirq_remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_gsi, bool pic_pin)
788782
{
789-
enum intx_ctlr vpin_ctlr = pic_pin ? INTX_CTLR_PIC : INTX_CTLR_IOAPIC;
783+
enum intx_ctlr vgsi_ctlr = pic_pin ? INTX_CTLR_PIC : INTX_CTLR_IOAPIC;
790784

791785
spinlock_obtain(&ptdev_lock);
792-
remove_intx_remapping(vm, virt_pin, vpin_ctlr);
786+
remove_intx_remapping(vm, virt_gsi, vgsi_ctlr);
793787
spinlock_release(&ptdev_lock);
794788
}
795789

hypervisor/arch/x86/ioapic.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -301,18 +301,12 @@ bool ioapic_is_pin_valid(uint32_t pin)
301301
return (pin != INVALID_INTERRUPT_PIN);
302302
}
303303

304-
uint32_t ioapic_pin_to_irq(uint32_t pin)
304+
/*
305+
*@pre ioapic_irq_is_gsi(gsi) == true
306+
*/
307+
uint32_t ioapic_gsi_to_irq(uint32_t gsi)
305308
{
306-
uint32_t i;
307-
uint32_t irq = IRQ_INVALID;
308-
309-
for (i = 0U; i < ioapic_nr_gsi; i++) {
310-
if (gsi_table_data[i].pin == pin) {
311-
irq = i;
312-
break;
313-
}
314-
}
315-
return irq;
309+
return gsi;
316310
}
317311

318312
static void

0 commit comments

Comments
 (0)