hv: Add APIs to convert x2APIC MSR accesses to LAPIC MMIO offset
This patch converts x2APIC MSR accesses to corresponding LAPIC MMIO offset to utitlize vlapic_write/read APIs to virtualize LAPIC. Also adds support to inject GP fault when read-only registers are attempted to be written to or vice versa. Tracked-On: #1626 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Reviewed-by: Xu Anthony <anthony.xu@intel.com>
This commit is contained in:
parent
e9fe6efd81
commit
80b6e62735
|
@ -1996,18 +1996,34 @@ static inline bool is_x2apic_enabled(const struct acrn_vlapic *vlapic)
|
|||
}
|
||||
}
|
||||
|
||||
static int vlapic_x2apic_access(struct vcpu *vcpu)
|
||||
static inline uint32_t x2apic_msr_to_regoff(uint32_t msr)
|
||||
{
|
||||
|
||||
return (((msr - 0x800U) & 0x3FFU) << 4U);
|
||||
}
|
||||
|
||||
static int vlapic_x2apic_access(struct vcpu *vcpu, uint32_t msr, bool write, uint64_t *val)
|
||||
{
|
||||
struct acrn_vlapic *vlapic;
|
||||
int error = 0;
|
||||
uint32_t offset;
|
||||
int error = -1;
|
||||
|
||||
/*
|
||||
* If vLAPIC is in xAPIC mode and guest tries to access x2APIC MSRs
|
||||
* inject a GP to guest
|
||||
*/
|
||||
vlapic = vcpu_vlapic(vcpu);
|
||||
if (is_x2apic_enabled(vlapic) == false) {
|
||||
/*
|
||||
* If vLAPIC is in xAPIC mode and guest tries to access x2APIC MSRs
|
||||
* inject a GP to guest
|
||||
*/
|
||||
error = -1;
|
||||
if (is_x2apic_enabled(vlapic)) {
|
||||
offset = x2apic_msr_to_regoff(msr);
|
||||
if (write) {
|
||||
if (!is_x2apic_read_only_msr(msr)) {
|
||||
error = vlapic_write(vlapic, offset, *val);
|
||||
}
|
||||
} else {
|
||||
if (!is_x2apic_write_only_msr(msr)) {
|
||||
error = vlapic_read(vlapic, offset, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
|
@ -2033,7 +2049,7 @@ vlapic_rdmsr(struct vcpu *vcpu, uint32_t msr, uint64_t *rval)
|
|||
|
||||
default:
|
||||
if (is_x2apic_msr(msr)) {
|
||||
error = vlapic_x2apic_access(vcpu);
|
||||
error = vlapic_x2apic_access(vcpu, msr, false, rval);
|
||||
} else {
|
||||
error = -1;
|
||||
dev_dbg(ACRN_DBG_LAPIC,
|
||||
|
@ -2064,7 +2080,7 @@ vlapic_wrmsr(struct vcpu *vcpu, uint32_t msr, uint64_t wval)
|
|||
|
||||
default:
|
||||
if (is_x2apic_msr(msr)) {
|
||||
error = vlapic_x2apic_access(vcpu);
|
||||
error = vlapic_x2apic_access(vcpu, msr, true, &wval);
|
||||
} else {
|
||||
error = -1;
|
||||
dev_dbg(ACRN_DBG_LAPIC,
|
||||
|
|
|
@ -541,6 +541,31 @@ static inline bool is_x2apic_msr(uint32_t msr)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#endif /* ASSEMBLER */
|
||||
|
||||
/* 5 high-order bits in every field are reserved */
|
||||
|
|
Loading…
Reference in New Issue