Skip to content

Commit 97f6097

Browse files
lyan3wenlingz
authored andcommitted
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>
1 parent c1b4121 commit 97f6097

File tree

4 files changed

+31
-23
lines changed

4 files changed

+31
-23
lines changed

hypervisor/arch/x86/guest/vcpu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ void reset_vcpu(struct acrn_vcpu *vcpu)
601601
vcpu->arch.cur_context = NORMAL_WORLD;
602602

603603
vlapic = vcpu_vlapic(vcpu);
604-
vlapic_reset(vlapic);
604+
vlapic_reset(vlapic, apicv_ops);
605605

606606
reset_vcpu_regs(vcpu);
607607
}

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static inline void vlapic_dump_irr(__unused const struct acrn_vlapic *vlapic, __
8888
static inline void vlapic_dump_isr(__unused const struct acrn_vlapic *vlapic, __unused const char *msg) {}
8989
#endif
9090

91-
static const struct acrn_apicv_ops *apicv_ops;
91+
const struct acrn_apicv_ops *apicv_ops;
9292

9393
static int32_t
9494
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
565565
if ((lapic->svr.v & APIC_SVR_ENABLE) == 0U) {
566566
dev_dbg(ACRN_DBG_LAPIC, "vlapic is software disabled, ignoring interrupt %u", vector);
567567
} else {
568-
apicv_ops->accept_intr(vlapic, vector, level);
568+
vlapic->ops->accept_intr(vlapic, vector, level);
569569
}
570570
}
571571

@@ -1609,8 +1609,11 @@ static int32_t vlapic_write(struct acrn_vlapic *vlapic, uint32_t offset, uint64_
16091609
return ret;
16101610
}
16111611

1612+
/*
1613+
* @pre vlapic != NULL && ops != NULL
1614+
*/
16121615
void
1613-
vlapic_reset(struct acrn_vlapic *vlapic)
1616+
vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops)
16141617
{
16151618
uint32_t i;
16161619
struct lapic_regs *lapic;
@@ -1648,6 +1651,8 @@ vlapic_reset(struct acrn_vlapic *vlapic)
16481651
}
16491652

16501653
vlapic->isrv = 0U;
1654+
1655+
vlapic->ops = ops;
16511656
}
16521657

16531658
/**
@@ -1659,7 +1664,7 @@ vlapic_init(struct acrn_vlapic *vlapic)
16591664
{
16601665
vlapic_init_timer(vlapic);
16611666

1662-
vlapic_reset(vlapic);
1667+
vlapic_reset(vlapic, apicv_ops);
16631668
}
16641669

16651670
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)
20562061
}
20572062
} else {
20582063
offset = x2apic_msr_to_regoff(msr);
2059-
if (apicv_ops->x2apic_read_msr_may_valid(offset)) {
2064+
if (vlapic->ops->x2apic_read_msr_may_valid(offset)) {
20602065
error = vlapic_read(vlapic, offset, val);
20612066
}
20622067
}
@@ -2088,7 +2093,7 @@ int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val)
20882093
}
20892094
} else {
20902095
offset = x2apic_msr_to_regoff(msr);
2091-
if (apicv_ops->x2apic_write_msr_may_valid(offset)) {
2096+
if (vlapic->ops->x2apic_write_msr_may_valid(offset)) {
20922097
error = vlapic_write(vlapic, offset, val);
20932098
}
20942099
}
@@ -2280,7 +2285,7 @@ static bool apicv_advanced_inject_intr(struct acrn_vlapic *vlapic,
22802285

22812286
bool vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected)
22822287
{
2283-
return apicv_ops->inject_intr(vlapic, guest_irq_enabled, injected);
2288+
return vlapic->ops->inject_intr(vlapic, guest_irq_enabled, injected);
22842289
}
22852290

22862291
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 *
23062311

23072312
bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
23082313
{
2309-
return apicv_ops->has_pending_delivery_intr(vcpu);
2314+
struct acrn_vlapic *vlapic = vcpu_vlapic(vcpu);
2315+
return vlapic->ops->has_pending_delivery_intr(vcpu);
23102316
}
23112317

23122318
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)
23632369
if (access_type == TYPE_LINEAR_APIC_INST_WRITE) {
23642370
err = emulate_instruction(vcpu);
23652371
if (err == 0) {
2366-
if (apicv_ops->apic_write_access_may_valid(offset)) {
2372+
if (vlapic->ops->apic_write_access_may_valid(offset)) {
23672373
(void)vlapic_write(vlapic, offset, mmio->value);
23682374
}
23692375
}
23702376
} else {
2371-
if (apicv_ops->apic_read_access_may_valid(offset)) {
2377+
if (vlapic->ops->apic_read_access_may_valid(offset)) {
23722378
(void)vlapic_read(vlapic, offset, &mmio->value);
23732379
} else {
23742380
mmio->value = 0UL;

hypervisor/arch/x86/guest/vlapic_priv.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,4 @@
8282
#define APIC_OFFSET_TIMER_DCR 0x3E0U /* Timer's Divide Configuration */
8383
#define APIC_OFFSET_SELF_IPI 0x3F0U /* Self IPI Register */
8484

85-
struct acrn_apicv_ops {
86-
void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level);
87-
bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected);
88-
bool (*has_pending_delivery_intr)(struct acrn_vcpu *vcpu);
89-
bool (*apic_read_access_may_valid)(uint32_t offset);
90-
bool (*apic_write_access_may_valid)(uint32_t offset);
91-
bool (*x2apic_read_msr_may_valid)(uint32_t offset);
92-
bool (*x2apic_write_msr_may_valid)(uint32_t offset);
93-
};
94-
9585
#endif /* VLAPIC_PRIV_H */

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include <timer.h>
3535
#include <apicreg.h>
3636

37-
3837
/**
3938
* @file vlapic.h
4039
*
@@ -85,6 +84,8 @@ struct acrn_vlapic {
8584

8685
uint64_t msr_apicbase;
8786

87+
const struct acrn_apicv_ops *ops;
88+
8889
/*
8990
* Copies of some registers in the virtual APIC page. We do this for
9091
* a couple of different reasons:
@@ -95,6 +96,17 @@ struct acrn_vlapic {
9596
uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1];
9697
} __aligned(PAGE_SIZE);
9798

99+
struct acrn_apicv_ops {
100+
void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level);
101+
bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected);
102+
bool (*has_pending_delivery_intr)(struct acrn_vcpu *vcpu);
103+
bool (*apic_read_access_may_valid)(uint32_t offset);
104+
bool (*apic_write_access_may_valid)(uint32_t offset);
105+
bool (*x2apic_read_msr_may_valid)(uint32_t offset);
106+
bool (*x2apic_write_msr_may_valid)(uint32_t offset);
107+
};
108+
109+
extern const struct acrn_apicv_ops *apicv_ops;
98110
void vlapic_set_apicv_ops(void);
99111

100112
/**
@@ -182,7 +194,7 @@ void vlapic_free(struct acrn_vcpu *vcpu);
182194
* @pre vlapic->vcpu->vcpu_id < CONFIG_MAX_VCPUS_PER_VM
183195
*/
184196
void vlapic_init(struct acrn_vlapic *vlapic);
185-
void vlapic_reset(struct acrn_vlapic *vlapic);
197+
void vlapic_reset(struct acrn_vlapic *vlapic, const struct acrn_apicv_ops *ops);
186198
void vlapic_restore(struct acrn_vlapic *vlapic, const struct lapic_regs *regs);
187199
uint64_t vlapic_apicv_get_apic_access_addr(void);
188200
uint64_t vlapic_apicv_get_apic_page_addr(struct acrn_vlapic *vlapic);

0 commit comments

Comments
 (0)