Skip to content

Commit 538ba08

Browse files
mingqiangchilijinxia
authored andcommitted
hv:Add vpin to ptdev entry mapping for vpic/vioapic
Now if the vmexit reason is virtulized EOI for level triggered interrupts, HV will loop all the ptdev entries, it is time-consuming, this patch add vpin to ptdev entry mapping for vpic and vioapic when add intx entry for a vm,it can use the ptdev entry directly according to the mapping for vpin and ptdev entry when EOI vmexit. v3-->v4: -- add check vpin in remove_intx_remapping -- move check vpin from ptdev_add_intx_remapping to add_intx_remapping Tracked-On: #861 Signed-off-by: Mingqiang Chi <mingqiang.chi@intel.com> Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com> Reviewed-by: Binbin Wu <binbin.wu@intel.com> Reviewed-by: Eddie Dong <eddie.dong@intel.com>
1 parent 297a264 commit 538ba08

File tree

5 files changed

+57
-32
lines changed

5 files changed

+57
-32
lines changed

hypervisor/arch/x86/assign.c

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ ptdev_lookup_entry_by_sid(uint32_t intr_type,
3939
return NULL;
4040
}
4141

42+
static inline struct ptdev_remapping_info *
43+
ptdev_lookup_entry_by_vpin(struct acrn_vm *vm, uint8_t virt_pin, bool pic_pin)
44+
{
45+
struct ptdev_remapping_info *entry;
46+
47+
if (pic_pin) {
48+
entry = vm->arch_vm.vpic.vpin_to_pt_entry[virt_pin];
49+
} else {
50+
entry = vm->arch_vm.vioapic.vpin_to_pt_entry[virt_pin];
51+
}
52+
return entry;
53+
}
54+
4255
#ifdef HV_DEBUG
4356
static bool ptdev_hv_owned_intx(const struct acrn_vm *vm, const union source_id *virt_sid)
4457
{
@@ -277,14 +290,20 @@ static struct ptdev_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint8
277290
DEFINE_IOAPIC_SID(virt_sid, virt_pin, vpin_src);
278291
uint32_t phys_irq = pin_to_irq(phys_pin);
279292

293+
if ((!pic_pin && virt_pin >= vioapic_pincount(vm))
294+
|| (pic_pin && virt_pin >= vpic_pincount())) {
295+
pr_err("ptdev_add_intx_remapping fails!\n");
296+
return NULL;
297+
}
298+
280299
if (!irq_is_gsi(phys_irq)) {
281300
pr_err("%s, invalid phys_pin: %d <-> irq: 0x%x is not a GSI\n", __func__, phys_pin, phys_irq);
282301
return NULL;
283302
}
284303

285304
entry = ptdev_lookup_entry_by_sid(PTDEV_INTR_INTX, &phys_sid, NULL);
286305
if (entry == NULL) {
287-
if (ptdev_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm) != NULL) {
306+
if (ptdev_lookup_entry_by_vpin(vm, virt_pin, pic_pin) != NULL) {
288307
pr_err("INTX re-add vpin %d", virt_pin);
289308
return NULL;
290309
}
@@ -314,26 +333,33 @@ static struct ptdev_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint8
314333
* required. */
315334
}
316335

317-
dev_dbg(ACRN_DBG_IRQ, "VM%d INTX add pin mapping vpin%d:ppin%d", vm->vm_id, virt_pin, phys_pin);
336+
if (pic_pin) {
337+
vm->arch_vm.vpic.vpin_to_pt_entry[virt_pin] = entry;
338+
} else {
339+
vm->arch_vm.vioapic.vpin_to_pt_entry[virt_pin] = entry;
340+
}
341+
342+
dev_dbg(ACRN_DBG_IRQ, "VM%d INTX add pin mapping vpin%d:ppin%d", entry->vm->vm_id, virt_pin, phys_pin);
318343

319344
return entry;
320345
}
321346

322347
/* deactive & remove mapping entry of vpin for vm */
323-
static void remove_intx_remapping(const struct acrn_vm *vm, uint8_t virt_pin, bool pic_pin)
348+
static void remove_intx_remapping(struct acrn_vm *vm, uint8_t virt_pin, bool pic_pin)
324349
{
325350
uint32_t phys_irq;
326351
struct ptdev_remapping_info *entry;
327-
enum ptdev_vpin_source vpin_src =
328-
pic_pin ? PTDEV_VPIN_PIC : PTDEV_VPIN_IOAPIC;
329-
DEFINE_IOAPIC_SID(virt_sid, virt_pin, vpin_src);
330352

353+
if ((!pic_pin && virt_pin >= vioapic_pincount(vm))
354+
|| (pic_pin && virt_pin >= vpic_pincount())) {
355+
pr_err("virtual irq pin is invalid!\n");
356+
return;
357+
}
331358

332-
entry = ptdev_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
359+
entry = ptdev_lookup_entry_by_vpin(vm, virt_pin, pic_pin);
333360
if (entry == NULL) {
334361
return;
335362
}
336-
337363
if (is_entry_active(entry)) {
338364
phys_irq = entry->allocated_pirq;
339365
/* disable interrupt */
@@ -342,13 +368,18 @@ static void remove_intx_remapping(const struct acrn_vm *vm, uint8_t virt_pin, bo
342368
ptdev_deactivate_entry(entry);
343369
dev_dbg(ACRN_DBG_IRQ,
344370
"deactive %s intx entry:ppin=%d, pirq=%d ",
345-
vpin_src == PTDEV_VPIN_PIC ?
346-
"vPIC" : "vIOAPIC",
371+
pic_pin ? "vPIC" : "vIOAPIC",
347372
entry->phys_sid.intx_id.pin, phys_irq);
348373
dev_dbg(ACRN_DBG_IRQ, "from vm%d vpin=%d\n",
349374
entry->vm->vm_id, virt_pin);
350375
}
351376

377+
if (pic_pin) {
378+
vm->arch_vm.vpic.vpin_to_pt_entry[virt_pin] = NULL;
379+
} else {
380+
vm->arch_vm.vioapic.vpin_to_pt_entry[virt_pin] = NULL;
381+
}
382+
352383
release_entry(entry);
353384
}
354385

@@ -464,9 +495,9 @@ void ptdev_intx_ack(struct acrn_vm *vm, uint8_t virt_pin,
464495
{
465496
uint32_t phys_irq;
466497
struct ptdev_remapping_info *entry;
467-
DEFINE_IOAPIC_SID(virt_sid, virt_pin, vpin_src);
498+
bool pic_pin = (vpin_src == PTDEV_VPIN_PIC);
468499

469-
entry = ptdev_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
500+
entry = ptdev_lookup_entry_by_vpin(vm, virt_pin, pic_pin);
470501
if (entry == NULL) {
471502
return;
472503
}
@@ -600,6 +631,7 @@ int ptdev_intx_pin_remap(struct acrn_vm *vm, uint8_t virt_pin,
600631
struct ptdev_remapping_info *entry;
601632
bool need_switch_vpin_src = false;
602633
DEFINE_IOAPIC_SID(virt_sid, virt_pin, vpin_src);
634+
bool pic_pin = (vpin_src == PTDEV_VPIN_PIC);
603635

604636
/*
605637
* virt pin could come from vpic master, vpic slave or vioapic
@@ -620,10 +652,9 @@ int ptdev_intx_pin_remap(struct acrn_vm *vm, uint8_t virt_pin,
620652
#endif
621653
/* query if we have virt to phys mapping */
622654
spinlock_obtain(&ptdev_lock);
623-
entry = ptdev_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
655+
entry = ptdev_lookup_entry_by_vpin(vm, virt_pin, pic_pin);
624656
if (entry == NULL) {
625657
if (is_vm0(vm)) {
626-
bool pic_pin = (vpin_src == PTDEV_VPIN_PIC);
627658

628659
/* for vm0, there is chance of vpin source switch
629660
* between vPIC & vIOAPIC for one legacy phys_pin.
@@ -633,12 +664,9 @@ int ptdev_intx_pin_remap(struct acrn_vm *vm, uint8_t virt_pin,
633664
* switch vpin source is needed
634665
*/
635666
if (virt_pin < NR_LEGACY_PIN) {
636-
DEFINE_IOAPIC_SID(tmp_vsid,
637-
pic_ioapic_pin_map[virt_pin],
638-
pic_pin ? PTDEV_VPIN_IOAPIC :
639-
PTDEV_VPIN_PIC);
640-
entry = ptdev_lookup_entry_by_sid(
641-
PTDEV_INTR_INTX, &tmp_vsid, vm);
667+
uint8_t vpin = pic_ioapic_pin_map[virt_pin];
668+
669+
entry = ptdev_lookup_entry_by_vpin(vm, vpin, !pic_pin);
642670
if (entry != NULL) {
643671
need_switch_vpin_src = true;
644672
}
@@ -707,12 +735,6 @@ int ptdev_add_intx_remapping(struct acrn_vm *vm, uint8_t virt_pin, uint8_t phys_
707735
{
708736
struct ptdev_remapping_info *entry;
709737

710-
if ((!pic_pin && virt_pin >= vioapic_pincount(vm))
711-
|| (pic_pin && virt_pin >= vpic_pincount())) {
712-
pr_err("ptdev_add_intx_remapping fails!\n");
713-
return -EINVAL;
714-
}
715-
716738
spinlock_obtain(&ptdev_lock);
717739
entry = add_intx_remapping(vm, virt_pin, phys_pin, pic_pin);
718740
spinlock_release(&ptdev_lock);
@@ -723,7 +745,7 @@ int ptdev_add_intx_remapping(struct acrn_vm *vm, uint8_t virt_pin, uint8_t phys_
723745
/*
724746
* @pre vm != NULL
725747
*/
726-
void ptdev_remove_intx_remapping(const struct acrn_vm *vm, uint8_t virt_pin, bool pic_pin)
748+
void ptdev_remove_intx_remapping(struct acrn_vm *vm, uint8_t virt_pin, bool pic_pin)
727749
{
728750
spinlock_obtain(&ptdev_lock);
729751
remove_intx_remapping(vm, virt_pin, pic_pin);

hypervisor/dm/vpic.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@
3131

3232
#define ACRN_DBG_PIC 6U
3333

34-
#define NR_VPIC_PINS_PER_CHIP 8U
35-
#define NR_VPIC_PINS_TOTAL 16U
36-
#define VPIC_INVALID_PIN 0xffU
37-
3834
static void vpic_set_pinstate(struct acrn_vpic *vpic, uint8_t pin, uint8_t level);
3935

4036
static inline bool master_pic(const struct acrn_vpic *vpic, struct i8259_reg_state *i8259)

hypervisor/include/arch/x86/assign.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ int ptdev_add_intx_remapping(struct acrn_vm *vm, uint8_t virt_pin, uint8_t phys_
119119
* @pre vm != NULL
120120
*
121121
*/
122-
void ptdev_remove_intx_remapping(const struct acrn_vm *vm, uint8_t virt_pin, bool pic_pin);
122+
void ptdev_remove_intx_remapping(struct acrn_vm *vm, uint8_t virt_pin, bool pic_pin);
123123

124124
/**
125125
* @brief Add interrupt remapping entry/entries for MSI/MSI-x as pre-hold mapping.

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#define VIOAPIC_BASE 0xFEC00000UL
4343
#define VIOAPIC_SIZE 4096UL
44+
#define VIOAPIC_MAX_PIN 256U
4445

4546
#define REDIR_ENTRIES_HW 120U /* SOS align with native ioapic */
4647
#define STATE_BITMAP_SIZE INT_DIV_ROUNDUP(REDIR_ENTRIES_HW, 64U)
@@ -53,6 +54,7 @@ struct acrn_vioapic {
5354
union ioapic_rte rtbl[REDIR_ENTRIES_HW];
5455
/* pin_state status bitmap: 1 - high, 0 - low */
5556
uint64_t pin_state[STATE_BITMAP_SIZE];
57+
struct ptdev_remapping_info *vpin_to_pt_entry[VIOAPIC_MAX_PIN];
5658
};
5759

5860
void vioapic_init(struct acrn_vm *vm);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@
9292
#define IO_ELCR1 0x4d0U
9393
#define IO_ELCR2 0x4d1U
9494

95+
#define NR_VPIC_PINS_PER_CHIP 8U
96+
#define NR_VPIC_PINS_TOTAL 16U
97+
#define VPIC_INVALID_PIN 0xffU
98+
9599
enum vpic_trigger {
96100
EDGE_TRIGGER,
97101
LEVEL_TRIGGER
@@ -124,6 +128,7 @@ struct acrn_vpic {
124128
struct acrn_vm *vm;
125129
spinlock_t lock;
126130
struct i8259_reg_state i8259[2];
131+
struct ptdev_remapping_info *vpin_to_pt_entry[NR_VPIC_PINS_TOTAL];
127132
};
128133

129134
void vpic_init(struct acrn_vm *vm);

0 commit comments

Comments
 (0)