mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-18 19:57:31 +00:00
hv: add ops to vlapic structure
This commit adds ops to vlapic structure, and add an *ops parameter to vlapic_reset(). At vlapic reset, the ops is set to the global apicv_ops, and may be assigned to other ops later. Tracked-On: #3227 Signed-off-by: Yan, Like <like.yan@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
c1b4121e3b
commit
97f6097f04
@ -601,7 +601,7 @@ void reset_vcpu(struct acrn_vcpu *vcpu)
|
|||||||
vcpu->arch.cur_context = NORMAL_WORLD;
|
vcpu->arch.cur_context = NORMAL_WORLD;
|
||||||
|
|
||||||
vlapic = vcpu_vlapic(vcpu);
|
vlapic = vcpu_vlapic(vcpu);
|
||||||
vlapic_reset(vlapic);
|
vlapic_reset(vlapic, apicv_ops);
|
||||||
|
|
||||||
reset_vcpu_regs(vcpu);
|
reset_vcpu_regs(vcpu);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ static inline void vlapic_dump_irr(__unused const struct acrn_vlapic *vlapic, __
|
|||||||
static inline void vlapic_dump_isr(__unused const struct acrn_vlapic *vlapic, __unused const char *msg) {}
|
static inline void vlapic_dump_isr(__unused const struct acrn_vlapic *vlapic, __unused const char *msg) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const struct acrn_apicv_ops *apicv_ops;
|
const struct acrn_apicv_ops *apicv_ops;
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
apicv_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector);
|
apicv_set_intr_ready(struct acrn_vlapic *vlapic, uint32_t vector);
|
||||||
@ -565,7 +565,7 @@ static void vlapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, bool
|
|||||||
if ((lapic->svr.v & APIC_SVR_ENABLE) == 0U) {
|
if ((lapic->svr.v & APIC_SVR_ENABLE) == 0U) {
|
||||||
dev_dbg(ACRN_DBG_LAPIC, "vlapic is software disabled, ignoring interrupt %u", vector);
|
dev_dbg(ACRN_DBG_LAPIC, "vlapic is software disabled, ignoring interrupt %u", vector);
|
||||||
} else {
|
} else {
|
||||||
apicv_ops->accept_intr(vlapic, vector, level);
|
vlapic->ops->accept_intr(vlapic, vector, level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1609,8 +1609,11 @@ static int32_t vlapic_write(struct acrn_vlapic *vlapic, uint32_t offset, uint64_
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @pre vlapic != NULL && ops != NULL
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
vlapic_reset(struct acrn_vlapic *vlapic)
|
vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct lapic_regs *lapic;
|
struct lapic_regs *lapic;
|
||||||
@ -1648,6 +1651,8 @@ vlapic_reset(struct acrn_vlapic *vlapic)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vlapic->isrv = 0U;
|
vlapic->isrv = 0U;
|
||||||
|
|
||||||
|
vlapic->ops = ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1659,7 +1664,7 @@ vlapic_init(struct acrn_vlapic *vlapic)
|
|||||||
{
|
{
|
||||||
vlapic_init_timer(vlapic);
|
vlapic_init_timer(vlapic);
|
||||||
|
|
||||||
vlapic_reset(vlapic);
|
vlapic_reset(vlapic, apicv_ops);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vlapic_restore(struct acrn_vlapic *vlapic, const struct lapic_regs *regs)
|
void vlapic_restore(struct acrn_vlapic *vlapic, const struct lapic_regs *regs)
|
||||||
@ -2056,7 +2061,7 @@ int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offset = x2apic_msr_to_regoff(msr);
|
offset = x2apic_msr_to_regoff(msr);
|
||||||
if (apicv_ops->x2apic_read_msr_may_valid(offset)) {
|
if (vlapic->ops->x2apic_read_msr_may_valid(offset)) {
|
||||||
error = vlapic_read(vlapic, offset, val);
|
error = vlapic_read(vlapic, offset, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2088,7 +2093,7 @@ int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
offset = x2apic_msr_to_regoff(msr);
|
offset = x2apic_msr_to_regoff(msr);
|
||||||
if (apicv_ops->x2apic_write_msr_may_valid(offset)) {
|
if (vlapic->ops->x2apic_write_msr_may_valid(offset)) {
|
||||||
error = vlapic_write(vlapic, offset, val);
|
error = vlapic_write(vlapic, offset, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2280,7 +2285,7 @@ static bool apicv_advanced_inject_intr(struct acrn_vlapic *vlapic,
|
|||||||
|
|
||||||
bool vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected)
|
bool vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected)
|
||||||
{
|
{
|
||||||
return apicv_ops->inject_intr(vlapic, guest_irq_enabled, injected);
|
return vlapic->ops->inject_intr(vlapic, guest_irq_enabled, injected);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool apicv_basic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
|
static bool apicv_basic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
|
||||||
@ -2306,7 +2311,8 @@ static bool apicv_advanced_has_pending_delivery_intr(__unused struct acrn_vcpu *
|
|||||||
|
|
||||||
bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
|
bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
return apicv_ops->has_pending_delivery_intr(vcpu);
|
struct acrn_vlapic *vlapic = vcpu_vlapic(vcpu);
|
||||||
|
return vlapic->ops->has_pending_delivery_intr(vcpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool apicv_basic_apic_read_access_may_valid(__unused uint32_t offset)
|
static bool apicv_basic_apic_read_access_may_valid(__unused uint32_t offset)
|
||||||
@ -2363,12 +2369,12 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
|
|||||||
if (access_type == TYPE_LINEAR_APIC_INST_WRITE) {
|
if (access_type == TYPE_LINEAR_APIC_INST_WRITE) {
|
||||||
err = emulate_instruction(vcpu);
|
err = emulate_instruction(vcpu);
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
if (apicv_ops->apic_write_access_may_valid(offset)) {
|
if (vlapic->ops->apic_write_access_may_valid(offset)) {
|
||||||
(void)vlapic_write(vlapic, offset, mmio->value);
|
(void)vlapic_write(vlapic, offset, mmio->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (apicv_ops->apic_read_access_may_valid(offset)) {
|
if (vlapic->ops->apic_read_access_may_valid(offset)) {
|
||||||
(void)vlapic_read(vlapic, offset, &mmio->value);
|
(void)vlapic_read(vlapic, offset, &mmio->value);
|
||||||
} else {
|
} else {
|
||||||
mmio->value = 0UL;
|
mmio->value = 0UL;
|
||||||
|
@ -82,14 +82,4 @@
|
|||||||
#define APIC_OFFSET_TIMER_DCR 0x3E0U /* Timer's Divide Configuration */
|
#define APIC_OFFSET_TIMER_DCR 0x3E0U /* Timer's Divide Configuration */
|
||||||
#define APIC_OFFSET_SELF_IPI 0x3F0U /* Self IPI Register */
|
#define APIC_OFFSET_SELF_IPI 0x3F0U /* Self IPI Register */
|
||||||
|
|
||||||
struct acrn_apicv_ops {
|
|
||||||
void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level);
|
|
||||||
bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected);
|
|
||||||
bool (*has_pending_delivery_intr)(struct acrn_vcpu *vcpu);
|
|
||||||
bool (*apic_read_access_may_valid)(uint32_t offset);
|
|
||||||
bool (*apic_write_access_may_valid)(uint32_t offset);
|
|
||||||
bool (*x2apic_read_msr_may_valid)(uint32_t offset);
|
|
||||||
bool (*x2apic_write_msr_may_valid)(uint32_t offset);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* VLAPIC_PRIV_H */
|
#endif /* VLAPIC_PRIV_H */
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <apicreg.h>
|
#include <apicreg.h>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file vlapic.h
|
* @file vlapic.h
|
||||||
*
|
*
|
||||||
@ -85,6 +84,8 @@ struct acrn_vlapic {
|
|||||||
|
|
||||||
uint64_t msr_apicbase;
|
uint64_t msr_apicbase;
|
||||||
|
|
||||||
|
const struct acrn_apicv_ops *ops;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copies of some registers in the virtual APIC page. We do this for
|
* Copies of some registers in the virtual APIC page. We do this for
|
||||||
* a couple of different reasons:
|
* a couple of different reasons:
|
||||||
@ -95,6 +96,17 @@ struct acrn_vlapic {
|
|||||||
uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1];
|
uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1];
|
||||||
} __aligned(PAGE_SIZE);
|
} __aligned(PAGE_SIZE);
|
||||||
|
|
||||||
|
struct acrn_apicv_ops {
|
||||||
|
void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level);
|
||||||
|
bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected);
|
||||||
|
bool (*has_pending_delivery_intr)(struct acrn_vcpu *vcpu);
|
||||||
|
bool (*apic_read_access_may_valid)(uint32_t offset);
|
||||||
|
bool (*apic_write_access_may_valid)(uint32_t offset);
|
||||||
|
bool (*x2apic_read_msr_may_valid)(uint32_t offset);
|
||||||
|
bool (*x2apic_write_msr_may_valid)(uint32_t offset);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct acrn_apicv_ops *apicv_ops;
|
||||||
void vlapic_set_apicv_ops(void);
|
void vlapic_set_apicv_ops(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,7 +194,7 @@ void vlapic_free(struct acrn_vcpu *vcpu);
|
|||||||
* @pre vlapic->vcpu->vcpu_id < CONFIG_MAX_VCPUS_PER_VM
|
* @pre vlapic->vcpu->vcpu_id < CONFIG_MAX_VCPUS_PER_VM
|
||||||
*/
|
*/
|
||||||
void vlapic_init(struct acrn_vlapic *vlapic);
|
void vlapic_init(struct acrn_vlapic *vlapic);
|
||||||
void vlapic_reset(struct acrn_vlapic *vlapic);
|
void vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops);
|
||||||
void vlapic_restore(struct acrn_vlapic *vlapic, const struct lapic_regs *regs);
|
void vlapic_restore(struct acrn_vlapic *vlapic, const struct lapic_regs *regs);
|
||||||
uint64_t vlapic_apicv_get_apic_access_addr(void);
|
uint64_t vlapic_apicv_get_apic_access_addr(void);
|
||||||
uint64_t vlapic_apicv_get_apic_page_addr(struct acrn_vlapic *vlapic);
|
uint64_t vlapic_apicv_get_apic_page_addr(struct acrn_vlapic *vlapic);
|
||||||
|
Loading…
Reference in New Issue
Block a user