mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-09 12:08:30 +00:00
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>
This commit is contained in:
parent
70dd254456
commit
28d50f1b96
@ -2038,6 +2038,27 @@ vlapic_x2apic_pt_icr_access(struct acrn_vm *vm, uint64_t val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool apicv_basic_x2apic_read_msr_may_valid(uint32_t offset)
|
||||
{
|
||||
return (offset != APIC_OFFSET_DFR) && (offset != APIC_OFFSET_ICR_HI);
|
||||
}
|
||||
|
||||
static bool apicv_advanced_x2apic_read_msr_may_valid(uint32_t offset)
|
||||
{
|
||||
return (offset == APIC_OFFSET_TIMER_CCR);
|
||||
}
|
||||
|
||||
static bool apicv_basic_x2apic_write_msr_may_valid(uint32_t offset)
|
||||
{
|
||||
return (offset != APIC_OFFSET_DFR) && (offset != APIC_OFFSET_ICR_HI);
|
||||
}
|
||||
|
||||
static bool apicv_advanced_x2apic_write_msr_may_valid(uint32_t offset)
|
||||
{
|
||||
return (offset != APIC_OFFSET_DFR) && (offset != APIC_OFFSET_ICR_HI) &&
|
||||
(offset != APIC_OFFSET_EOI) && (offset != APIC_OFFSET_SELF_IPI);
|
||||
}
|
||||
|
||||
int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val)
|
||||
{
|
||||
struct acrn_vlapic *vlapic;
|
||||
@ -2062,8 +2083,8 @@ int32_t vlapic_x2apic_read(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t *val)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!is_x2apic_write_only_msr(msr)) {
|
||||
offset = x2apic_msr_to_regoff(msr);
|
||||
offset = x2apic_msr_to_regoff(msr);
|
||||
if (apicv_ops->x2apic_read_msr_may_valid(offset)) {
|
||||
error = vlapic_read(vlapic, offset, val);
|
||||
}
|
||||
}
|
||||
@ -2094,8 +2115,8 @@ int32_t vlapic_x2apic_write(struct acrn_vcpu *vcpu, uint32_t msr, uint64_t val)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!is_x2apic_read_only_msr(msr)) {
|
||||
offset = x2apic_msr_to_regoff(msr);
|
||||
offset = x2apic_msr_to_regoff(msr);
|
||||
if (apicv_ops->x2apic_write_msr_may_valid(offset)) {
|
||||
error = vlapic_write(vlapic, offset, val);
|
||||
}
|
||||
}
|
||||
@ -2315,6 +2336,26 @@ bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu)
|
||||
return apicv_ops->has_pending_delivery_intr(vcpu);
|
||||
}
|
||||
|
||||
static bool apicv_basic_apic_read_access_may_valid(__unused uint32_t offset)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool apicv_advanced_apic_read_access_may_valid(uint32_t offset)
|
||||
{
|
||||
return ((offset == APIC_OFFSET_CMCI_LVT) || (offset == APIC_OFFSET_TIMER_CCR));
|
||||
}
|
||||
|
||||
static bool apicv_basic_apic_write_access_may_valid(uint32_t offset)
|
||||
{
|
||||
return (offset != APIC_OFFSET_SELF_IPI);
|
||||
}
|
||||
|
||||
static bool apicv_advanced_apic_write_access_may_valid(uint32_t offset)
|
||||
{
|
||||
return (offset == APIC_OFFSET_CMCI_LVT);
|
||||
}
|
||||
|
||||
int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
{
|
||||
int32_t err = 0;
|
||||
@ -2340,10 +2381,16 @@ int32_t apic_access_vmexit_handler(struct acrn_vcpu *vcpu)
|
||||
if (err >= 0) {
|
||||
if (access_type == 1UL) {
|
||||
if (emulate_instruction(vcpu) == 0) {
|
||||
(void)vlapic_write(vlapic, offset, mmio->value);
|
||||
if (apicv_ops->apic_write_access_may_valid(offset)) {
|
||||
(void)vlapic_write(vlapic, offset, mmio->value);
|
||||
}
|
||||
}
|
||||
} else if (access_type == 0UL) {
|
||||
(void)vlapic_read(vlapic, offset, &mmio->value);
|
||||
if (apicv_ops->apic_read_access_may_valid(offset)) {
|
||||
(void)vlapic_read(vlapic, offset, &mmio->value);
|
||||
} else {
|
||||
mmio->value = 0ULL;
|
||||
}
|
||||
err = emulate_instruction(vcpu);
|
||||
} else {
|
||||
pr_err("Unhandled APIC access type: %lu\n", access_type);
|
||||
@ -2502,12 +2549,20 @@ static const struct acrn_apicv_ops apicv_basic_ops = {
|
||||
.accept_intr = apicv_basic_accept_intr,
|
||||
.inject_intr = apicv_basic_inject_intr,
|
||||
.has_pending_delivery_intr = apicv_basic_has_pending_delivery_intr,
|
||||
.apic_read_access_may_valid = apicv_basic_apic_read_access_may_valid,
|
||||
.apic_write_access_may_valid = apicv_basic_apic_write_access_may_valid,
|
||||
.x2apic_read_msr_may_valid = apicv_basic_x2apic_read_msr_may_valid,
|
||||
.x2apic_write_msr_may_valid = apicv_basic_x2apic_write_msr_may_valid,
|
||||
};
|
||||
|
||||
static const struct acrn_apicv_ops apicv_advanced_ops = {
|
||||
.accept_intr = apicv_advanced_accept_intr,
|
||||
.inject_intr = apicv_advanced_inject_intr,
|
||||
.has_pending_delivery_intr = apicv_advanced_has_pending_delivery_intr,
|
||||
.apic_read_access_may_valid = apicv_advanced_apic_read_access_may_valid,
|
||||
.apic_write_access_may_valid = apicv_advanced_apic_write_access_may_valid,
|
||||
.x2apic_read_msr_may_valid = apicv_advanced_x2apic_read_msr_may_valid,
|
||||
.x2apic_write_msr_may_valid = apicv_advanced_x2apic_write_msr_may_valid,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -86,6 +86,10 @@ 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 */
|
||||
|
@ -567,31 +567,6 @@ static inline bool is_x2apic_msr(uint32_t msr)
|
||||
return ((msr >= 0x800U) && (msr < 0x900U));
|
||||
}
|
||||
|
||||
static inline bool is_x2apic_read_only_msr(uint32_t msr)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
if ((msr == MSR_IA32_EXT_XAPICID) ||
|
||||
(msr == MSR_IA32_EXT_APIC_VERSION) ||
|
||||
(msr == MSR_IA32_EXT_APIC_PPR) ||
|
||||
(msr == MSR_IA32_EXT_APIC_LDR) ||
|
||||
((msr >= MSR_IA32_EXT_APIC_ISR0) &&
|
||||
(msr <= MSR_IA32_EXT_APIC_IRR7)) ||
|
||||
(msr == MSR_IA32_EXT_APIC_CUR_COUNT)) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool is_x2apic_write_only_msr(uint32_t msr)
|
||||
{
|
||||
bool ret = false;
|
||||
if ((msr == MSR_IA32_EXT_APIC_EOI) || (msr == MSR_IA32_EXT_APIC_SELF_IPI)) {
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct acrn_vcpu;
|
||||
|
||||
void init_msr_emulation(struct acrn_vcpu *vcpu);
|
||||
|
Loading…
Reference in New Issue
Block a user