mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 20:53:46 +00:00
hv: revise interfaces description in vlapic
Add comments for APIs: - vlapic_pending_intr(); - vlapic_pending_accepted(); - vlapic_post_intr(); - lapicv_get_pir_desc_paddr(); - vlapic_intr_level(); - vlapic_intr_edge(); - vlapic_set_local_intr(); - vlapic_intr_msi(); Tracked-On: #1595 Signed-off-by: Yonghua Huang <yonghua.huang@intel.com>
This commit is contained in:
parent
469496311c
commit
c41f286085
@ -531,12 +531,35 @@ vlapic_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector, bool level)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Post an interrupt to the vcpu running on 'hostcpu'. */
|
/**
|
||||||
|
* @brief Send notification vector to target pCPU.
|
||||||
|
*
|
||||||
|
* If APICv Posted-Interrupt is enabled and target pCPU is in non-root mode,
|
||||||
|
* pCPU will sync pending virtual interrupts from PIR to vIRR automatically,
|
||||||
|
* without VM exit.
|
||||||
|
* If pCPU in root-mode, virtual interrupt will be injected in next VM entry.
|
||||||
|
*
|
||||||
|
* @param[in] dest_pcpu_id Target CPU ID.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
void vlapic_post_intr(uint16_t dest_pcpu_id)
|
void vlapic_post_intr(uint16_t dest_pcpu_id)
|
||||||
{
|
{
|
||||||
send_single_ipi(dest_pcpu_id, VECTOR_POSTED_INTR);
|
send_single_ipi(dest_pcpu_id, VECTOR_POSTED_INTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get physical address to PIR description.
|
||||||
|
*
|
||||||
|
* If APICv Posted-interrupt is supported, this address will be configured
|
||||||
|
* to VMCS "Posted-interrupt descriptor address" field.
|
||||||
|
*
|
||||||
|
* @param[in] vcpu Target vCPU
|
||||||
|
*
|
||||||
|
* @return physicall address to PIR
|
||||||
|
*
|
||||||
|
* @pre vcpu != NULL
|
||||||
|
*/
|
||||||
uint64_t apicv_get_pir_desc_paddr(struct vcpu *vcpu)
|
uint64_t apicv_get_pir_desc_paddr(struct vcpu *vcpu)
|
||||||
{
|
{
|
||||||
struct acrn_vlapic *vlapic;
|
struct acrn_vlapic *vlapic;
|
||||||
@ -1286,6 +1309,19 @@ vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
|
|||||||
return 0; /* handled completely in the kernel */
|
return 0; /* handled completely in the kernel */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get pending virtual interrupts for vLAPIC.
|
||||||
|
*
|
||||||
|
* @param[in] vlapic Pointer to target vLAPIC data structure
|
||||||
|
* @param[inout] vecptr Pointer to vector buffer and will be filled
|
||||||
|
* with eligible vector if any.
|
||||||
|
*
|
||||||
|
* @return 0 - There is no eligible pending vector.
|
||||||
|
* @return 1 - There is pending vector.
|
||||||
|
*
|
||||||
|
* @remark The vector does not automatically transition to the ISR as a
|
||||||
|
* result of calling this function.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
vlapic_pending_intr(const struct acrn_vlapic *vlapic, uint32_t *vecptr)
|
vlapic_pending_intr(const struct acrn_vlapic *vlapic, uint32_t *vecptr)
|
||||||
{
|
{
|
||||||
@ -1318,6 +1354,21 @@ vlapic_pending_intr(const struct acrn_vlapic *vlapic, uint32_t *vecptr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Accept virtual interrupt.
|
||||||
|
*
|
||||||
|
* Transition 'vector' from IRR to ISR. This function is called with the
|
||||||
|
* vector returned by 'vlapic_pending_intr()' when the guest is able to
|
||||||
|
* accept this interrupt (i.e. RFLAGS.IF = 1 and no conditions exist that
|
||||||
|
* block interrupt delivery).
|
||||||
|
*
|
||||||
|
* @param[in] vlapic Pointer to target vLAPIC data structure
|
||||||
|
* @param[in] vector Target virtual interrupt vector
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @pre vlapic != NULL
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
vlapic_intr_accepted(struct acrn_vlapic *vlapic, uint32_t vector)
|
vlapic_intr_accepted(struct acrn_vlapic *vlapic, uint32_t vector)
|
||||||
{
|
{
|
||||||
@ -1879,17 +1930,12 @@ int
|
|||||||
vlapic_set_intr(struct vcpu *vcpu, uint32_t vector, bool level)
|
vlapic_set_intr(struct vcpu *vcpu, uint32_t vector, bool level)
|
||||||
{
|
{
|
||||||
struct acrn_vlapic *vlapic;
|
struct acrn_vlapic *vlapic;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (vcpu == NULL) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* According to section "Maskable Hardware Interrupts" in Intel SDM
|
* According to section "Maskable Hardware Interrupts" in Intel SDM
|
||||||
* vectors 16 through 255 can be delivered through the local APIC.
|
* vectors 16 through 255 can be delivered through the local APIC.
|
||||||
*/
|
*/
|
||||||
if (vector > 255U) {
|
if ((vcpu == NULL) || (vector > 255U)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1905,9 +1951,22 @@ vlapic_set_intr(struct vcpu *vcpu, uint32_t vector, bool level)
|
|||||||
vcpu_make_request(vcpu, ACRN_REQUEST_EVENT);
|
vcpu_make_request(vcpu, ACRN_REQUEST_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Triggers LAPIC local interrupt(LVT).
|
||||||
|
*
|
||||||
|
* @param[in] vm Pointer to VM data structure
|
||||||
|
* @param[in] vcpu_id_arg ID of vCPU, BROADCAST_CPU_ID means triggering
|
||||||
|
* interrupt to all vCPUs.
|
||||||
|
* @param[in] vector Vector to be fired.
|
||||||
|
*
|
||||||
|
* @return 0 on success.
|
||||||
|
* @return -EINVAL on error that vcpu_id_arg or vector is invalid.
|
||||||
|
*
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
vlapic_set_local_intr(struct vm *vm, uint16_t vcpu_id_arg, uint32_t vector)
|
vlapic_set_local_intr(struct vm *vm, uint16_t vcpu_id_arg, uint32_t vector)
|
||||||
{
|
{
|
||||||
@ -1939,6 +1998,18 @@ vlapic_set_local_intr(struct vm *vm, uint16_t vcpu_id_arg, uint32_t vector)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inject MSI to target VM.
|
||||||
|
*
|
||||||
|
* @param[in] vm Pointer to VM data structure
|
||||||
|
* @param[in] addr MSI address.
|
||||||
|
* @param[in] msg MSI data.
|
||||||
|
*
|
||||||
|
* @return 0 on success.
|
||||||
|
* @return non-zero on error that addr is invalid.
|
||||||
|
*
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
vlapic_intr_msi(struct vm *vm, uint64_t addr, uint64_t msg)
|
vlapic_intr_msi(struct vm *vm, uint64_t addr, uint64_t msg)
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,14 @@
|
|||||||
#ifndef VLAPIC_H
|
#ifndef VLAPIC_H
|
||||||
#define VLAPIC_H
|
#define VLAPIC_H
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file vlapic.h
|
||||||
|
*
|
||||||
|
* @brief public APIs for virtual LAPIC
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 16 priority levels with at most one vector injected per level.
|
* 16 priority levels with at most one vector injected per level.
|
||||||
*/
|
*/
|
||||||
@ -103,26 +111,72 @@ struct acrn_vlapic {
|
|||||||
void vlapic_set_cr8(struct acrn_vlapic *vlapic, uint64_t val);
|
void vlapic_set_cr8(struct acrn_vlapic *vlapic, uint64_t val);
|
||||||
uint64_t vlapic_get_cr8(const struct acrn_vlapic *vlapic);
|
uint64_t vlapic_get_cr8(const struct acrn_vlapic *vlapic);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Returns 0 if there is no eligible vector that can be delivered to the
|
* @brief virtual LAPIC
|
||||||
* guest at this time and non-zero otherwise.
|
|
||||||
*
|
*
|
||||||
* If an eligible vector number is found and 'vecptr' is not NULL then it will
|
* @addtogroup acrn_vlapic ACRN vLAPIC
|
||||||
* be stored in the location pointed to by 'vecptr'.
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get pending virtual interrupts for vLAPIC.
|
||||||
*
|
*
|
||||||
* Note that the vector does not automatically transition to the ISR as a
|
* @param[in] vlapic Pointer to target vLAPIC data structure
|
||||||
* result of calling this function.
|
* @param[inout] vecptr Pointer to vector buffer and will be filled
|
||||||
|
* with eligible vector if any.
|
||||||
|
*
|
||||||
|
* @return 0 - There is no eligible pending vector.
|
||||||
|
* @return 1 - There is pending vector.
|
||||||
|
*
|
||||||
|
* @remark The vector does not automatically transition to the ISR as a
|
||||||
|
* result of calling this function.
|
||||||
*/
|
*/
|
||||||
int vlapic_pending_intr(const struct acrn_vlapic *vlapic, uint32_t *vecptr);
|
int vlapic_pending_intr(const struct acrn_vlapic *vlapic, uint32_t *vecptr);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* @brief Accept virtual interrupt.
|
||||||
|
*
|
||||||
* Transition 'vector' from IRR to ISR. This function is called with the
|
* Transition 'vector' from IRR to ISR. This function is called with the
|
||||||
* vector returned by 'vlapic_pending_intr()' when the guest is able to
|
* vector returned by 'vlapic_pending_intr()' when the guest is able to
|
||||||
* accept this interrupt (i.e. RFLAGS.IF = 1 and no conditions exist that
|
* accept this interrupt (i.e. RFLAGS.IF = 1 and no conditions exist that
|
||||||
* block interrupt delivery).
|
* block interrupt delivery).
|
||||||
|
*
|
||||||
|
* @param[in] vlapic Pointer to target vLAPIC data structure
|
||||||
|
* @param[in] vector Target virtual interrupt vector
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @pre vlapic != NULL
|
||||||
*/
|
*/
|
||||||
void vlapic_intr_accepted(struct acrn_vlapic *vlapic, uint32_t vector);
|
void vlapic_intr_accepted(struct acrn_vlapic *vlapic, uint32_t vector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send notification vector to target pCPU.
|
||||||
|
*
|
||||||
|
* If APICv Posted-Interrupt is enabled and target pCPU is in non-root mode,
|
||||||
|
* pCPU will sync pending virtual interrupts from PIR to vIRR automatically,
|
||||||
|
* without VM exit.
|
||||||
|
* If pCPU in root-mode, virtual interrupt will be injected in next VM entry.
|
||||||
|
*
|
||||||
|
* @param[in] dest_pcpu_id Target CPU ID.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
void vlapic_post_intr(uint16_t dest_pcpu_id);
|
void vlapic_post_intr(uint16_t dest_pcpu_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get physical address to PIR description.
|
||||||
|
*
|
||||||
|
* If APICv Posted-interrupt is supported, this address will be configured
|
||||||
|
* to VMCS "Posted-interrupt descriptor address" field.
|
||||||
|
*
|
||||||
|
* @param[in] vcpu Target vCPU
|
||||||
|
*
|
||||||
|
* @return physicall address to PIR
|
||||||
|
*
|
||||||
|
* @pre vcpu != NULL
|
||||||
|
*/
|
||||||
uint64_t apicv_get_pir_desc_paddr(struct vcpu *vcpu);
|
uint64_t apicv_get_pir_desc_paddr(struct vcpu *vcpu);
|
||||||
|
|
||||||
int vlapic_rdmsr(struct vcpu *vcpu, uint32_t msr, uint64_t *rval);
|
int vlapic_rdmsr(struct vcpu *vcpu, uint32_t msr, uint64_t *rval);
|
||||||
@ -136,24 +190,63 @@ int vlapic_set_intr(struct vcpu *vcpu, uint32_t vector, bool level);
|
|||||||
|
|
||||||
#define LAPIC_TRIG_LEVEL true
|
#define LAPIC_TRIG_LEVEL true
|
||||||
#define LAPIC_TRIG_EDGE false
|
#define LAPIC_TRIG_EDGE false
|
||||||
|
/**
|
||||||
|
* @brief Pend level-trigger mode virtual interrupt to vCPU.
|
||||||
|
*
|
||||||
|
* @param[in] vcpu Pointer to target vCPU data structure
|
||||||
|
* @param[in] vector Vector to be injected.
|
||||||
|
*
|
||||||
|
* @return 0 on success.
|
||||||
|
* @return -EINVAL on error that vector is invalid or vcpu is NULL.
|
||||||
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
vlapic_intr_level(struct vcpu *vcpu, uint32_t vector)
|
vlapic_intr_level(struct vcpu *vcpu, uint32_t vector)
|
||||||
{
|
{
|
||||||
return vlapic_set_intr(vcpu, vector, LAPIC_TRIG_LEVEL);
|
return vlapic_set_intr(vcpu, vector, LAPIC_TRIG_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Pend edge-trigger mode virtual interrupt to vCPU.
|
||||||
|
*
|
||||||
|
* @param[in] vcpu Pointer to target vCPU data structure
|
||||||
|
* @param[in] vector Vector to be injected.
|
||||||
|
*
|
||||||
|
* @return 0 on success.
|
||||||
|
* @return -EINVAL on error that vector is invalid or vcpu is NULL.
|
||||||
|
*/
|
||||||
static inline int
|
static inline int
|
||||||
vlapic_intr_edge(struct vcpu *vcpu, uint32_t vector)
|
vlapic_intr_edge(struct vcpu *vcpu, uint32_t vector)
|
||||||
{
|
{
|
||||||
return vlapic_set_intr(vcpu, vector, LAPIC_TRIG_EDGE);
|
return vlapic_set_intr(vcpu, vector, LAPIC_TRIG_EDGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Triggers the LAPIC local interrupt (LVT) 'vector' on 'cpu'. 'cpu' can
|
* @brief Triggers LAPIC local interrupt(LVT).
|
||||||
* be set to -1 to trigger the interrupt on all CPUs.
|
*
|
||||||
|
* @param[in] vm Pointer to VM data structure
|
||||||
|
* @param[in] vcpu_id_arg ID of vCPU, BROADCAST_CPU_ID means triggering
|
||||||
|
* interrupt to all vCPUs.
|
||||||
|
* @param[in] vector Vector to be fired.
|
||||||
|
*
|
||||||
|
* @return 0 on success.
|
||||||
|
* @return -EINVAL on error that vcpu_id_arg or vector is invalid.
|
||||||
|
*
|
||||||
|
* @pre vm != NULL
|
||||||
*/
|
*/
|
||||||
int vlapic_set_local_intr(struct vm *vm, uint16_t vcpu_id_arg, uint32_t vector);
|
int vlapic_set_local_intr(struct vm *vm, uint16_t vcpu_id_arg, uint32_t vector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inject MSI to target VM.
|
||||||
|
*
|
||||||
|
* @param[in] vm Pointer to VM data structure
|
||||||
|
* @param[in] addr MSI address.
|
||||||
|
* @param[in] msg MSI data.
|
||||||
|
*
|
||||||
|
* @return 0 on success.
|
||||||
|
* @return non-zero on error that addr is invalid.
|
||||||
|
*
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
int vlapic_intr_msi(struct vm *vm, uint64_t addr, uint64_t msg);
|
int vlapic_intr_msi(struct vm *vm, uint64_t addr, uint64_t msg);
|
||||||
|
|
||||||
void vlapic_deliver_intr(struct vm *vm, bool level, uint32_t dest,
|
void vlapic_deliver_intr(struct vm *vm, bool level, uint32_t dest,
|
||||||
@ -189,4 +282,9 @@ int apic_write_vmexit_handler(struct vcpu *vcpu);
|
|||||||
int veoi_vmexit_handler(struct vcpu *vcpu);
|
int veoi_vmexit_handler(struct vcpu *vcpu);
|
||||||
int tpr_below_threshold_vmexit_handler(__unused struct vcpu *vcpu);
|
int tpr_below_threshold_vmexit_handler(__unused struct vcpu *vcpu);
|
||||||
void calcvdest(struct vm *vm, uint64_t *dmask, uint32_t dest, bool phys);
|
void calcvdest(struct vm *vm, uint64_t *dmask, uint32_t dest, bool phys);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/* End of acrn_vlapic */
|
||||||
#endif /* VLAPIC_H */
|
#endif /* VLAPIC_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user