hv: Add two vlapic APIs

Sometimes HV would like to know if there are specific interrupt
pending in vIRR, and clears them if necessary (such as in x86_tee case).

This patch adds two APIs: get_next_pending_intr and clear_pending_intr.
This patch also moves the inline api prio() from
vlapic.c to vlapic.h

v3:
    Remove apicv_get_next_pending_intr and apicv_clear_pending_intr
    and use vlapic_get_next_pending_intr and vlapic_clear_pending_intr
    directly.

v2:
    get_pending_intr -> get_next_pending_intr
    apicv_basic/advanced_clear_pending_intr -> apicv_clear_pending_intr
    apicv_basic/advanced_get_pending_intr -> apicv_get_next_pending_intr
    has_pending_intr kept

Tracked-On: #6571
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Wang, Yu1 <yu1.wang@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
Yifan Liu 2021-12-02 09:18:03 +00:00 committed by wenlingz
parent 1d831cd3a2
commit 702a71639f
2 changed files with 31 additions and 7 deletions

View File

@ -51,11 +51,6 @@
#define VLAPIC_VERBOS 0
static inline uint32_t prio(uint32_t x)
{
return (x >> 4U);
}
#define VLAPIC_VERSION (16U)
#define APICBASE_BSP 0x00000100UL
#define APICBASE_X2APIC 0x00000400UL
@ -2342,14 +2337,19 @@ bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
return vlapic->ops->has_pending_delivery_intr(vcpu);
}
static bool apicv_basic_has_pending_intr(struct acrn_vcpu *vcpu)
uint32_t vlapic_get_next_pending_intr(struct acrn_vcpu *vcpu)
{
struct acrn_vlapic *vlapic = vcpu_vlapic(vcpu);
uint32_t vector;
vector = vlapic_find_highest_irr(vlapic);
return vector != 0UL;
return vector;
}
static bool apicv_basic_has_pending_intr(struct acrn_vcpu *vcpu)
{
return vlapic_get_next_pending_intr(vcpu) != 0UL;
}
static bool apicv_advanced_has_pending_intr(struct acrn_vcpu *vcpu)
@ -2357,6 +2357,13 @@ static bool apicv_advanced_has_pending_intr(struct acrn_vcpu *vcpu)
return apicv_basic_has_pending_intr(vcpu);
}
bool vlapic_clear_pending_intr(struct acrn_vcpu *vcpu, uint32_t vector)
{
struct lapic_reg *irrptr = &(vcpu->arch.vlapic.apic_page.irr[0]);
uint32_t idx = vector >> 5U;
return bitmap32_test_and_clear_lock((uint16_t)(vector & 0x1fU), &irrptr[idx].v);
}
bool vlapic_has_pending_intr(struct acrn_vcpu *vcpu)
{
struct acrn_vlapic *vlapic = vcpu_vlapic(vcpu);

View File

@ -114,6 +114,18 @@ void vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool
bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu);
bool vlapic_has_pending_intr(struct acrn_vcpu *vcpu);
/**
* Returns the highest priority pending vector on vLAPIC, or
* 0 if there is no pending vector.
*/
uint32_t vlapic_get_next_pending_intr(struct acrn_vcpu *vcpu);
/**
* Clears a pending vector from vIRR. Returns true if
* the bit was previously present, false otherwise.
*/
bool vlapic_clear_pending_intr(struct acrn_vcpu *vcpu, uint32_t vector);
uint64_t vlapic_get_tsc_deadline_msr(const struct acrn_vlapic *vlapic);
void vlapic_set_tsc_deadline_msr(struct acrn_vlapic *vlapic, uint64_t val_arg);
uint64_t vlapic_get_apicbase(const struct acrn_vlapic *vlapic);
@ -132,6 +144,11 @@ void vlapic_set_intr(struct acrn_vcpu *vcpu, uint32_t vector, bool level);
#define LAPIC_TRIG_LEVEL true
#define LAPIC_TRIG_EDGE false
static inline uint32_t prio(uint32_t x)
{
return (x >> 4U);
}
/**
* @brief Triggers LAPIC local interrupt(LVT).
*