Skip to content

Commit 6a4dcce

Browse files
Sainath Grandhilijinxia
authored andcommitted
hv: APIs for building x2APIC ID and LDR
x2APIC ID and LDR are in different format compared to xAPIC mode of operation. This patch adds code to build ID and LDR when guest uses vLAPIC in x2APIC mode. Tracked-On: #1626 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Reviewed-by: Xu Anthony <anthony.xu@intel.com>
1 parent 7ecc521 commit 6a4dcce

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static inline uint32_t prio(uint32_t x)
4949
#define APICBASE_BSP 0x00000100UL
5050
#define APICBASE_X2APIC 0x00000400U
5151
#define APICBASE_ENABLED 0x00000800UL
52+
#define LOGICAL_ID_MASK 0xFU
53+
#define CLUSTER_ID_MASK 0xFFFF0U
5254

5355
#define ACRN_DBG_LAPIC 6U
5456

@@ -102,6 +104,8 @@ static void vlapic_set_error(struct acrn_vlapic *vlapic, uint32_t mask);
102104

103105
static void vlapic_timer_expired(void *data);
104106

107+
static inline bool is_x2apic_enabled(const struct acrn_vlapic *vlapic);
108+
105109
static struct acrn_vlapic *
106110
vm_lapic_from_vcpu_id(struct vm *vm, uint16_t vcpu_id)
107111
{
@@ -180,13 +184,29 @@ vlapic_build_id(const struct acrn_vlapic *vlapic)
180184
}
181185
#endif
182186

183-
lapic_regs_id = (uint32_t)vlapic_id << APIC_ID_SHIFT;
187+
if (is_x2apic_enabled(vlapic)) {
188+
lapic_regs_id = vlapic_id;
189+
} else {
190+
lapic_regs_id = (uint32_t)vlapic_id << APIC_ID_SHIFT;
191+
}
184192

185193
dev_dbg(ACRN_DBG_LAPIC, "vlapic APIC PAGE ID : 0x%08x", lapic_regs_id);
186194

187195
return lapic_regs_id;
188196
}
189197

198+
static inline void vlapic_build_x2apic_id(struct acrn_vlapic *vlapic)
199+
{
200+
struct lapic_regs *lapic;
201+
uint32_t logical_id, cluster_id;
202+
203+
lapic = &(vlapic->apic_page);
204+
lapic->id.v = vlapic_build_id(vlapic);
205+
logical_id = lapic->id.v & LOGICAL_ID_MASK;
206+
cluster_id = (lapic->id.v & CLUSTER_ID_MASK) >> 4U;
207+
lapic->ldr.v = (cluster_id << 16U) | (1U << logical_id);
208+
}
209+
190210
static void
191211
vlapic_dfr_write_handler(struct acrn_vlapic *vlapic)
192212
{
@@ -1672,6 +1692,17 @@ static int
16721692
vlapic_set_apicbase(struct acrn_vlapic *vlapic, uint64_t new)
16731693
{
16741694

1695+
uint64_t changed;
1696+
changed = vlapic->msr_apicbase ^ new;
1697+
1698+
if (changed == APICBASE_X2APIC) {
1699+
if ((new & APICBASE_X2APIC) == APICBASE_X2APIC) {
1700+
vlapic->msr_apicbase = new;
1701+
vlapic_build_x2apic_id(vlapic);
1702+
return 0;
1703+
}
1704+
}
1705+
16751706
if (vlapic->msr_apicbase != new) {
16761707
dev_dbg(ACRN_DBG_LAPIC,
16771708
"NOT support to change APIC_BASE MSR from %#lx to %#lx",

0 commit comments

Comments
 (0)