Skip to content

Commit 2e60ade

Browse files
lifeixwenlingz
authored andcommitted
hv: vmcs: simplify update EOI-exit bitmap
1) The previous implementaion will recalculate the whole EOI-exit bitmap for each RTE once the destination, trigger mode, delivery mode or vector of a RTE has changed and update the EOI-exit bitmap for each vcpu of the VM. In this patch, only set the corresponding bit of EOI-exit bitmap for a vcpu when a level triggered interrupt has accepted in IRR or clear the corresponding bit of EOI-exit bitmap for a vcpu when a dege triggered interrupt has accepted in IRR which means only update a bit of EOI-exit bitmap in a vcpu when updating TMR. 2) Rename set eoi_exit related API to set eoi_exit_bitmap. Tracked-On: #1842 Signed-off-by: Li, Fei1 <fei1.li@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 501b3f7 commit 2e60ade

File tree

5 files changed

+47
-90
lines changed

5 files changed

+47
-90
lines changed

hypervisor/arch/x86/guest/vcpu.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,25 +149,36 @@ void vcpu_set_vmcs_eoi_exit(struct acrn_vcpu *vcpu)
149149
* called with vcpu->arch.lock held
150150
* @pre vcpu != NULL && vector <= 255U
151151
*/
152-
void vcpu_set_eoi_exit(struct acrn_vcpu *vcpu, uint32_t vector)
152+
void vcpu_set_eoi_exit_bitmap(struct acrn_vcpu *vcpu, uint32_t vector)
153153
{
154154
pr_dbg("%s", __func__);
155155

156-
if (bitmap_test_and_set_nolock((uint16_t)(vector & 0x3fU),
156+
if (!bitmap_test_and_set_nolock((uint16_t)(vector & 0x3fU),
157157
&(vcpu->arch.eoi_exit_bitmap[(vector & 0xffU) >> 6U]))) {
158-
pr_warn("Duplicated vector %u vcpu%u", vector, vcpu->vcpu_id);
158+
vcpu_make_request(vcpu, ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE);
159+
}
160+
}
161+
162+
void vcpu_clear_eoi_exit_bitmap(struct acrn_vcpu *vcpu, uint32_t vector)
163+
{
164+
pr_dbg("%s", __func__);
165+
166+
if (bitmap_test_and_clear_nolock((uint16_t)(vector & 0x3fU),
167+
&(vcpu->arch.eoi_exit_bitmap[(vector & 0xffU) >> 6U]))) {
168+
vcpu_make_request(vcpu, ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE);
159169
}
160170
}
161171

162172
/*
163173
* Reset all eoi_exit_bitmaps
164174
* called with vcpu->arch.lock held
165175
*/
166-
void vcpu_reset_eoi_exit_all(struct acrn_vcpu *vcpu)
176+
void vcpu_reset_eoi_exit_bitmaps(struct acrn_vcpu *vcpu)
167177
{
168178
pr_dbg("%s", __func__);
169179

170180
memset((void *)(vcpu->arch.eoi_exit_bitmap), 0U, sizeof(vcpu->arch.eoi_exit_bitmap));
181+
vcpu_make_request(vcpu, ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE);
171182
}
172183

173184
struct acrn_vcpu *get_ever_run_vcpu(uint16_t pcpu_id)

hypervisor/arch/x86/guest/virq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu)
454454
flush_vpid_single(arch->vpid);
455455
}
456456

457-
if (bitmap_test_and_clear_lock(ACRN_REQUEST_EOI_EXIT_UPDATE, pending_req_bits)) {
457+
if (bitmap_test_and_clear_lock(ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE, pending_req_bits)) {
458458
vcpu_set_vmcs_eoi_exit(vcpu);
459459
}
460460

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,13 @@ vlapic_set_tmr(struct acrn_vlapic *vlapic, uint32_t vector, bool level)
466466
lapic = &(vlapic->apic_page);
467467
tmrptr = &lapic->tmr[0];
468468
if (level) {
469-
bitmap32_set_lock((uint16_t)(vector & 0x1fU), &tmrptr[vector >> 5U].v);
469+
if (!bitmap32_test_and_set_lock((uint16_t)(vector & 0x1fU), &tmrptr[vector >> 5U].v)) {
470+
vcpu_set_eoi_exit_bitmap(vlapic->vcpu, vector);
471+
}
470472
} else {
471-
bitmap32_clear_lock((uint16_t)(vector & 0x1fU), &tmrptr[vector >> 5U].v);
473+
if (bitmap32_test_and_clear_lock((uint16_t)(vector & 0x1fU), &tmrptr[vector >> 5U].v)) {
474+
vcpu_clear_eoi_exit_bitmap(vlapic->vcpu, vector);
475+
}
472476
}
473477
}
474478

@@ -485,6 +489,8 @@ vlapic_reset_tmr(struct acrn_vlapic *vlapic)
485489
for (i = 0; i < 8; i++) {
486490
lapic->tmr[i].v = 0U;
487491
}
492+
493+
vcpu_reset_eoi_exit_bitmaps(vlapic->vcpu);
488494
}
489495

490496
/*

hypervisor/dm/vioapic.c

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -175,66 +175,6 @@ vioapic_set_irqline_lock(const struct acrn_vm *vm, uint32_t irqline, uint32_t op
175175
spinlock_release(&(vioapic->mtx));
176176
}
177177

178-
/*
179-
* Generate eoi_exit_bitmap and request each VCPU to update VMCS fields
180-
* To be called with vioapic->mtx
181-
* @pre vioapic != NULL
182-
*/
183-
static void
184-
vioapic_update_eoi_exit(const struct acrn_vioapic *vioapic)
185-
{
186-
struct acrn_vcpu *vcpu;
187-
union ioapic_rte rte;
188-
uint64_t mask;
189-
uint32_t vector, delmode, dest;
190-
uint32_t pin, pincount;
191-
uint16_t vcpu_id;
192-
bool level, phys;
193-
194-
dev_dbg(ACRN_DBG_IOAPIC, "%s", __func__);
195-
196-
/* clear old bitmap to generate new bitmap */
197-
foreach_vcpu(vcpu_id, vioapic->vm, vcpu) {
198-
spinlock_obtain(&(vcpu->arch.lock));
199-
vcpu_reset_eoi_exit_all(vcpu);
200-
}
201-
202-
/* go through RTEs and set corresponding bits of eoi_exit_bitmap */
203-
pincount = vioapic_pincount(vioapic->vm);
204-
for (pin = 0U; pin < pincount; pin++) {
205-
rte = vioapic->rtbl[pin];
206-
207-
level = (rte.bits.trigger_mode == IOAPIC_RTE_TRGRMODE_LEVEL);
208-
vector = rte.bits.vector;
209-
210-
if (level && ((vector >= 0x20U) && (vector < NR_MAX_VECTOR))) {
211-
/* if level-trigger and vector is valid */
212-
delmode = (uint32_t)rte.bits.delivery_mode;
213-
214-
if ((delmode != IOAPIC_RTE_DELMODE_FIXED) && (delmode != IOAPIC_RTE_DELMODE_LOPRI)) {
215-
dev_dbg(ACRN_DBG_IOAPIC,
216-
"Ignoring level trigger-mode for delivery-mode 0x%x", delmode);
217-
} else {
218-
dest = (uint32_t)rte.bits.dest_field;
219-
phys = (rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY);
220-
vlapic_calc_dest(vioapic->vm, &mask, dest, phys, false);
221-
222-
for (vcpu_id = ffs64(mask); vcpu_id != INVALID_BIT_INDEX; vcpu_id = ffs64(mask)) {
223-
vcpu = vcpu_from_vid(vioapic->vm, vcpu_id);
224-
vcpu_set_eoi_exit(vcpu, vector);
225-
bitmap_clear_nolock(vcpu_id, &mask);
226-
}
227-
}
228-
}
229-
}
230-
231-
/* make request if eoi_exit_bitmap changed */
232-
foreach_vcpu(vcpu_id, vioapic->vm, vcpu) {
233-
spinlock_release(&(vcpu->arch.lock));
234-
vcpu_make_request(vcpu, ACRN_REQUEST_EOI_EXIT_UPDATE);
235-
}
236-
}
237-
238178
static uint32_t
239179
vioapic_indirect_read(const struct acrn_vioapic *vioapic, uint32_t addr)
240180
{
@@ -377,17 +317,6 @@ static void vioapic_indirect_write(struct acrn_vioapic *vioapic, uint32_t addr,
377317
vioapic->rtbl[pin] = new;
378318
dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: redir table entry %#lx",
379319
pin, vioapic->rtbl[pin].full);
380-
/*
381-
* If "Trigger Mode" or "Delivery Mode" or "Vector"
382-
* in the redirection table entry have changed then
383-
* rendezvous all the vcpus to update their vlapic
384-
* trigger-mode registers.
385-
*/
386-
if ((changed.bits.vector != 0UL) || (changed.bits.delivery_mode != 0UL)
387-
|| (changed.bits.trigger_mode != 0UL) || (changed.bits.dest_field != 0UL)) {
388-
dev_dbg(ACRN_DBG_IOAPIC, "ioapic pin%hhu: recalculate vlapic trigger-mode reg", pin);
389-
vioapic_update_eoi_exit(vioapic);
390-
}
391320

392321
/*
393322
* Generate an interrupt if the following conditions are met:

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

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,14 @@
7171
/*
7272
* VCPU related APIs
7373
*/
74-
#define ACRN_REQUEST_EXCP 0U
75-
#define ACRN_REQUEST_EVENT 1U
76-
#define ACRN_REQUEST_EXTINT 2U
77-
#define ACRN_REQUEST_NMI 3U
78-
#define ACRN_REQUEST_EOI_EXIT_UPDATE 4U
79-
#define ACRN_REQUEST_EPT_FLUSH 5U
80-
#define ACRN_REQUEST_TRP_FAULT 6U
81-
#define ACRN_REQUEST_VPID_FLUSH 7U /* flush vpid tlb */
74+
#define ACRN_REQUEST_EXCP 0U
75+
#define ACRN_REQUEST_EVENT 1U
76+
#define ACRN_REQUEST_EXTINT 2U
77+
#define ACRN_REQUEST_NMI 3U
78+
#define ACRN_REQUEST_EOI_EXIT_BITMAP_UPDATE 4U
79+
#define ACRN_REQUEST_EPT_FLUSH 5U
80+
#define ACRN_REQUEST_TRP_FAULT 6U
81+
#define ACRN_REQUEST_VPID_FLUSH 7U /* flush vpid tlb */
8282

8383
#define save_segment(seg, SEG_NAME) \
8484
{ \
@@ -503,14 +503,14 @@ void vcpu_set_guest_msr(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val);
503503
void vcpu_set_vmcs_eoi_exit(struct acrn_vcpu *vcpu);
504504

505505
/**
506-
* @brief reset eoi_exit_bitmap
506+
* @brief reset all eoi_exit_bitmaps
507507
*
508508
* @param[in] vcpu pointer to vcpu data structure
509509
*
510510
* @return void
511511
*/
512512

513-
void vcpu_reset_eoi_exit_all(struct acrn_vcpu *vcpu);
513+
void vcpu_reset_eoi_exit_bitmaps(struct acrn_vcpu *vcpu);
514514

515515
/**
516516
* @brief set eoi_exit_bitmap bit
@@ -520,9 +520,20 @@ void vcpu_reset_eoi_exit_all(struct acrn_vcpu *vcpu);
520520
* @param[in] vcpu pointer to vcpu data structure
521521
* @param[in] vector
522522
*
523-
* @return void
523+
* @return void
524+
*/
525+
void vcpu_set_eoi_exit_bitmap(struct acrn_vcpu *vcpu, uint32_t vector);
526+
/**
527+
* @brief clear eoi_exit_bitmap bit
528+
*
529+
* Clear corresponding bit of vector in eoi_exit_bitmap
530+
*
531+
* @param[in] vcpu pointer to vcpu data structure
532+
* @param[in] vector
533+
*
534+
* @return void
524535
*/
525-
void vcpu_set_eoi_exit(struct acrn_vcpu *vcpu, uint32_t vector);
536+
void vcpu_clear_eoi_exit_bitmap(struct acrn_vcpu *vcpu, uint32_t vector);
526537
/**
527538
* @brief set all the vcpu registers
528539
*

0 commit comments

Comments
 (0)