Skip to content

Commit 28d50f1

Browse files
lifeixwenlingz
authored andcommitted
hv: vlapic: add apic register offset check API
Add apic rgister offset check before do vlapic read/write. Tracked-On: #1842 Signed-off-by: Li, Fei1 <fei1.li@intel.com>
1 parent 70dd254 commit 28d50f1

File tree

3 files changed

+65
-31
lines changed

3 files changed

+65
-31
lines changed

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,27 @@ vlapic_x2apic_pt_icr_access(struct acrn_vm *vm, uint64_t val)
20382038
return ret;
20392039
}
20402040

2041+
static bool apicv_basic_x2apic_read_msr_may_valid(uint32_t offset)
2042+
{
2043+
return (offset != APIC_OFFSET_DFR) && (offset != APIC_OFFSET_ICR_HI);
2044+
}
2045+
2046+
static bool apicv_advanced_x2apic_read_msr_may_valid(uint32_t offset)
2047+
{
2048+
return (offset == APIC_OFFSET_TIMER_CCR);
2049+
}
2050+
2051+
static bool apicv_basic_x2apic_write_msr_may_valid(uint32_t offset)
2052+
{
2053+
return (offset != APIC_OFFSET_DFR) && (offset != APIC_OFFSET_ICR_HI);
2054+
}
2055+
2056+
static bool apicv_advanced_x2apic_write_msr_may_valid(uint32_t offset)
2057+
{
2058+
return (offset != APIC_OFFSET_DFR) && (offset != APIC_OFFSET_ICR_HI) &&
2059+
(offset != APIC_OFFSET_EOI) && (offset != APIC_OFFSET_SELF_IPI);
2060+
}
2061+
20412062
int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val)
20422063
{
20432064
struct acrn_vlapic *vlapic;
@@ -2062,8 +2083,8 @@ int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val)
20622083
break;
20632084
}
20642085
} else {
2065-
if (!is_x2apic_write_only_msr(msr)) {
2066-
offset = x2apic_msr_to_regoff(msr);
2086+
offset = x2apic_msr_to_regoff(msr);
2087+
if (apicv_ops->x2apic_read_msr_may_valid(offset)) {
20672088
error = vlapic_read(vlapic, offset, val);
20682089
}
20692090
}
@@ -2094,8 +2115,8 @@ int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val)
20942115
break;
20952116
}
20962117
} else {
2097-
if (!is_x2apic_read_only_msr(msr)) {
2098-
offset = x2apic_msr_to_regoff(msr);
2118+
offset = x2apic_msr_to_regoff(msr);
2119+
if (apicv_ops->x2apic_write_msr_may_valid(offset)) {
20992120
error = vlapic_write(vlapic, offset, val);
21002121
}
21012122
}
@@ -2315,6 +2336,26 @@ bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
23152336
return apicv_ops->has_pending_delivery_intr(vcpu);
23162337
}
23172338

2339+
static bool apicv_basic_apic_read_access_may_valid(__unused uint32_t offset)
2340+
{
2341+
return true;
2342+
}
2343+
2344+
static bool apicv_advanced_apic_read_access_may_valid(uint32_t offset)
2345+
{
2346+
return ((offset == APIC_OFFSET_CMCI_LVT) || (offset == APIC_OFFSET_TIMER_CCR));
2347+
}
2348+
2349+
static bool apicv_basic_apic_write_access_may_valid(uint32_t offset)
2350+
{
2351+
return (offset != APIC_OFFSET_SELF_IPI);
2352+
}
2353+
2354+
static bool apicv_advanced_apic_write_access_may_valid(uint32_t offset)
2355+
{
2356+
return (offset == APIC_OFFSET_CMCI_LVT);
2357+
}
2358+
23182359
int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
23192360
{
23202361
int32_t err = 0;
@@ -2340,10 +2381,16 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
23402381
if (err >= 0) {
23412382
if (access_type == 1UL) {
23422383
if (emulate_instruction(vcpu) == 0) {
2343-
(void)vlapic_write(vlapic, offset, mmio->value);
2384+
if (apicv_ops->apic_write_access_may_valid(offset)) {
2385+
(void)vlapic_write(vlapic, offset, mmio->value);
2386+
}
23442387
}
23452388
} else if (access_type == 0UL) {
2346-
(void)vlapic_read(vlapic, offset, &mmio->value);
2389+
if (apicv_ops->apic_read_access_may_valid(offset)) {
2390+
(void)vlapic_read(vlapic, offset, &mmio->value);
2391+
} else {
2392+
mmio->value = 0ULL;
2393+
}
23472394
err = emulate_instruction(vcpu);
23482395
} else {
23492396
pr_err("Unhandled APIC access type: %lu\n", access_type);
@@ -2502,12 +2549,20 @@ static const struct acrn_apicv_ops apicv_basic_ops = {
25022549
.accept_intr = apicv_basic_accept_intr,
25032550
.inject_intr = apicv_basic_inject_intr,
25042551
.has_pending_delivery_intr = apicv_basic_has_pending_delivery_intr,
2552+
.apic_read_access_may_valid = apicv_basic_apic_read_access_may_valid,
2553+
.apic_write_access_may_valid = apicv_basic_apic_write_access_may_valid,
2554+
.x2apic_read_msr_may_valid = apicv_basic_x2apic_read_msr_may_valid,
2555+
.x2apic_write_msr_may_valid = apicv_basic_x2apic_write_msr_may_valid,
25052556
};
25062557

25072558
static const struct acrn_apicv_ops apicv_advanced_ops = {
25082559
.accept_intr = apicv_advanced_accept_intr,
25092560
.inject_intr = apicv_advanced_inject_intr,
25102561
.has_pending_delivery_intr = apicv_advanced_has_pending_delivery_intr,
2562+
.apic_read_access_may_valid = apicv_advanced_apic_read_access_may_valid,
2563+
.apic_write_access_may_valid = apicv_advanced_apic_write_access_may_valid,
2564+
.x2apic_read_msr_may_valid = apicv_advanced_x2apic_read_msr_may_valid,
2565+
.x2apic_write_msr_may_valid = apicv_advanced_x2apic_write_msr_may_valid,
25112566
};
25122567

25132568
/*

hypervisor/arch/x86/guest/vlapic_priv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ struct acrn_apicv_ops {
8686
void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level);
8787
bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected);
8888
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);
8993
};
9094

9195
#endif /* VLAPIC_PRIV_H */

hypervisor/include/arch/x86/msr.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -567,31 +567,6 @@ static inline bool is_x2apic_msr(uint32_t msr)
567567
return ((msr >= 0x800U) && (msr < 0x900U));
568568
}
569569

570-
static inline bool is_x2apic_read_only_msr(uint32_t msr)
571-
{
572-
bool ret = false;
573-
574-
if ((msr == MSR_IA32_EXT_XAPICID) ||
575-
(msr == MSR_IA32_EXT_APIC_VERSION) ||
576-
(msr == MSR_IA32_EXT_APIC_PPR) ||
577-
(msr == MSR_IA32_EXT_APIC_LDR) ||
578-
((msr >= MSR_IA32_EXT_APIC_ISR0) &&
579-
(msr <= MSR_IA32_EXT_APIC_IRR7)) ||
580-
(msr == MSR_IA32_EXT_APIC_CUR_COUNT)) {
581-
ret = true;
582-
}
583-
return ret;
584-
}
585-
586-
static inline bool is_x2apic_write_only_msr(uint32_t msr)
587-
{
588-
bool ret = false;
589-
if ((msr == MSR_IA32_EXT_APIC_EOI) || (msr == MSR_IA32_EXT_APIC_SELF_IPI)) {
590-
ret = true;
591-
}
592-
return ret;
593-
}
594-
595570
struct acrn_vcpu;
596571

597572
void init_msr_emulation(struct acrn_vcpu *vcpu);

0 commit comments

Comments
 (0)