Skip to content

Commit 37eb369

Browse files
Sainath Grandhiwenlingz
authored andcommitted
hv: Use ptirq_lookup_entry_by_sid to lookup virtual source id in IOAPIC irq entries
Reverts 538ba08: hv:Add vpin to ptdev entry mapping for vpic/vioapic ACRN uses an array of size per VM to store ptirq entries against the vIOAPIC pin and an array of size per VM to store ptirq entries against the vPIC pin. This is done to speed up "ptirq entry" lookup at runtime for Level triggered interrupts in API ptirq_intx_ack used on EOI. This patch switches the lookup API for INTx interrupts to the API, ptirq_lookup_entry_by_sid This could add delay to processing EOI for Level triggered interrupts. Trade-off here is space saved for array/s of size CONFIG_MAX_IOAPIC_LINES with 8 bytes per data. On a server platform, ACRN needs to emulate multiple vIOAPICs for SOS VM, same as the number of physical IO-APICs. Thereby ACRN would need around 10 such arrays per VM. Removes the need of "pic_pin" except for the APIs facing the hypercalls hcall_set_ptdev_intr_info, hcall_reset_ptdev_intr_info Tracked-On: #4151 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
1 parent 0c9628f commit 37eb369

File tree

5 files changed

+46
-73
lines changed

5 files changed

+46
-73
lines changed

hypervisor/arch/x86/guest/assign.c

Lines changed: 43 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,6 @@ ptirq_lookup_entry_by_sid(uint32_t intr_type,
4747
return entry_found;
4848
}
4949

50-
static inline struct ptirq_remapping_info *
51-
ptirq_lookup_entry_by_vpin(const struct acrn_vm *vm, uint32_t virt_pin, bool pic_pin)
52-
{
53-
struct ptirq_remapping_info *entry;
54-
55-
if (pic_pin) {
56-
entry = vm->arch_vm.vpic.vpin_to_pt_entry[virt_pin];
57-
} else {
58-
entry = vm->arch_vm.vioapic.vpin_to_pt_entry[virt_pin];
59-
}
60-
return entry;
61-
}
62-
6350
static uint32_t calculate_logical_dest_mask(uint64_t pdmask)
6451
{
6552
uint32_t dest_mask = 0UL;
@@ -356,23 +343,21 @@ remove_msix_remapping(const struct acrn_vm *vm, uint16_t virt_bdf, uint32_t entr
356343
* - if the entry already be added by other vm, return NULL
357344
*/
358345
static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin,
359-
uint32_t phys_pin, bool pic_pin)
346+
uint32_t phys_pin, enum intx_ctlr vpin_ctlr)
360347
{
361348
struct ptirq_remapping_info *entry = NULL;
362-
bool entry_is_updated = true;
363-
enum intx_ctlr vpin_ctlr = pic_pin ? INTX_CTLR_PIC : INTX_CTLR_IOAPIC;
364349
DEFINE_INTX_SID(phys_sid, phys_pin, INTX_CTLR_IOAPIC);
365350
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
366351
uint32_t phys_irq = ioapic_pin_to_irq(phys_pin);
367352

368-
if (((!pic_pin) && (virt_pin >= vioapic_pincount(vm))) || (pic_pin && (virt_pin >= vpic_pincount()))) {
353+
if (((vpin_ctlr == INTX_CTLR_IOAPIC) && (virt_pin >= vioapic_pincount(vm))) || ((vpin_ctlr == INTX_CTLR_PIC) && (virt_pin >= vpic_pincount()))) {
369354
pr_err("ptirq_add_intx_remapping fails!\n");
370355
} else if (!ioapic_irq_is_gsi(phys_irq)) {
371356
pr_err("%s, invalid phys_pin: %d <-> irq: 0x%x is not a GSI\n", __func__, phys_pin, phys_irq);
372357
} else {
373358
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &phys_sid, NULL);
374359
if (entry == NULL) {
375-
if (ptirq_lookup_entry_by_vpin(vm, virt_pin, pic_pin) == NULL) {
360+
if (ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm) == NULL) {
376361
entry = ptirq_alloc_entry(vm, PTDEV_INTR_INTX);
377362
if (entry != NULL) {
378363
entry->phys_sid.value = phys_sid.value;
@@ -401,15 +386,12 @@ static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint3
401386
} else {
402387
/* The mapping has already been added to the VM. No action
403388
* required. */
404-
entry_is_updated = false;
405389
}
406390

407-
if ((entry != NULL) && entry_is_updated) {
408-
if (pic_pin) {
409-
vm->arch_vm.vpic.vpin_to_pt_entry[virt_pin] = entry;
410-
} else {
411-
vm->arch_vm.vioapic.vpin_to_pt_entry[virt_pin] = entry;
412-
}
391+
/*
392+
* ptirq entry is either created or transferred from SOS VM to Post-launched VM
393+
*/
394+
if (entry != NULL) {
413395
dev_dbg(DBG_LEVEL_IRQ, "VM%d INTX add pin mapping vpin%d:ppin%d",
414396
entry->vm->vm_id, virt_pin, phys_pin);
415397
}
@@ -419,16 +401,17 @@ static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint3
419401
}
420402

421403
/* deactive & remove mapping entry of vpin for vm */
422-
static void remove_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, bool pic_pin)
404+
static void remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_pin, enum intx_ctlr vpin_ctlr)
423405
{
424406
uint32_t phys_irq;
425407
struct ptirq_remapping_info *entry;
426408
struct intr_source intr_src;
409+
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
427410

428-
if (((!pic_pin) && (virt_pin >= vioapic_pincount(vm))) || (pic_pin && (virt_pin >= vpic_pincount()))) {
411+
if (((vpin_ctlr == INTX_CTLR_IOAPIC) && (virt_pin >= vioapic_pincount(vm))) || ((vpin_ctlr == INTX_CTLR_PIC) && (virt_pin >= vpic_pincount()))) {
429412
pr_err("virtual irq pin is invalid!\n");
430413
} else {
431-
entry = ptirq_lookup_entry_by_vpin(vm, virt_pin, pic_pin);
414+
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
432415
if (entry != NULL) {
433416
if (is_entry_active(entry)) {
434417
phys_irq = entry->allocated_pirq;
@@ -442,18 +425,12 @@ static void remove_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, bool pi
442425
dmar_free_irte(intr_src, (uint16_t)phys_irq);
443426
dev_dbg(DBG_LEVEL_IRQ,
444427
"deactive %s intx entry:ppin=%d, pirq=%d ",
445-
pic_pin ? "vPIC" : "vIOAPIC",
428+
(vpin_ctlr == INTX_CTLR_PIC) ? "vPIC" : "vIOAPIC",
446429
entry->phys_sid.intx_id.pin, phys_irq);
447430
dev_dbg(DBG_LEVEL_IRQ, "from vm%d vpin=%d\n",
448431
entry->vm->vm_id, virt_pin);
449432
}
450433

451-
if (pic_pin) {
452-
vm->arch_vm.vpic.vpin_to_pt_entry[virt_pin] = NULL;
453-
} else {
454-
vm->arch_vm.vioapic.vpin_to_pt_entry[virt_pin] = NULL;
455-
}
456-
457434
ptirq_release_entry(entry);
458435
}
459436
}
@@ -560,9 +537,9 @@ void ptirq_intx_ack(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ctlr vpin_c
560537
{
561538
uint32_t phys_irq;
562539
struct ptirq_remapping_info *entry;
563-
bool pic_pin = (vpin_ctlr == INTX_CTLR_PIC);
540+
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
564541

565-
entry = ptirq_lookup_entry_by_vpin(vm, virt_pin, pic_pin);
542+
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
566543
if (entry != NULL) {
567544
phys_irq = entry->allocated_pirq;
568545

@@ -705,9 +682,8 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
705682
{
706683
int32_t status = 0;
707684
struct ptirq_remapping_info *entry = NULL;
708-
bool need_switch_vpin_ctlr = false;
709685
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
710-
bool pic_pin = (vpin_ctlr == INTX_CTLR_PIC);
686+
DEFINE_INTX_SID(alt_virt_sid, virt_pin, vpin_ctlr);
711687

712688
/*
713689
* virt pin could come from vpic master, vpic slave or vioapic
@@ -721,16 +697,10 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
721697
*/
722698

723699
/* no remap for vuart intx */
724-
if (is_vuart_intx(vm, virt_sid.intx_id.pin)) {
725-
status = -ENODEV;
726-
}
727-
728-
if ((status != 0) || (pic_pin && (virt_pin >= NR_VPIC_PINS_TOTAL))) {
729-
status = -EINVAL;
730-
} else {
700+
if (!is_vuart_intx(vm, virt_sid.intx_id.pin)) {
731701
/* query if we have virt to phys mapping */
732702
spinlock_obtain(&ptdev_lock);
733-
entry = ptirq_lookup_entry_by_vpin(vm, virt_pin, pic_pin);
703+
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
734704
if (entry == NULL) {
735705
if (is_sos_vm(vm)) {
736706

@@ -744,9 +714,23 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
744714
if (virt_pin < NR_LEGACY_PIN) {
745715
uint32_t vpin = get_pic_pin_from_ioapic_pin(virt_pin);
746716

747-
entry = ptirq_lookup_entry_by_vpin(vm, vpin, !pic_pin);
717+
if (vpin_ctlr == INTX_CTLR_PIC) {
718+
alt_virt_sid.intx_id.ctlr = INTX_CTLR_IOAPIC;
719+
} else {
720+
alt_virt_sid.intx_id.ctlr = INTX_CTLR_PIC;
721+
}
722+
alt_virt_sid.intx_id.pin = vpin;
723+
724+
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &alt_virt_sid, vm);
748725
if (entry != NULL) {
749-
need_switch_vpin_ctlr = true;
726+
entry->virt_sid.value = virt_sid.value;
727+
dev_dbg(DBG_LEVEL_IRQ,
728+
"IOAPIC pin=%hhu pirq=%u vpin=%d switch from %s to %s vpin=%d for vm%d",
729+
entry->phys_sid.intx_id.pin,
730+
entry->allocated_pirq, entry->virt_sid.intx_id.pin,
731+
(vpin_ctlr == INTX_CTLR_IOAPIC) ? "vPIC" : "vIOAPIC",
732+
(vpin_ctlr == INTX_CTLR_IOAPIC) ? "vIOPIC" : "vPIC",
733+
virt_pin, entry->vm->vm_id);
750734
}
751735
}
752736

@@ -755,10 +739,10 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
755739
uint32_t phys_pin = virt_pin;
756740

757741
/* fix vPIC pin to correct native IOAPIC pin */
758-
if (pic_pin) {
742+
if (vpin_ctlr == INTX_CTLR_PIC) {
759743
phys_pin = get_pic_pin_from_ioapic_pin(virt_pin);
760744
}
761-
entry = add_intx_remapping(vm, virt_pin, phys_pin, pic_pin);
745+
entry = add_intx_remapping(vm, virt_pin, phys_pin, vpin_ctlr);
762746
if (entry == NULL) {
763747
pr_err("%s, add intx remapping failed",
764748
__func__);
@@ -774,22 +758,11 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
774758
}
775759
}
776760
spinlock_release(&ptdev_lock);
761+
} else {
762+
status = -EINVAL;
777763
}
778764

779765
if (status == 0) {
780-
spinlock_obtain(&ptdev_lock);
781-
/* if vpin source need switch */
782-
if ((need_switch_vpin_ctlr) && (entry != NULL)) {
783-
dev_dbg(DBG_LEVEL_IRQ,
784-
"IOAPIC pin=%hhu pirq=%u vpin=%d switch from %s to %s vpin=%d for vm%d",
785-
entry->phys_sid.intx_id.pin,
786-
entry->allocated_pirq, entry->virt_sid.intx_id.pin,
787-
(vpin_ctlr == INTX_CTLR_IOAPIC) ? "vPIC" : "vIOAPIC",
788-
(vpin_ctlr == INTX_CTLR_IOAPIC) ? "vIOPIC" : "vPIC",
789-
virt_pin, entry->vm->vm_id);
790-
entry->virt_sid.value = virt_sid.value;
791-
}
792-
spinlock_release(&ptdev_lock);
793766
activate_physical_ioapic(vm, entry);
794767
}
795768

@@ -807,9 +780,10 @@ int32_t ptirq_intx_pin_remap(struct acrn_vm *vm, uint32_t virt_pin, enum intx_ct
807780
int32_t ptirq_add_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, uint32_t phys_pin, bool pic_pin)
808781
{
809782
struct ptirq_remapping_info *entry;
783+
enum intx_ctlr vpin_ctlr = pic_pin ? INTX_CTLR_PIC : INTX_CTLR_IOAPIC;
810784

811785
spinlock_obtain(&ptdev_lock);
812-
entry = add_intx_remapping(vm, virt_pin, phys_pin, pic_pin);
786+
entry = add_intx_remapping(vm, virt_pin, phys_pin, vpin_ctlr);
813787
spinlock_release(&ptdev_lock);
814788

815789
return (entry != NULL) ? 0 : -ENODEV;
@@ -818,10 +792,12 @@ int32_t ptirq_add_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, uint32_t
818792
/*
819793
* @pre vm != NULL
820794
*/
821-
void ptirq_remove_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, bool pic_pin)
795+
void ptirq_remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_pin, bool pic_pin)
822796
{
797+
enum intx_ctlr vpin_ctlr = pic_pin ? INTX_CTLR_PIC : INTX_CTLR_IOAPIC;
798+
823799
spinlock_obtain(&ptdev_lock);
824-
remove_intx_remapping(vm, virt_pin, pic_pin);
800+
remove_intx_remapping(vm, virt_pin, vpin_ctlr);
825801
spinlock_release(&ptdev_lock);
826802
}
827803

hypervisor/dm/vioapic.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ int32_t vioapic_mmio_access_handler(struct io_request *io_req, void *handler_pri
530530
* @pre vm->arch_vm.vioapic != NULL
531531
* @pre rte != NULL
532532
*/
533-
void vioapic_get_rte(struct acrn_vm *vm, uint32_t pin, union ioapic_rte *rte)
533+
void vioapic_get_rte(const struct acrn_vm *vm, uint32_t pin, union ioapic_rte *rte)
534534
{
535535
struct acrn_vioapic *vioapic;
536536

hypervisor/include/arch/x86/guest/assign.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ int32_t ptirq_add_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, uint32_t
122122
* @pre vm != NULL
123123
*
124124
*/
125-
void ptirq_remove_intx_remapping(struct acrn_vm *vm, uint32_t virt_pin, bool pic_pin);
125+
void ptirq_remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_pin, bool pic_pin);
126126

127127
/**
128128
* @brief Remove interrupt remapping entry/entries for MSI/MSI-x.

hypervisor/include/dm/vioapic.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242

4343
#define VIOAPIC_BASE 0xFEC00000UL
4444
#define VIOAPIC_SIZE 4096UL
45-
#define VIOAPIC_MAX_PIN 256U
4645

4746
#define REDIR_ENTRIES_HW 120U /* SOS align with native ioapic */
4847
#define STATE_BITMAP_SIZE INT_DIV_ROUNDUP(REDIR_ENTRIES_HW, 64U)
@@ -58,7 +57,6 @@ struct acrn_vioapic {
5857
union ioapic_rte rtbl[REDIR_ENTRIES_HW];
5958
/* pin_state status bitmap: 1 - high, 0 - low */
6059
uint64_t pin_state[STATE_BITMAP_SIZE];
61-
struct ptirq_remapping_info *vpin_to_pt_entry[VIOAPIC_MAX_PIN];
6260
};
6361

6462
void vioapic_init(struct acrn_vm *vm);
@@ -104,7 +102,7 @@ void vioapic_set_irqline_nolock(const struct acrn_vm *vm, uint32_t irqline, uint
104102

105103
uint32_t vioapic_pincount(const struct acrn_vm *vm);
106104
void vioapic_process_eoi(struct acrn_vm *vm, uint32_t vector);
107-
void vioapic_get_rte(struct acrn_vm *vm, uint32_t pin, union ioapic_rte *rte);
105+
void vioapic_get_rte(const struct acrn_vm *vm, uint32_t pin, union ioapic_rte *rte);
108106
int32_t vioapic_mmio_access_handler(struct io_request *io_req, void *handler_private_data);
109107

110108
/**

hypervisor/include/dm/vpic.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ struct acrn_vpic {
134134
struct acrn_vm *vm;
135135
spinlock_t lock;
136136
struct i8259_reg_state i8259[2];
137-
struct ptirq_remapping_info *vpin_to_pt_entry[NR_VPIC_PINS_TOTAL];
138137
};
139138

140139
void vpic_init(struct acrn_vm *vm);

0 commit comments

Comments
 (0)