hv: Shuffle logic in vlapic_set_apicbase API implementation

This patch changes the code in vlapic_set_apicbase for the following reasons
1) Better readability as it first checks if the new value programmed into
MSR is any different from the existing value cached in guest structures
2) Check if both bits 11:10 are set before enabling x2APIC mode for guest.
Current code does not check if Bit 11 is set.
3) Add TODO in the comments, to detail about the current gaps in
IA32_APIC_BASE MSR emulation.

Tracked-On: #3253
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Sainath Grandhi 2019-06-10 15:20:52 -07:00 committed by wenlingz
parent 8426db9309
commit 1026f1754c

View File

@ -54,9 +54,10 @@ static inline uint32_t prio(uint32_t x)
}
#define VLAPIC_VERSION (16U)
#define APICBASE_BSP 0x00000100UL
#define APICBASE_X2APIC 0x00000400U
#define APICBASE_XAPIC 0x00000800U
#define APICBASE_LAPIC_MODE (APICBASE_XAPIC | APICBASE_X2APIC)
#define APICBASE_ENABLED 0x00000800UL
#define LOGICAL_ID_MASK 0xFU
#define CLUSTER_ID_MASK 0xFFFF0U
@ -1763,20 +1764,39 @@ int32_t vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new)
{
int32_t ret = 0;
uint64_t changed;
changed = vlapic->msr_apicbase ^ new;
bool change_in_vlapic_mode = false;
if ((changed == APICBASE_X2APIC) && ((new & APICBASE_X2APIC) == APICBASE_X2APIC)) {
atomic_set64(&vlapic->msr_apicbase, changed);
vlapic_build_x2apic_id(vlapic);
switch_apicv_mode_x2apic(vlapic->vcpu);
ret = 0;
} else if (vlapic->msr_apicbase != new) {
dev_dbg(ACRN_DBG_LAPIC,
"NOT support to change APIC_BASE MSR from %#lx to %#lx",
vlapic->msr_apicbase, new);
ret = -1;
} else {
/* No other state currently, do nothing */
if (vlapic->msr_apicbase != new) {
changed = vlapic->msr_apicbase ^ new;
change_in_vlapic_mode = ((changed & APICBASE_LAPIC_MODE) != 0U);
/*
* TODO: Logic to check for change in Reserved Bits and Inject GP
*/
/*
* Logic to check for change in Bits 11:10 for vLAPIC mode switch
*/
if (change_in_vlapic_mode) {
if ((new & APICBASE_LAPIC_MODE) ==
(APICBASE_XAPIC | APICBASE_X2APIC)) {
vlapic->msr_apicbase = new;
vlapic_build_x2apic_id(vlapic);
switch_apicv_mode_x2apic(vlapic->vcpu);
} else {
/*
* TODO: Logic to check for Invalid transitions, Invalid State
* and mode switch according to SDM 10.12.5
* Fig. 10-27
*/
}
}
/*
* TODO: Logic to check for change in Bits 35:12 and Bit 7 and emulate
*/
}
return ret;